Show message where filter can not find result

4

I'm using the excellent Isotope plugin to filter items on a page.

Filtering occurs according to the classes used in li that are referenced in option . When you select a filter, the properly referenced elements are displayed, and those that do not match are hidden.

But when the filter does not find any results, it would be necessary to display a message in place saying "No results found", instead of empty space.

Look at the JSFiddle with the code . Select in the "City 4" or "School 4" filter, where the middle column will not show results.

Example:

    
asked by anonymous 19.12.2014 / 18:09

1 answer

4

My first suggestion is to create an item for "no results" and place it next to the others. Give it a special class so that it is not visible along with others (as long as there is no filter, for example):

<li class="sem-resultados">
    Nenhum resultado encontrado
</li>

At first, this would only be enough for it to be hidden (because it does not have the class produkt-element , but in your code before doing any filtering it still remains visible.Then place a rule in your CSS to hide it, in fact:

.sem-resultados {
    display: none;
}

With an item of this in each column, let's filter: whenever the plugin finishes arranging the elements on the screen, the layoutComplete event occurs. In this event, you can count how many elements in each column are visible, and if there are none, show .sem-resultados :

$(".isotope.full").each(function() {
    var semResultados = $(this).find(".sem-resultados");
    var algumVisivel = $(this).find("li:visible").length > 0;
    semResultados.toggle(!algumVisivel);
});

However, I encountered two problems with this approach:

  • When layoutComplete is called, the elements still have the same visibility as they had before (since it seems to me that before the smooth transition of the elements, not their end). This makes it a little more complicated to know if there is any element visible or not.

    A workaround is to use a setTimeout to execute the above code only after all pending events have already been executed:

    $container.isotope("on", "layoutComplete", function() {
        setTimeout(function() {
            $(".isotope.full").each(function() {
                var semResultados = $(this).find(".sem-resultados");
                var algumVisivel = $(this).find("li:visible").length > 0;
                semResultados.toggle(!algumVisivel);
            });
        }, 500);
    });
    
  • For the same reason, if in the previous filtering the "no results" element was visible, in the new it is shown "over" of the elements present until the workaround above is executed, causing an effect unpleasant visual ... The solution is to hide .sem-resultados just before filtering:

     $(".sem-resultados").hide();
     $container.isotope({ filter: selector });
    
  • Final example .

    The visual effect may not be the best possible be a bit nasty, but that's what I achieved given the restrictions imposed by this plugin.

    Update: If you do not mind losing the smooth transition, just assign the transitionDuration property to zero:

    $container.isotope({
        itemSelector : '.produkt-element',
        transitionDuration: "0"
    });
    

    And so you can put the timeout also in 0 (but you have to keep it anyway). So there is no delay, only a slight flicker ... :)

        
    19.12.2014 / 19:25