2013-12-09 47 views
2

我有几个复选框,根据选择的复选框来过滤产品。单击复选框时,过滤器将工作,并将产品ID添加到数组中。正如你所看到的,这两个过滤器都有一些相同的ID,所以如果他们点击了多个输入框,我想确保这些ID只被推入到数组中。例如。如果他们有input.white选择和input.greymelange选择,然后他们点击filter-btn我只想重复的id被推动一次。有什么办法可以做到这一点?只有在数组不存在的情况下才推送到阵列

JQUERY

var productIds = [""]; 

$(document).on('click', 'a.filter-btn', function(e){ 

    $(".listingTemplate").html(""); 
    if ($('input.white').is(':checked')) { 
      productIds.push("4021401143741", "4021402266227"); 
    } 

    if ($('input.greymelange').is(':checked')) { 
      productIds.push("4021401143741", "4021402266227","4021402266418", "4021401143796"); 
    } 
}); 

HTML

<input type="checkbox" id="white" class="white" value="white" />     
<input type="checkbox" id="greymelange" class="greymelange" value="greymelange" /> 
<a href="#" class="filter-btn">filter</a> 
+0

......你究竟想用这段代码来做什么?我认为重新设计您的代码来循环使用产品而不是过滤器会简化您的代码,并且对数据库更友好。 – user1618143

回答

4

您可以使用$.inArray()$.each()

1)保持一个数组deArray内所有新的价值观。
2)使用$.each遍历这个数组,然后找到它是否在productIds 使用​​

if ($('input.greymelange').is(':checked')) { 
     var deArray = ["4021401143741", "4021402266227", "4021402266418", "4021401143796"]; 
     $.each(deArray, function (i, j) { 
      if ($.inArray(j, productIds) == -1) { 
       productIds.push(j); 
      } 
     }); 
    } 

建议:不数组声明空字符串。

var productIds = [""]; //considered as an string. This will affect 
         //when you check length, now it is 1 
var productIds = []; //length is 0 

最后,

var productIds = []; 

$(document).on('click', 'a.filter-btn', function (e) { 
    $(".listingTemplate").html(""); 
    if ($('input.white').is(':checked')) { 
     var dArray = ["4021401143741", "4021402266227"]; 
     $.each(dArray, function (i, j) { 
      if ($.inArray(j, productIds) == -1) { 
       console.log(j) 
       productIds.push(j); 
      } 
     }) 
    } 

     if ($('input.greymelange').is(':checked')) { 
      var deArray = ["4021401143741", "4021402266227", "4021402266418", "4021401143796"]; 
      $.each(deArray, function (i, j) { 
       if ($.inArray(j, productIds) == -1) { 
        productIds.push(j); 
       } 
      }) 
     } 
      console.log(productIds) 
     }); 

JSFiddle

+0

嗨,不应该在每个函数的某个地方使用deArray? – user1937021

+0

@ user1937021好赶上:)我已更新。它应该用在'每个' – Praveen

+0

@ user1937021我有一些错字错误,我已经修复它在这个小提琴http://jsfiddle.net/74MAr/ – Praveen

0

你需要检查,如果你添加到列表前的项目包含。不幸的是这并不容易,因为它应该是,但下面的堆栈解释说:How do I check if an array includes an object in JavaScript?

既然你这个标记作为jQuery的,下面的(例子)代码可能为你工作:

if ($.inArray("4021401143741", productIds) === -1) 
    productIds.push("4021401143741"); 

更多有关此通话的信息​​see here。祝你好运!

0

要检查的项目在数组中已经存在,你可以使用Array.indexOf。请注意,IE < 9本身并不存在,但是我已经发布了一个代码片断,如果它不可用,它会将它添加到Array原型。

var products = []; 
function addProducts() { 
    for(var i = 0, l = arguments.length; i < l; i++) { 
     if(products.indexOf(arguments[i]) === -1) { 
      products.push(arguments[i]); 
     } 
    } 
} 
//Add indexOf if it doesn't exist natively 
if (!Array.prototype.indexOf) { 
    Array.prototype.indexOf = function(elt) { 
     var len = this.length >>> 0; 
     var from = Number(arguments[1]) || 0; 
     from = (from < 0) 
      ? Math.ceil(from) 
      : Math.floor(from); 
     if (from < 0) 
      from += len; 

     for(; from < len; from++) { 
      if(from in this && this[from] === elt) 
      return from; 
     } 
     return -1; 
    }; 
} 

然后使用这些新功能,你可以修改你的代码:

$(document).on('click', 'a.filter-btn', function(e) { 
    if($('input.white').is(':checked')) { 
     addProducts("4021401143741", "4021402266227"); 
    } 
    if($('input.greymelange').is(':checked')) { 
     addProducts("4021401143741", "4021402266227","4021402266418", "4021401143796"); 
    } 
}); 

正如一个方面说明。如果您可以避免它,则不应将事件绑定到文档。如果您使用大量事件,将事件绑定到文档可能会导致性能问题。每次触发一个click事件时,都会运行此函数来检查目标是否与您指定的目标匹配。为了限制这种性能命中,你应该将它们绑定到最接近的不变元素。在表单内部的输入示例中,可以将其添加到表单中。

0

将以下代码添加到缺血性条件下。 // Continue execution推送值。

isSet = false; 
currentVal = '999999999999'; 
$.each(productIds, function(index, value) { 
    if(value == currentVal){ 
    isSet = true; 
    } 
}); 

if(isSet){ 
// Continue execution 
} else { 
// failure 
} 
0

它需要是一个数组吗?这听起来像你更好使用一个普通的对象:

productIds[ 420… ] = true; 

这取决于你的代码的其余部分,但它听起来像你想实现一个哈希/查找表/字典,而不是一个数组 - 以这种方式检查存在也更直接。

2

如果你只有一组固定的产品ID,为什么你需要一个可变长度的数组来存储哪个产品ID被检查?

我会建议也许建立一个包含这个逻辑的对象,你可以使用。

function productMapper() { 
    var colorToIdMap = { 
     'white' = [ 
      '4021401143741', 
      '4021402266227' 
     ], 
     'greymelange' = [ 
      '4021401143741', 
      '4021402266227', 
      '4021402266418', 
      '4021401143796' 
     ] 
    }; 
    var selectedIds = []; 
    function selectIds(color) { 
     this.selectedIds = []; 
     var colorIds = this.colorToIdMap[color]; 
     for(i = 0; i < colorIds.length; i++) { 
      var currentId = colorIds[i]; 
      if(this.selectedIds.indexOf(currentId) === -1) { 
       this.selectedIds.push(currentId); 
      } 
     } 
    } 
    function getSelectedIds() { 
     return this.selectedIds; 
    } 
} 

用法可能是:

var selectedProductMap = new productMapper(); 

$(document).on('click', 'a.filter-btn', function(e){ 

    $(".listingTemplate").html(""); 
    if ($('input.white').is(':checked')) { 
      selectedProductMap.selectIds('white'); 
    } 

    if ($('input.greymelange').is(':checked')) { 
      selectedProductMap.selectIds('greymelange'); 
    } 
}); 

这样做的好处是,当你添加新的颜色和产品ID的很容易,只是将它们添加到这个类(或具有动态生成的类的部分从一个数据库。

我也建议寻找重构HTML,这样你不需要为每个颜色选项添加if条件。也许给所有复选框输入一个公共类并从输入派生颜色值财产这样就可以在你的onclick函数中执行:

$('input.filterCheckbox').each(function(index.value)) { 
    var $currentCheckbox = $(this); 
    if($currentCheckbox.is(':checked')) { 
     selectedProductMap.selectIds($currentCheckbox.val()); 
    } 
} 

var currentlySelectedIds = selectedProductMap.getSelectedIds(); 
相关问题