SitePoint Sponsor

User Tag List

Results 1 to 12 of 12

Thread: Exact Match

  1. #1
    SitePoint Addict Shaydez's Avatar
    Join Date
    Jul 2006
    Location
    Boca Raton, Florida
    Posts
    356
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Exact Match

    The following code is something i got together and its not really doing what i need it to do.

    I'm trying to get exact match results .. If i clicked Internet and Telephone it should only show exactly what i click on. if i clicked on 1 it should show one and if i clicked on all 3 it should only show all three..

    Code:
        
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"> </script>
        <script type="text/javascript">
    		 $(document).ready(function(){
    		
    			$('div.tags').delegate('input:checkbox', 'change', function() {
    				var $lis = $('.results > li').fadeOut();
    				//For each one checked
    					$('input:checked').each(function() {
    						$lis.filter('.' + $(this).attr('rel')).fadeIn();
    					});
    			});
    		});
        </script>

    HTML Code:
      <div class="tags">
        <label><input type="checkbox" rel="internet" /> Internet </label>
        <label><input type="checkbox" rel="telephone" /> Telephone</label>
        <label><input type="checkbox" rel="television" /> Television</label>
    
    </div>
    
    <ul class="results">
        <li class="internet">
            Internet
        </li>
        <li class="telephone">
            Telephone
        </li>
        <li class="television">
            Television
        </li>
        <li class="internet telephone television">
            Internet / Telephone / Television
        </li>
        <li class="television internet">
            Television / Internet 
        </li>
        <li class="television telephone">
            Television / Telephone
        </li>
    </ul>
    Sr. Website Developer and Internet Marketing
    www.CarlosJa.com Note: If anyone
    needs to get ahold of me please feel free to email me through
    my site. Apparently i missed quite a few private messages.

  2. #2
    SitePoint Enthusiast
    Join Date
    Oct 2012
    Posts
    41
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    nevermind - see paul's reply, much simpeler

  3. #3
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,707
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Here you are needing to filter the list of items so that each shown item has the same number of correct matches as the ones that are checked.

    Code javascript:
    $('div.tags').on('change', 'input:checkbox', function() {
        var $lis = $('.results > li').fadeOut();
        var checkedTypes = $('input:checked');
        $lis.filter(function () {
            item = $(this);
            return checkedTypes.filter(function () {
                return item.is('.' + $(this).attr('rel'));
            }).length === checkedTypes.length;
        }).fadeIn();
    });
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  4. #4
    SitePoint Enthusiast
    Join Date
    Oct 2012
    Posts
    41
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    I just removed my post because your (paul) solution seemed better written, but it's not exactly what he wants. If a user checks 'telephone', then only the 'telephone'-li should be shown. In your case it shows all li's with the class telephone, even if it has other classes...

    These were my 2 attempts:

    - This one relies on the order of your classes on your li-elements! The class "internet" should always come before "telephone" and "telephone" should always come before "television". If you want to add another class (for lay-out purposes or so), you can add them at the end of the class-attribute and change the selector to "^=" instead of "=".
    Code JavaScript:
    $('div.tags').on('change', 'input:checkbox', function() {
    	var $lis = $('.results > li').fadeOut();
    	//For each one checked
    	var c = "";
    	$( "input:checked" ).each(function(){
    		c += $( this ).attr( "rel" ) + " ";
    	});
    	c = $.trim( c );
    	$lis.filter("[class='"+c+"']").fadeIn();
    });

    - This one is a bit complex and I'm sure a pro JS'er will be able to rewrite it. Or it'll give you a clue on a way to do so:
    In short: i create an array of the selected checkboxes/classes. I filter $lis and see if the number of classes is the same as the amount of checked checkboxes. If so, then i'm looping over the classes and see if they all appear in the array.
    Code JavaScript:
    $('div.tags').on('change', 'input:checkbox', function() {
    	var $lis = $('.results > li').fadeOut();
    	//For each one checked
    	var arr = $( "input:checked" ).map(function(){
    		return $( this ).attr( "rel" );
    	});
     
    	$lis.filter(function(){
    		var li = $( this );
    		var classes = li.attr( "class" ).split( /\s+/ );
    		if( classes.length === arr.length ){
    			var ok = true;
    			for( var i = 0; i < classes.length; i++ ){
    				if( $.inArray( classes[ i ], arr ) < 0 ){
    					ok = false;
    				}
    			}
     
    			return ok;
    		}	
    		return false;
    	}).fadeIn();
    });

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,707
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Denk View Post
    I just removed my post because your (paul) solution seemed better written, but it's not exactly what he wants. If a user checks 'telephone', then only the 'telephone'-li should be shown. In your case it shows all li's with the class telephone, even if it has other classes...
    Ahh, I should read things with greater care. Feel free to put your solution back up, and I'll see what I can come up with that matches what's wanted too
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  6. #6
    SitePoint Enthusiast
    Join Date
    Oct 2012
    Posts
    41
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    i edited my previous post, feel free to update it. i'm looking forward to seeing your solution :-)

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,707
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Denk View Post
    i edited my previous post, feel free to update it. i'm looking forward to seeing your solution :-)
    Thanks. The simple solution involves checking if each item has no conflict with each of the three checkboxes.
    How to check if there's no conflict? Filtering the checkboxes against each item should result in the total number of checkboxes, when the item fully matches.

    Code javascript:
    $('div.tags').on('change', 'input:checkbox', function() {
        var lis = $('.results > li').fadeOut(),
            inputs = $('input');
     
        lis.filter(function () {
            return item.filter(function () {
                // remove the item if it doesn't match with all of the checkboxes
                return item.is(function () {
                    var item = $(this);
                    // all checkboxes must agree with whether the item contains that class name or not
                    return inputs.filter(function () {
                        var className = '.' + $(this).attr('rel');
                        return item.is(className) === $(this).is(':checked');
                    }).length === inputs.length;
                });
            }).length > 0;
        }).fadeIn();
    });
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  8. #8
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,707
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    There's a lot of nesting in there though.

    This version of the code has some functions expanded out - but is this easier to understand?

    Code javascript:
    $('div.tags').on('change', 'input:checkbox', function() {
        function itemMatchingAllCheckboxes() {
            var item = $(this);
            // all checkboxes must agree with whether the item contains that class name or not
            return inputs.filter(function () {
                var className = '.' + $(this).attr('rel');
                return item.is(className) === $(this).is(':checked');
            }).length === inputs.length;
        }
     
        function compareItemsWithCheckboxes() {
            return $(this).filter(function () {
                return $(this).is(itemMatchingAllCheckboxes);
            }).length > 0;
        }
     
        var lis = $('.results > li').fadeOut(),
            inputs = $('input');
     
        lis.filter(compareItemsWithCheckboxes).fadeIn();
    });
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  9. #9
    SitePoint Addict Shaydez's Avatar
    Join Date
    Jul 2006
    Location
    Boca Raton, Florida
    Posts
    356
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    wow.. i really appreciate the help. My script was way....... off .. again thank you so much. honestly would've never figured that out in a million years. lol
    Sr. Website Developer and Internet Marketing
    www.CarlosJa.com Note: If anyone
    needs to get ahold of me please feel free to email me through
    my site. Apparently i missed quite a few private messages.

  10. #10
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,707
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Shaydez View Post
    wow.. i really appreciate the help. My script was way....... off .. again thank you so much. honestly would've never figured that out in a million years. lol
    Well my code started off as being messier than what I provided up there. It began with a series of variables, and then creating more variables for itemIsChecked and noItemIsChecked then checking that both itemIsChecked and !noItemIsChecked apply. That way we're checking if items matching the checked checkboxes are consistent with the items that don't match the unchecked checkboxes. Because we only want an item that is checked, but is also not one of the ones that is not checked.

    So from a start with "I want the item when it's in checked group, and when it's not in the not checked group", I then make further improvements to the code and simplify things until the original mess no longer exists, and cleaner code is what tends to remain.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  11. #11
    SitePoint Addict Shaydez's Avatar
    Join Date
    Jul 2006
    Location
    Boca Raton, Florida
    Posts
    356
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    I'm trying to figure out how to reset the filters. Everytime I put if length == 0 inside the function it'll show all the results disappear again.

    if non of the checkboxes are checked it should show all the results.
    Sr. Website Developer and Internet Marketing
    www.CarlosJa.com Note: If anyone
    needs to get ahold of me please feel free to email me through
    my site. Apparently i missed quite a few private messages.

  12. #12
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,707
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    We could update the following piece instead:

    Code javascript:
    var lis = $('.results > li').fadeOut(),
        inputs = $('input');
     
    lis.filter(compareItemsWithCheckboxes).fadeIn();

    What you can do is to save the checked items and the filtered list of items to variables:

    Code javascript:
    var lis = $('.results > li').fadeOut(),
        inputs = $('input'),
        checkedItems = inputs.filter(':checked'),
        itemsToShow = lis.filter(compareItemsWithCheckboxes);
     
    itemsToShow.fadeIn();

    Which then allows you to see if nothing is selected, so that you can update the items that you want shown instead:

    Code javascript:
    ...
    if (checkedItems.length === 0) {
        itemsToShow = lis;
    }
    itemsToShow.fadeIn();

    And because items are animated individually, the fadeIn will be out of sync when different items are being faded out then in, so we can delay the fadeIn until the initial fadeOut has finished:

    Code javascript:
    ...
    setTimeout(function () {
        itemsToShow.fadeIn();
    }, 400);

    And now, we can tidy up by bringing the fadeOut and fadeIn closer together in the code, which results in the following:

    Code javascript:
    var lis = $('.results > li'),
    ...
    lis.fadeOut();
    setTimeout(function () {
        itemsToShow.fadeIn();
    }, 400);

    That helps us to see a further improvement that could be made. Check out the following:

    Code javascript:
    var inputs = $('input'),
        checkedItems = inputs.filter(':checked'),
        lis = $('.results > li'),
        itemsToShow = lis;
     
    if (checkedItems.length > 0) {
        itemsToShow = itemsToShow.filter(compareItemsWithCheckboxes);
    }
    ...

    Instead of performing the compareItemsWithCheckboxes every time, we could instead have the itemsToShow start off as the full list of items, then see if any checkboxes are checked. If there are, we can then go ahead with filtering them.

    Code javascript:
    var inputs = $('input'),
        checkedItems = inputs.filter(':checked'),
        lis = $('.results > li'),
        itemsToShow = lis;
     
    if (checkedItems.length > 0) {
        itemsToShow = itemsToShow.filter(compareItemsWithCheckboxes);
    }
    ...

    That leaves us with the following final set of code:

    Code javascript:
    var inputs = $('input'),
        checkedItems = inputs.filter(':checked'),
        lis = $('.results > li'),
        itemsToShow = lis;
     
    if (checkedItems.length > 0) {
        itemsToShow = itemsToShow.filter(compareItemsWithCheckboxes);
    }
    lis.fadeOut();
    setTimeout(function () {
        itemsToShow.fadeIn();
    }, 400);

    You can find the above test code at http://jsfiddle.net/pmw57/J4fbj/4/
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •