javascriptjqueryjquery-isotope

Isotope: Create warning if search and filter doesn't give back any result


I have written an extension for TYPO3. Now i have a problem. Can anyone tell me what i have to do if i want to display a custom warning text-message as soon as the searchstring or dropdown-filter doesn't give back any results? Something like:

"Sorry - we can't find any entries with this search filters!"

Currently my code is looking like this:

    // Isotope Steinlexikon
    $(function() {
        var $container = $('#lexikon-masonry'),
            $select = $('#lexikon-filter select'),
            filters = {};


        var qsRegex;
        var SelectFilter = '*';

        $container.isotope({
            itemSelector: '.item',
            // Filter mit Suchfeld
            filter: function() {
                var $this = $(this);
                var SerRes = qsRegex ? $(this).text().match( qsRegex ) : true;
                var SelRes = $(this).is(SelectFilter);
                return SerRes && SelRes;
            }
        });
        // use value of search field to filter
        var $quicksearch = $('#quicksearch').keyup( debounce( function() {
            qsRegex = new RegExp( $quicksearch.val(), 'gi' );
            $container.isotope();
        }, 200 ) );
        // debounce so filtering doesn't happen every millisecond
        function debounce( fn, threshold ) {
            var timeout;
            return function debounced() {
                if ( timeout ) {
                    clearTimeout( timeout );
                }
                function delayed() {
                    fn();
                    timeout = null;
                }
                timeout = setTimeout( delayed, threshold || 100 );
            }
        }

        //fancybox
        $('.fancybox2').on('click', function(e){
            e.preventDefault(); // Default action ausschalten

            $.fancybox({
                //width: 500,
                //height: 400,
                autoSize: true,
                href: $(this).attr('href'),
                type: 'ajax'
            });
        });


        // Filter mit Select Form

        $select.change(function() {

            var $this = $(this);

            // store filter value in object
            // i.e. filters.color = 'red'
            var group = $this.attr('data-filter-group');

            filters[ group ] = $this.find(':selected').attr('data-filter-value');
            // console.log( $this.find(':selected') )
            // convert object into array
            var isoFilters = [];
            for ( var prop in filters ) {
                isoFilters.push( filters[ prop ] )
            }
            console.log(filters);
            SelectFilter = isoFilters.join('');
            $container.isotope();
            return false;

        });
    });
#lexikon-masonry .item	{
	margin: 5px;
	padding: 5px;
	background: #fff;
	border: 1px #ccc solid;
    float: left;
	-moz-box-shadow: 0px 6px 6px 0px rgba(0,0,0,0.2);
	-webkit-box-shadow:  0px 6px 6px 0px rgba(0,0,0,0.2);
	box-shadow: 0px 6px 6px 0px rgba(0,0,0,0.2);
}
#lexikon-masonry .item img	{
	opacity: 1;
}
#lexikon-masonry .item:hover img	{
	opacity: 0.5;
}
#lexikon-masonry .image-hover #image-caption	{
	position: relative;	
	width: 100%;
	text-align: center;
	bottom: 0px;
	background: #fff;
	z-index: 1;
	opacity: 1;
	text-transform: uppercase;

}
#lexikon-masonry .image-hover:hover #image-caption	{
	opacity: 0.8;
}
#lexikon-masonry .image-hover #image-caption span	{
	text-transform: none;
}
#lexikon-masonry .image-hover .img-button-link	{
	position: absolute;	
	/*left: 50%;
	top: 50%;*/
	margin-left: 110px;
	margin-top: -125px;
	opacity: 0;
}
#lexikon-masonry .image-hover:hover .img-button-link	{
	opacity: 1;
}

div#lexikon-filter {
    position:left;
}

div.lexStyled { 
    float: left;
    margin-right: 20px;
    overflow:hidden; /* this hides the select's drop button */ 
    padding:0; 
    margin:0; 
    background: white url(../images/select-down.png) no-repeat bottom right; 
    /* this is the new drop button, in image form */ 
    width:12em; 
	border-radius:2px; 
    box-shadow: 0 1px 3px rgba(0,0,0,0.2); 
    border: solid 1px #ccc; 
}

div.lexStyled select { 
    width:115% /* this percentage effectively extends the drop down button out of view */; 
    background-color:transparent /* this hides the select's background making any styling visible from the div */; 
    background-image:none; 
    -webkit-appearance: none /* this is required for Webkit browsers */; 
    border:none; 
    box-shadow:none; 
    padding:0.3em 0.5em; /* padding should be added to the select, not the div */ 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://isotope.metafizzy.co/v1/jquery.isotope.min.js"></script>
	<div class="row">
		<div id="lexikon-suche" class="col span_3">
			<input class="form-control" type="text" data-filter-value="" id="quicksearch" placeholder="Durchsuchen" />
		</div>
		<div id="lexikon-filter" class="col span_9">
			<div class="lexStyled">
			<select data-filter-group="gestein">
				<option data-filter-value="*" class="selected">Alle Gesteine</option>
                <option data-filter-value=".lagersteine" class="selected">Lagersteine</option>
                <option data-filter-value=".kunststeine" class="selected">Kunststeine</option>

			</select>
			</div>
			<div class="lexStyled">
			<select data-filter-group="farbe">
				<option data-filter-value="*" class="selected">Alle Farben</option>
                <option data-filter-value=".rot" class="selected">Rot</option>
                <option data-filter-value=".gelb" class="selected">Gelb</option>

			</select>
			</div>

		</div>
	</div>
<br><hr><br>
	<div class="row">
		<div id="lexikon-masonry" class="col span_12">
				<div class="item image-hover lagersteine rot gelb">
					<div id="image-caption" class="name">Test1</div>
				</div>
				<div class="item image-hover kunststeine rot">
					<div id="image-caption" class="name">Test2</div>
				</div>
            <div class="item image-hover lagersteine kunststeine gelb">
                <div id="image-caption" class="name">Test3</div>
				</div>
		</div>
	</div>

I did not come through the examples given in these answers (jQuery Isotope filter to no items?). It does not work for me.

Thx for your help


Solution

  • You can get Isotope instance like this

    $container.data('isotope')
    

    And this has property $filteredAtoms, which holds filtered items. So to get count, use this:

    var visibleItemsCount = $container.data('isotope').$filteredAtoms.length; 
    

    For V2

    var visibleItemsCount = $container.data('isotope').filteredItems.length; 
    

    And after filtering, check for visible items. If has some, hide message, show otherwise.

    // Function to check if filters have some results
    function checkResults(){
      var visibleItemsCount = $container.data('isotope').$filteredAtoms.length;
    
      if( visibleItemsCount > 0 ){
        $('.no-results').hide();
      }
      else{
        $('.no-results').show();
      }
    }
    

    // Isotope Steinlexikon
        $(function() {
            var $container = $('#lexikon-masonry'),
                $select = $('#lexikon-filter select'),
                filters = {};
    
    
            var qsRegex;
            var SelectFilter = '*';
    
            $container.isotope({
                itemSelector: '.item',
                // Filter mit Suchfeld
                filter: function() {
                    var $this = $(this);
                    var SerRes = qsRegex ? $(this).text().match( qsRegex ) : true;
                    var SelRes = SelectFilter == '' || $(this).is(SelectFilter);
                    return SerRes && SelRes;
                }
            });
            // use value of search field to filter
            var $quicksearch = $('#quicksearch').keyup( debounce( function() {
                qsRegex = new RegExp( $quicksearch.val(), 'gi' );
                $container.isotope();
                checkResults();
            }, 200 ) );
            // debounce so filtering doesn't happen every millisecond
            function debounce( fn, threshold ) {
                var timeout;
                return function debounced() {
                    if ( timeout ) {
                        clearTimeout( timeout );
                    }
                    function delayed() {
                        fn();
                        timeout = null;
                    }
                    timeout = setTimeout( delayed, threshold || 100 );
                }
            }
    
            // Function to check if filters have some results
            function checkResults(){
              var visibleItemsCount = $container.data('isotope').$filteredAtoms.length;
              console.log(filters);
              if( visibleItemsCount > 0 ){
                $('.no-results').hide();
              }
              else{
                $('.no-results').show();
              }
            }
          
            //fancybox
            $('.fancybox2').on('click', function(e){
                e.preventDefault(); // Default action ausschalten
    
                $.fancybox({
                    //width: 500,
                    //height: 400,
                    autoSize: true,
                    href: $(this).attr('href'),
                    type: 'ajax'
                });
            });
    
    
            // Filter mit Select Form
    
            $select.change(function() {
    
                var $this = $(this);
    
                // store filter value in object
                // i.e. filters.color = 'red'
                var group = $this.attr('data-filter-group');
    
                filters[ group ] = $this.find(':selected').attr('data-filter-value');
                // console.log( $this.find(':selected') )
                // convert object into array
                var isoFilters = [];
                for ( var prop in filters ) {
                  if( filters[ prop ] != '*' ){
                    isoFilters.push( filters[ prop ] )
                  }
                }
                SelectFilter = isoFilters.join('');
                $container.isotope();
                checkResults();
                return false;
    
            });
        });
    #lexikon-masonry .item	{
    	margin: 5px;
    	padding: 5px;
    	background: #fff;
    	border: 1px #ccc solid;
        float: left;
    	-moz-box-shadow: 0px 6px 6px 0px rgba(0,0,0,0.2);
    	-webkit-box-shadow:  0px 6px 6px 0px rgba(0,0,0,0.2);
    	box-shadow: 0px 6px 6px 0px rgba(0,0,0,0.2);
    }
    #lexikon-masonry .item img	{
    	opacity: 1;
    }
    #lexikon-masonry .item:hover img	{
    	opacity: 0.5;
    }
    #lexikon-masonry .image-hover #image-caption	{
    	position: relative;	
    	width: 100%;
    	text-align: center;
    	bottom: 0px;
    	background: #fff;
    	z-index: 1;
    	opacity: 1;
    	text-transform: uppercase;
    
    }
    #lexikon-masonry .image-hover:hover #image-caption	{
    	opacity: 0.8;
    }
    #lexikon-masonry .image-hover #image-caption span	{
    	text-transform: none;
    }
    #lexikon-masonry .image-hover .img-button-link	{
    	position: absolute;	
    	/*left: 50%;
    	top: 50%;*/
    	margin-left: 110px;
    	margin-top: -125px;
    	opacity: 0;
    }
    #lexikon-masonry .image-hover:hover .img-button-link	{
    	opacity: 1;
    }
    
    .no-results{
      display:none;
    }
    
    div#lexikon-filter {
        position:left;
    }
    
    div.lexStyled { 
        float: left;
        margin-right: 20px;
        overflow:hidden; /* this hides the select's drop button */ 
        padding:0; 
        margin:0; 
        background: white url(../images/select-down.png) no-repeat bottom right; 
        /* this is the new drop button, in image form */ 
        width:12em; 
    	border-radius:2px; 
        box-shadow: 0 1px 3px rgba(0,0,0,0.2); 
        border: solid 1px #ccc; 
    }
    
    div.lexStyled select { 
        width:115% /* this percentage effectively extends the drop down button out of view */; 
        background-color:transparent /* this hides the select's background making any styling visible from the div */; 
        background-image:none; 
        -webkit-appearance: none /* this is required for Webkit browsers */; 
        border:none; 
        box-shadow:none; 
        padding:0.3em 0.5em; /* padding should be added to the select, not the div */ 
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://isotope.metafizzy.co/v1/jquery.isotope.min.js"></script>
    	<div class="row">
    		<div id="lexikon-suche" class="col span_3">
    			<input class="form-control" type="text" data-filter-value="" id="quicksearch" placeholder="Durchsuchen" />
    		</div>
    		<div id="lexikon-filter" class="col span_9">
    			<div class="lexStyled">
    			<select data-filter-group="gestein">
    				<option data-filter-value="*" class="selected">Alle Gesteine</option>
                    <option data-filter-value=".lagersteine" class="selected">Lagersteine</option>
                    <option data-filter-value=".kunststeine" class="selected">Kunststeine</option>
    
    			</select>
    			</div>
    			<div class="lexStyled">
    			<select data-filter-group="farbe">
    				<option data-filter-value="*" class="selected">Alle Farben</option>
                    <option data-filter-value=".rot" class="selected">Rot</option>
                    <option data-filter-value=".gelb" class="selected">Gelb</option>
    
    			</select>
    			</div>
    
    		</div>
    	</div>
    <br><hr><br>
    	<div class="row">
    		<div id="lexikon-masonry" class="col span_12">
    				<div class="item image-hover lagersteine rot gelb">
    					<div id="image-caption" class="name">Test1</div>
    				</div>
    				<div class="item image-hover kunststeine rot">
    					<div id="image-caption" class="name">Test2</div>
    				</div>
                <div class="item image-hover lagersteine kunststeine gelb">
                    <div id="image-caption" class="name">Test3</div>
    				</div>
    		</div>
            <div class="no-results">Sorry - we can't find any entries with this search filters!</div>
    	</div>