2013-07-09 51 views
1

對於所有jQuery英雄,我需要幫助! (再次)同位素:組合過濾+多重選擇

我發現在互聯網上類似的問題,我的,但沒有答案爲止: -/

我想過濾一堆使用jQuery同位素項目。我改編自插件的主頁,工作正常組合式過濾器例子,看起來像這樣:

$(function() { 
var $container = $('#container'), 
    filters = {}; 
$container.isotope({ 
    itemSelector: '.item', 
    filter: '', 
}); 

// filter links 
$('.filter a').click(function() { 
    var $this = $(this); 
    // don't proceed if already selected 
    if ($this.hasClass('selected')) { 
     return; 
    } 

    var $optionSet = $this.parents('.option-set'); 
    // change selected class 
    $optionSet.find('.selected').removeClass('selected'); 
    $this.addClass('selected'); 

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

    // convert object into array 
    var isoFilters = []; 
    for (var prop in filters) { 
     isoFilters.push(filters[prop]) 
    } 
    var selector = isoFilters.join(''); 
    $container.isotope({ 
     filter: selector 
    }); 
    return false; 
}); }); 

,並在濾鏡菜單中的一些HTML代碼:

<div id="nav"> 
    <ul class="filter option-set" data-filter-group="who"> 
     <li><a href="#filter-who-any" data-filter-value="" class="selected">Any</a></li> 
     <li><a href="#filter-who-boys" data-filter-value=".boys">Boys</a></li> 
     <li><a href="#filter-who-girls" data-filter-value=".girls">Girls</a></li> 
    </ul> 

</div> 

我成立了一個小提琴演示用三濾jsFiddle

現在,我想使人們有可能從每個類別中選擇多個標籤:可結合類別

類別1:一個OR b ORÇ

AND

Categoy 2:一個OR b ORÇ

AND

Categoy 3: b ORÇ

有一個check-box-example通過desandro,但這是不太我在尋找的東西,因爲我希望保持和狀況類別之間。基本上我想要3個過濾器類別,每個都有一些複選框(或鏈接,但我猜複選框功能更強大)。 我認爲這兩個示例中使用的方法是完全不同的,我不知道如何組合它們的功能。

我希望你明白我的觀點,任何人都可以幫我找到解決方案。

在此先感謝!

回答

0

我可以讓它工作,但並不像我在一個實例中那樣直截了當。 我覺得你需要承受心靈上的幾件事情:

  1. 如果你想使用一個限制性的條件,那麼我建議鴕鳥政策使用「數據 - 過濾 - 值」選項。相反,把你的過濾器變量作爲類。然後,您需要在onclick事件中自己觸發同位素功能。 這是因爲否則,當用戶單擊按鈕時,您將觸發「默認」同位素函數,並且無法達到限制性的AND。

  2. 在相同的方向上,對於要與一起使用的每個嵌套過濾器選項組合,您將需要使用新變量名(所以新類)。否則,我不會看到其他方式(目前)獲得限制條件。

該概念有關限制性的,並且是非限制性的AND子句是像的外和內的區別加入。如果你想處理兩個過濾器,一個是另一個過濾器的子過濾器,那麼你應該使用這個概念。
其中一個例子就像電子書列表,它可以按照品牌進行過濾,另一個是基於不同範圍價格的子過濾器。

我告訴你下面的代碼示例,在這裏我實現這個想法,它可以給你什麼,我的意思是一個暗示:

HTML:

<!--Filters section --> 
<div id="filters"> 
    <ul id="optionSet1" class="option-set" data-option-key="filter"> 
      <li><a id="filter10" href="#filter" class="selected">Everything</a></li> 
     <c:forEach var="brand" items="${brands}" varStatus="status" > 
      <li><a id="filter1${status.count}" href="#filter" class='${brand}'>${brand}</a></li> 
     </c:forEach> 
    </ul> 
    <ul id="optionSet2" class="option-set" data-option-key="filter"> 
     <li><a id="filter20" href="#filter" class="selected">Any Price</a> </li> 
    <c:forEach var="brandPrice" items="${brandPrices}" varStatus="status" > 
     <li><a id="filter2${status.count}" href="#filter" class='${brandPrice}'>${brandPrice}</a></li> 
    </c:forEach> 
    </ul> 
</div> 


<!--Elements to filter --> 
<div id="portfolio-wrapper" class="row"> 
    <c:forEach var="publication" items="${publications}" varStatus="status" >    
     <div class='span4 portfolio-item ${publication.filterOption1} ${publication.filterOption2} ${publication.filterOption3}...'> 
<!-- filterOption3 would be the combination of filterOption1 and filterOption2, you can make this building a string as the addition of filterOption1 and filterOption2 strings--> 
      <!--Content to display-->   
    </c:forEach> 
</div> 

的javascript:

$(function(){ 

     $("a[id^='filter1']").on('click', function() { 
//   alert($(this).attr('class')); 
//   alert($('#optionSet2 .selected').attr('class')); 
      var myclass = $('#optionSet2 .selected').attr('class'); 
      myclass = myclass.replace(' selected',''); 
      myclass = myclass.replace('selected',''); 
      var myclass2 = $(this).attr('class'); 
      myclass2 = myclass2.replace(' selected',''); 
      myclass2 = myclass2.replace('selected',''); 
      if($(myclass=='' && myclass2==''){ 
       $('#portfolio-wrapper').isotope({ filter: '*'}); 
      }else if(myclass==''){ 
       $('#portfolio-wrapper').isotope({ filter: '.'+ myclass2+'' }); 
      }else if(myclass2==''){ 
       $('#portfolio-wrapper').isotope({ filter: '.'+myclass+'' }); 
      }else{ 

       $('#portfolio-wrapper').isotope({ filter: '.'+myclass2+myclass+''}); 
      } 
     }); 

     $("a[id^='filter2']").on('click', function() { 
//   alert($(this).attr('class')); 
//   alert($('#optionSet1 .selected').attr('class')); 
      var myclass = $('#optionSet1 .selected').attr('class'); 
      myclass = myclass.replace(' selected',''); 
      myclass = myclass.replace('selected',''); 
      var myclass2 = $(this).attr('class'); 
      myclass2 = myclass2.replace(' selected',''); 
      myclass2 = myclass2.replace('selected',''); 
      if(myclass=='' && myclass2==''){ 
       $('#portfolio-wrapper').isotope({ filter: '*'}); 
      }else if(myclass==''){ 
       $('#portfolio-wrapper').isotope({ filter: '.'+ myclass2+'' }); 
      }else if(myclass2==''){ 
       $('#portfolio-wrapper').isotope({ filter: '.'+myclass+'' }); 
      }else{ 

       $('#portfolio-wrapper').isotope({ filter: '.'+myclass+myclass2+''}); 
      } 
     }); 

}); 
+0

謝謝!幾周前我發佈了這個問題,同時我找到了另一個解決方案。我應該刪除這個問題,因爲它不再是當前的問題。但是,無論如何謝謝你,我也會看看你的解決方案,並且mybe再次改變我的腳本。 – Alani

+0

@Alani我有完全相同的問題。我知道如何製作多重複選框同位素,我可以製作組合過濾器。現在你是怎麼把這兩個結合起來的?如果你能回答你自己的問題,這將是很好的。謝謝! – Trekdrop

+0

@LarsKerff我結合了多個下拉菜單的濾鏡。但是不可能在一個下拉列表中選擇多個選項,因此它與複選框不同,可能不是您要查找的內容。但你可以看看這個演示,也許它有助於反正:[jfiddle](http://jsfiddle.net/alani/9WRLE/) – Alani

11

使用具有metafizzy同位素過濾的多種過濾器類型需要多維數組來保存每種過濾器類型的數組。

我有一個活生生的例子here

而對於例如JS是here

對於一個完整的代碼解釋見我的回答this question

+0

謝謝,它幫助很多:) –

5

看看這裏

http://codepen.io/desandro/pen/btFfG

這是DrewT的同樣的答案,但從我sotope團隊。

所有你必須以過濾器把每一個組下的同一對象做

 var filters = {};//sould be outside the scope of the filtering function 


    $a.click(function()//filtering function 
       var group = $optionSet.attr('data-filter-group'); 
      var filterGroup = filters[group]; 
           if (!filterGroup) { 
            filterGroup = filters[group] = []; 
           } 
     filters[ group ].push($this.attr('data-filter-value')); 

現在你要做的就是調用getComboFilter功能(你不必瞭解裏面getComboFilter的代碼,認爲它是同位素的一部分)

 var comboFilter = getComboFilter(filters); 
$container.isotope({ filter: comboFilter}); 
        });//end filtering function 

function getComboFilter(filters) { 
    var i = 0; 
    var comboFilters = []; 
    var message = []; 

    for (var prop in filters) { 
    message.push(filters[ prop ].join(' ')); 
    var filterGroup = filters[ prop ]; 
    // skip to next filter group if it doesn't have any values 
    if (!filterGroup.length) { 
     continue; 
    } 
    if (i === 0) { 
     // copy to new array 
     comboFilters = filterGroup.slice(0); 
    } else { 
     var filterSelectors = []; 
     // copy to fresh array 
     var groupCombo = comboFilters.slice(0); // [ A, B ] 
     // merge filter Groups 
     for (var k=0, len3 = filterGroup.length; k < len3; k++) { 
     for (var j=0, len2 = groupCombo.length; j < len2; j++) { 
      filterSelectors.push(groupCombo[j] + filterGroup[k]); // [ 1, 2 ] 
     } 

     } 
     // apply filter selectors to combo filters for next group 
     comboFilters = filterSelectors; 
    } 
    i++; 
    } 

    var comboFilter = comboFilters.join(', '); 
    return comboFilter; 
} 
+0

非常好的工作,謝謝 –

0

抱歉了疏通這個問題,但我最近遇到了同樣的問題,(恕我直言)浪費了大量的時間與聯合選擇解決這個。 (將陣列A的每個類與陣列B的每個類相結合,等等)

使用過濾函數。它允許任意的複雜性,並且可能是所有非平凡情況的正確選擇。

最重要的是,使用選擇器沒有性能上的好處(如果選擇器直接輸入到querySelector或jQuery調用中,您可能會有所預期)。通過各項目同位素迭代並不管選擇的功能應用:

return function(item) { 
    return matchesSelector(item.element, filter); 
}; 

因此,你可能也只是把你的過濾邏輯放到一個函數,而不是試圖產生一個選擇的字符串。