3

I have some data stored in an array. When I click on a checkbox I would like to show the item that meet the criteria and hide the ones that don't.

For example if I have a list of products that are being rendered through a for loop and when I click the checkbox for android, I would like to only show android phones.

Here is my javascript code so far:

var data = {
    "products": [{
        "Name": "Apple iPhone6 16GB",
        "OS": "iOS",
        "Camera": "16mp",
        "Price": "$" + 99.99,
        "Specs": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel finibus ligula. Duis pretium, velit eget venenatis laoreet, eros nulla facilisis eros, quis consectetur nisl sapien ut justo. Nulla et erat ex. Morbi tincidunt vitae tellus eget iaculis. Sed imperdiet, justo et ultricies imperdiet, leo ante elementum nunc, et facilisis mauris felis id felis. Etiam sit amet dolor purus. Vestibulum et hendrerit neque, sit amet gravida dolor."
    }, {
        "Name": "Samsung- Galaxy S6 32GB",
        "OS": "android",
        "Camera": "16mp",
        "Price": "$" + 199.99,
        "Specs": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel finibus ligula. Duis pretium, velit eget venenatis laoreet, eros nulla facilisis eros, quis consectetur nisl sapien ut justo. Nulla et erat ex. Morbi tincidunt vitae tellus eget iaculis. Sed imperdiet, justo et ultricies imperdiet, leo ante elementum nunc, et facilisis mauris felis id felis. Etiam sit amet dolor purus. Vestibulum et hendrerit neque, sit amet gravida dolor."
    }, {
        "Name": "HTC One M9 32GB",
        "OS": "android",
        "Camera": "16mp",
        "Price": "$" + 199.99,
        "Specs": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel finibus ligula. Duis pretium, velit eget venenatis laoreet, eros nulla facilisis eros, quis consectetur nisl sapien ut justo. Nulla et erat ex. Morbi tincidunt vitae tellus eget iaculis. Sed imperdiet, justo et ultricies imperdiet, leo ante elementum nunc, et facilisis mauris felis id felis. Etiam sit amet dolor purus. Vestibulum et hendrerit neque, sit amet gravida dolor."
    }, {
        "Name": "Apple iPhone6 Plus 32GB",
        "OS": "iOS",
        "Camera": "16mp",
        "Price": "$" + 399.99,
        "Specs": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel finibus ligula. Duis pretium, velit eget venenatis laoreet, eros nulla facilisis eros, quis consectetur nisl sapien ut justo. Nulla et erat ex. Morbi tincidunt vitae tellus eget iaculis. Sed imperdiet, justo et ultricies imperdiet, leo ante elementum nunc, et facilisis mauris felis id felis. Etiam sit amet dolor purus. Vestibulum et hendrerit neque, sit amet gravida dolor."
    }, {
        "Name": "Samsung Galaxy Note 5 32GB",
        "OS": "android",
        "Camera": "16mp",
        "Price": "$" + 499.99,
        "Specs": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel finibus ligula. Duis pretium, velit eget venenatis laoreet, eros nulla facilisis eros, quis consectetur nisl sapien ut justo. Nulla et erat ex. Morbi tincidunt vitae tellus eget iaculis. Sed imperdiet, justo et ultricies imperdiet, leo ante elementum nunc, et facilisis mauris felis id felis. Etiam sit amet dolor purus. Vestibulum et hendrerit neque, sit amet gravida dolor."
    }, {
        "Name": "LG G Flex 2 32GB",
        "OS": "android",
        "Camera": "16mp",
        "Price": "$" + 199.99,
        "Specs": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel finibus ligula. Duis pretium, velit eget venenatis laoreet, eros nulla facilisis eros, quis consectetur nisl sapien ut justo. Nulla et erat ex. Morbi tincidunt vitae tellus eget iaculis. Sed imperdiet, justo et ultricies imperdiet, leo ante elementum nunc, et facilisis mauris felis id felis. Etiam sit amet dolor purus. Vestibulum et hendrerit neque, sit amet gravida dolor."
    }]
}
for (var i = 0; i < data.products.length; i++) {
    $('#productList').append(
        '<div class="item">' +
            '<h3>' + data.products[i].Name + '</h3>' +
            '<h4>' + data.products[i].OS + '</h4>' +
            '<h5>' + data.products[i].Camera + '</h5>' +
            '<h5>' + data.products[i].Price + '</h5>' +
            '<p>' + data.products[i].Specs
    );
}

And here is the HTML code:

<div id="container">
  <ul id="mainNav">
    <li>
      Device Manufacturer
      <ul>
        <li><input type="checkbox" name= "device" value="Apple"> Apple</li>
        <li><input type="checkbox" name= "device" value="HTC"> HTC</li>
        <li><input type="checkbox" name= "device" value="LG"> LG</li>
        <li><input type="checkbox" name= "device" value="Samsung"> Samsung</li>
      </ul>
    </li>
    <li>
      Operating System
      <ul>
        <li><input type="checkbox" name= "device" value="Android"> Android</li>
        <li><input type="checkbox" name= "device" value="ios"> iOS</li>
      </ul>
    </li>
    <li>
      Camera
      <ul>
        <li><input type="checkbox" name= "device" value="8mp"> 8mp</li>
        <li><input type="checkbox" name= "device" value="16mp"> 16mp</li>
      </ul>
    </li>
    <li>
      Storage
      <ul>
        <li><input type="checkbox" name= "device" value="Apple"> 16GB</li>
        <li><input type="checkbox" name= "device" value="Apple"> 32GB</li>
        <li><input type="checkbox" name= "device" value="Apple"> 64GB</li>
      </ul>
    </li>
  </ul>
  <div id="productList"></div>
</div>
Pierre
  • 18,643
  • 4
  • 41
  • 62
  • When I was beautifying your code I noticed that you are missing the closing tag for `div.item` and for the `p` inside. – Pierre Aug 01 '15 at 00:50

1 Answers1

0

Here's one simple way you can do it (there are probably much better solutions out there but this should work):

http://jsfiddle.net/txrk87ug/17/

Created the building of product list as a function. It first clears the product list, then creates an array of devices checkboxes selected and then builds the product list using the array as a filter to choose appropriate products:

$.fn.buildProductList = function(){
    $('#productList').html("");
    var devices = [];
    $('input[name="device"]:checked').each(function() {
        devices.push(this.value);
    });
    for(var i =0; i < data.products.length; i++) {
        if($.inArray(data.products[i].Device, devices) > -1)
        {
            $('#productList').append(data.products[i].Name + '' + '<br />' + data.products[i].OS + '' + '<br />' + data.products[i].Camera + '' + '<br />' + data.products[i].Price + '' + '<br />' + data.products[i].Specs + '<br />&nbsp;<br />');
        }
    }
}

Created trigger to fire the build product list function when checkboxes change:

$(":checkbox").change(function() {
    $.fn.buildProductList();
});

Your products will need properties that match the values of the checkbox selections you are making. For the demo I only included the "Device" property. You should be able to select any number of Device Manufacturers and have it display only products that match those selections. You can build your arrays for the other checkbox groups in the same way and add it to the if statement when deciding if the product should be appended to the list.

Hopefully this gets you a good start at least.

Alec Menconi
  • 735
  • 1
  • 16
  • 36
  • thank you so much for this solution. While trying to come up with a way to store images inside json, i started learning xml. Currently I am trying to add a like and dislike button to each item. I am using a each loop to cycle my xml file to dynamically render each item. Is there a way I can tag you in a new post? Again I greatly appreciate your help. – Travis Davis Aug 11 '15 at 02:07
  • Glad it worked for you. Not sure how you can alert others of questions, would be a cool feature. You can ping my email at menconiusa@yahoo.com. Can't promise I'll be of any use but I'll take a look at any other questions you have and see if I can help. Thanks. – Alec Menconi Aug 11 '15 at 05:58
  • oh ok much appreciated. Question for ya; if I remove the first line of jquery in the function will #productList be visible once the page loads, and can I filter xml data the same way you're filtering the json data? Meaning would this work: $('#productList').append('$("name")').text(); inside the loop? – Travis Davis Aug 11 '15 at 17:31
  • Yes the first line just clears the product list, by calling html("") we are just changing the html for the DOM element selected (ID of productList in this case) to be blank. If we didn't do this, each time the loop ran it would just keep adding products so they would be in the list multiple times as you ran it more and more. In the jsfiddle link you can remove the line and see what happens. The append code will just add content to the DOM element (the productList div again in this case as well) so it shouldn't matter where you grab the content to append from. Send me a link if problems. – Alec Menconi Aug 11 '15 at 17:47
  • After reading your comment again I think I might have misunderstood, are you asking how to have the product list be populated on page load? Couple ways to do that, either build a function that builds the full list and call it on page load or you can have the full list as the default HTML for the div, then changing the filter selections will wipe that HTML and repopulate it with matching products again. I can list some more code examples if you need. – Alec Menconi Aug 11 '15 at 17:51
  • Yea that's what I meant, the list be populated on page load, like when you go to bestbuy.com and you click on computers, all products are shown as default and then the list changes based on what filter has been checked. also if I have a set of images inside a folder is there a way to store the path of the image inside each array option and then have the image show up with each product? – Travis Davis Aug 12 '15 at 00:46
  • here's an example: image: "images/example.jpg"<---- adding this to the array for each product? – Travis Davis Aug 12 '15 at 00:50
  • http://jsfiddle.net/6ec4b6nw/1/ - That should have the full list on load or when no options are selected. It also selects products additively within the same category (so selecting Apple and HTC shows all Apple and HTC products) but it filters across categories so Apple and Android checked shows all products from Apple with Android OS. If no options are selected in a category it assumes they are all checked for filter purposes. This should work similarly to those e-commerce sites. – Alec Menconi Aug 12 '15 at 01:29
  • Also yes you should be able to load up images just fine. When loading the product to show the image just wrap the path to the image inside an HTML tag with src pointing to your image file. For instance: + '

    '
    – Alec Menconi Aug 12 '15 at 01:34
  • Ok i get it, when you use .push it fills the empty array with that filter with products that contain that value. Man Alec I can not begin to thank you enough for your help. I got the image to load and I understand how to use xml data and json data. Again thank you so much. – Travis Davis Aug 12 '15 at 17:34
  • Correct, you start by initializing devices as an empty array, then for every item that is checked you add the value for that option to the devices array and that option matches a property of the product item data, then it checks each product to see if that property value matches one of the array items and only shows the product if at least one array item matches across all four categories. Glad I could be of help and good luck with the project. – Alec Menconi Aug 12 '15 at 18:08
  • in the event I need to use an external json file do I link it in the for loop like this: for(var i = 0; i < data.json.length; i++) – Travis Davis Aug 13 '15 at 00:02
  • Yeah that basically looks correct. Haven't done this myself as I mostly do C# MVC for this stuff. You should be able to just assign the json you get to a variable and call the length of that for the for loop as described here http://stackoverflow.com/questions/18238173/javascript-loop-through-json-array. – Alec Menconi Aug 13 '15 at 03:08