Logical problem,seeking an algorithm
- Manufacter (Trusardi, Calvin Kein, Armani...)
- Color (red, blue, black...) 开发者_StackOverflow中文版
- OtherFeatures (goretex, blah, blah...)
Each feature is displayed as a checkbox...
The problem is that i want to disable the checkboxes if its selection would lead to no results..For example Armani's products may have color blue only so checking armani should disable the black and red,but other manufactors shouldnt be disabled... as checking them should provide a result... Here is the code so farresults = $("#products li");
results.hide();
var filtersGroup = $("#filters li.filtersGroup");
$("#filters li.filtersGroup a").removeClass("disabled");
filtersGroup.each(function(index) {
var classes = "";
$(this).find("a.checked").each(function(index) {
classes = classes + "." + $(this).attr("id") + ",";
});
if (classes == "") return true;
results = results.filter(classes.substr(0, classes.length - 1));
//periorismos
filtersGroup.not($(this)).each(function(index) {
$(this).find("a").each(function(index) {
if (results.filter("." + $(this).attr("id")).length <= 0) {
$(this).removeClass("checked").addClass("disabled");
}
});
});
});
Although it filters them successfully ,the disabling isnt always correct. for example to reproduce the problem ,if you choose all the manufactors and then choose a color manufactors would be disabled but colors not at the first time..
One solution i figured is to create multiple results which would simulate all the next possible check.(if 16 features and 4 checked means 12 possible other checked .. But i think that this approach sucks... Any other idea?You could add a class for each manufacturer, colour, etc. then simply disable by class. I assume here there's a results hash keyed off manufacturer:
results['Trusardi'] = 5
results['Armani' = 0
..then:
$("#filters li.filtersGroup a").addClass("disabled");
foreach (m in manufacturers) {
if (manufacturers[m] > 0) {
$("#filters li.filtersGroup a." + m).removeClass("disabled");
}
}
etc.
You have a faceted search problem - where many combinations produce no results. Instead of disabling, I suggest calculating and showing how many results results would appear if a given criterion is selected. Then with each click, executing that algorithm again. So your search would like very similar to newegg.com:
http://www.newegg.com/Store/SubCategory.aspx?SubCategory=10&name=Desktop-PCs
Depending on how much data you're dealing with you might want to consider using solr.
I think that i found the solution.. It was simpler than i thought... I was trying to find a solution all day long and it was simpler than i thought.. Here it is....
results=$("#products li");
results.hide();
var groupClasses=[];
var groupsChecked=0;
var filtersGroup=$("#filters li.filtersGroup");
$("#filters li.filtersGroup a").removeClass("disabled");
filtersGroup.each(function(index) {
var classes="";
$(this).find("a.checked").each(function(index) {
classes=classes+ "." + $(this).attr("id") +",";
});
groupClasses[groupClasses.length]=classes;
if(classes=="") return true;
groupsChecked++;
results=results.filter(classes.substr(0,classes.length-1));
});
//disable
var gi=0;
filtersGroup.each(function(index) {
if( ! (groupsChecked<=1 && groupClasses[gi]!=""))
{
$(this).find("a").not(".checked").each(function(){
if (results.filter("." + $(this).attr("id")).length <= 0) {
$(this).removeClass("checked").addClass("disabled");
}
});
}
gi++;
});
It seems to be correct. I amnot sure though but testing it seems ok..
Can't you just compute the results for every unchecked option and compare them to the current products that suffice. (I'm not very familiar with jQuery so I wouldn't know how...)
精彩评论