2016-04-27 3 views
2

Ich verwende Search & Filter Pro, um Bilder auf einer Website zu filtern. Ich habe das Kontrollkästchen Filter in Akkordeons. Beim Laden der Seite funktioniert alles richtig. Das Problem ist, wenn ich auf einen Filter klicke, benutzt er AJAX, der die Filter neu erstellt und meine Akkordeonklassen löscht.AJAX erstellt Akkordeons und bricht sie

Die Suche & Filter kommt mit ein paar Haken, eine, die ausgeführt wird, wenn der AJAX startet und eine nach Abschluss. Ich kann das Akkordeon-Skript erneut ausführen, wenn AJAX komplett ist, aber ich verliere, welches Akkordeon offen ist. Hier

ist der Akkordeon-Code ...

ecg.accordions = ecg.accordions || {}; 

    ecg.accordions = { 

     scrollToDiv: function(element){ 
      var offset = element.offset(); 
      var offsetTop = offset.top - 40; 
      $('body,html').animate({ 
         scrollTop: offsetTop 
      }, 500); 
     }, 

     init: function(){ 
      $('li[data-sf-field-type="taxonomy"]').not(':first').children('ul').hide(); 
      $('li[data-sf-field-type="taxonomy"]:first-child h4').addClass('expanded') 

      $('li[data-sf-field-type="taxonomy"] h4').click(function(){ 

       if ($(this).hasClass('expanded')){ 
        $(this) 
         .next() 
         .slideUp('fast'); 
        $(this).removeClass('expanded'); 
       }else{ 
        $('.expanded').each(function(){ 
         $(this) 
          .next() 
          .slideUp('fast'); 
         $(this).removeClass('expanded'); 
        });      
        $(this) 
         .next() 
         .slideDown('fast', function(){ 
          var el = $(this); 
          ecg.accordions.scrollToDiv(el); 
         }); 
        $(this).addClass('expanded'); 
       } 
       return false; 
      }); 
     } // init 

    } // ecg.accordions 

Hier sind die Haken der Filter-Plugin bietet ...

//detects the start of an ajax request being made 
$(document).on("sf:ajaxstart", ".searchandfilter", function(){ 
    console.log("ajax start"); 
}); 

//detects when the ajax request has finished and the content has been updated 
$(document).on("sf:ajaxfinish", ".searchandfilter", function(){ 
    console.log("ajax complete"); 
    ecg.accordions.init(); 
}); 

Sie können in dem fertiggestellten Ereignisse siehe oben ich den Akkordeon-Code erneut aus . Ich dachte, vielleicht bekomme ich im Ajax-Start-Skript das offene Akkordeon und gebe es an das abgeschlossene Ajax-Event weiter, ich weiß nicht, ob das möglich ist.

Hier ist ein Beispiel-Markup für ein paar Filter

<div class="filters"> 
     <form action="#" method="post" class="searchandfilter" data-sf-form-id="20" data-is-rtl="0" data-results-url="#" data-ajax-form-url="#" data-use-history-api="1" data-template-loaded="1" data-lang-code="" data-ajax="1" data-ajax-target=".listing" data-ajax-links-selector=".pagination a" data-update-ajax-url="1" data-only-results-ajax="1" data-scroll-to-pos="0" data-auto-update="1" data-auto-count="1" data-auto-count-refresh-mode="1" id="search-filter-form-20" autocomplete="off"> 
      <ul> 
      <li class="sf-field-taxonomy-ce_venue" data-sf-field-name="_sft_ce_venue" data-sf-field-type="taxonomy" data-sf-field-input-type="checkbox"> 
       <h4>Venue</h4> 
       <ul data-operator="or" class=""> 
        <li class="sf-level-0 sf-item-39" data-sf-count="2"> 
         <input class="sf-input-checkbox" type="checkbox" value="ven1" name="_sft_ce_venue[]" id="sf-input-60a0def98ed13c6d6f9a27aee1c13e70"> 
         <label class="sf-label-checkbox" for="sf-input-60a0def98ed13c6d6f9a27aee1c13e70">ven1<span class="sf-count">(2)</span></label> 
        </li> 
        <li class="sf-level-0 sf-item-42" data-sf-count="1"> 
         <input class="sf-input-checkbox" type="checkbox" value="ven2" name="_sft_ce_venue[]" id="sf-input-500ece294de752754740cc49b255a686"> 
         <label class="sf-label-checkbox" for="sf-input-500ece294de752754740cc49b255a686">ven2<span class="sf-count">(1)</span></label> 
        </li> 
       </ul> 
      </li> 
      <li class="sf-field-taxonomy-ce_color" data-sf-field-name="_sft_ce_color" data-sf-field-type="taxonomy" data-sf-field-input-type="checkbox"> 
       <h4>Color</h4> 
       <ul data-operator="or" class=""> 
        <li class="sf-level-0 sf-item-81" data-sf-count="2"> 
         <input class="sf-input-checkbox" type="checkbox" value="color1" name="_sft_ce_color[]" id="sf-input-39bf68813f58db9c7013a386ac7d5201"> 
         <label class="sf-label-checkbox" for="sf-input-39bf68813f58db9c7013a386ac7d5201">color1<span class="sf-count">(2)</span></label> 
        </li> 
        <li class="sf-level-0 sf-item-43" data-sf-count="1"> 
         <input class="sf-input-checkbox" type="checkbox" value="color2" name="_sft_ce_color[]" id="sf-input-68bb548aeaab5440359a3afbdf9d9513"> 
         <label class="sf-label-checkbox" for="sf-input-68bb548aeaab5440359a3afbdf9d9513">color2<span class="sf-count">(1)</span></label> 
        </li> 
       </ul> 
      </li> 
      </ul> 
     </form> 
    </div> 
+0

Können Sie Beispiel-Markup bereitstellen? Haben diese Taxonomie-Listenelemente irgendwelche unterscheidenden Attribute? Z.B. Die Search & Filter Filme Demo '

+0

Ich habe der Frage ein Beispiel-Markup hinzugefügt. Das erste li hat eine eindeutige Klasse für jeden Filter. Ich war in der Lage, mit diesem und lokalen/Session-Speicher zu arbeiten, damit es richtig funktioniert. ABER ich glaube nicht, dass das der beste Ansatz ist – RiddleMeThis

Antwort

1

Nun, die Idee, die für mich eine Notiz hält in den Sinn kommt, auf dem Akkordeon geöffnet, so war, dass wir es wieder öffnen können, falls zutreffend.

Anstatt die Event-Handler direkt auf die einzelnen Elemente selbst anzuwenden, müssen Sie sich auf Ereignis-Sprudeln verlassen, so dass wir nur init einmal aufrufen. So

:

 $('li[data-sf-field-type="taxonomy"] h4').click(function(){ 

Becomes:

 $('.filters').on('click', 'li[data-sf-field-type="taxonomy"] h4', function(){ 

Wenn ein Akkordeon aktiviert ist, können wir auf den erweiterten Liste Punkt die Referenz "Speicher". Für mich scheint es der Inhalt von <h4> kann verwendet werden, um sie zu identifizieren, also werden wir das als ein Beispiel verwenden.

So in dem Click-Handler, wo Sie haben:

   $(this).addClass('expanded'); 

Wir hinzufügen:

   var $h4 = $(this); // ... 
       $h4.parents('.filters').data('reference', $h4.text()); 

(ich den Code so, anstatt mit einem Abfrageobjekt zu erzeugen, gereinigt ($(this)), die jeweils Zeit, wiederverwenden, zvar $h4 = $(this); $h4.next().slideUp('fast'); //...)

Aktualisieren Sie das Standard-Akkordeon, das gleiche zu tun, also wo init hat:

 $('li[data-sf-field-type="taxonomy"]:first-child h4').addClass('expanded') 

Wir machen es zu:

 var $first_h4 = $('li[data-sf-field-type="taxonomy"]:first-child h4'); 
     $first_h4.addClass('expanded').parents('.filter').data('reference', $first_h4.text()); 

dann die Suche aktualisieren und vollständigen Code filtern diese zu nutzen :

//detects when the ajax request has finished and the content has been updated 
$(document).on("sf:ajaxfinish", ".searchandfilter", function(){ 
    console.log("ajax complete"); 
    //ecg.accordions.init(); 
    // Loop through each filter, check if they had an expanded accordion, loop through the new h4's to see if there's match. 
    $('.filters').each(function(){ 
     var $filter = $(this); 
     var id  = $filter.data('reference'); 
     if (id) { 
      $filter.find('li[data-sf-field-type="taxonomy"] h4:contains(' + id + ')').toggleClass('expanded', true); 
     } 
    }); 
}); 

Wenn Sie etwas wollen um immer offen zu sein, wie Sie den ersten Artikel über init öffnen, setzen Sie diesen Code in seine eigene Funktion und verwenden Sie ihn erneut in der Suche & filter complete event. Brauche etwas Feinschliff, aber ja.

+0

Habe es funktioniert, danke, das hat mich auf den richtigen Weg gebracht. – RiddleMeThis

Verwandte Themen