javascript - 复选框仅在搜索后第二次单击后才有效

标签 javascript jquery html css checkbox

我正在尝试创建 vendor 列表(复选框 + 标签)和搜索字段以过滤 vendor 。我设法渲染了列表,在第一次加载后它工作正常,但在我搜索 vendor 列表后,首先单击复选框不起作用。我需要单击两次才能选中复选框。 screenshot

在搜索 vendor 列表时,我需要在第一次单击后选中复选框。请帮忙。

我创建了这个 fiddle here

HTML:

<div class="col-sm-12">
    <div class="infoBlock suppliersWrapper">
        <div class="blockTitle">Supplier:</div>
        <div class="blockContent">
            <p class="checkedSupliersTitile">Supplier list:</p>
            <div class="row">  
                <div class="col-sm-12 col-lg-8">                                 
                    <input type="text" class="form-control stickTop" placeholder="Search..." id="SearchSupplierInput">
                    <ul class="supplierList scrollable" id="suppliers"></ul>
                </div>
                <div class="col-sm-12 col-lg-4">
                    <p class="checkedSupliersTitile">Checked suppliers:</p>
                    <p class="checkedSupliersText" id="checkedSuppliers">no suppliers selected</p>
                </div>
            </div>
        </div>
    </div>
</div>

CSS:

.supplierList label {
    color: #575757;
    display: block;
    font-size: 15px;
    font-weight: 400;
    cursor:pointer;
    font-family: 'Ubuntu', sans-serif;
}

.supplierList input[type="checkbox"   ]{
    width     : 2em;
    margin    : 0;
    padding   : 0;
    font-size : 1em;
    opacity   : 0;
}  

.supplierList input[type="checkbox"   ] + label{
    display      : inline-block;
    margin-left  : -1em;
    line-height  : 1.5em;
    position:relative;
    z-index: 33;
}

.supplierList input[type="checkbox"] + label::before {
    border: 1px solid #d6d6d6;
    border-radius: 1px;
    content: "";
    height: 20px;
    left: -1.8em;
    position: absolute;
    top: 0.06em;
    width: 20px;
    -webkit-box-shadow: 3px 3px 0 0 rgba(25, 24, 25, 0.04) inset;
    -moz-box-shadow: 3px 3px 0 0 rgba(25, 24, 25, 0.04) inset;
    box-shadow: 3px 3px 0 0 rgba(25, 24, 25, 0.04) inset;
    background: #ffffff;
}

.supplierList input[type="checkbox"   ]:checked + label:before{
    background:#46c87c;
}

.supplierList input[type="checkbox"]:checked + label::after {
    color: #fff;
    content: "";
    font-family: "fontawesome";
    left: -1.6em;
    position: absolute;
    top: 0;
}

JavaScript:

$(document).ready(function() {
    var SupplierList = [{"name":"125","id":"1"},
                    {"name":"2Bit Telecom Corporation","id":"2"},
                    {"name":"Alleven Telecom Corp Standart","id":"3"}];
var selectedSuppliers = [];
// Собираем и фильтруем активных поставшиков 


renderSupplierList(SupplierList);

$("#SearchSupplierInput").on("change paste keyup", function() {
    var userInput = $(this).val();        
    var my_json = JSON.stringify(SupplierList);
    var filtered_supplierList = find_in_object(JSON.parse(my_json), {name:userInput});

    if (userInput.length >= 3) {
        $("#suppliers").html("");        
        renderSupplierList(filtered_supplierList);
    } else if(!userInput) {
        $("#suppliers").html("");
        renderSupplierList(SupplierList);
    }
});   

function renderSupplierList(array) {
    array.forEach(function(item, i) {
    if(typeof selectedSuppliers["id"+item.id] === 'undefined') {
        var ifCheckd = "";
    }
    else {
        var ifCheckd = "checked";
    }
    $("#suppliers").append('\
                <li><span>\n\
                <input class="supplierSelect" type="checkbox" id="supplier'+i+'" ' + ifCheckd + ' name="supplier" value="'+ item.id +'"> \n\
                <label for="supplier'+i+'">'+ item.name +'</label>\n\
                </span></li>');
    });       
}

function find_in_object(my_object, my_criteria) {

    return my_object.filter(function(obj) {
        //console.log(obj);
        return Object.keys(my_criteria).every(function(c) {
        //if (obj[c].search(/my_criteria[c]/i) == -1) {
            if (obj[c].search(new RegExp(my_criteria[c], "i")) == -1) {
                return false;
            } else {
                return true;
            }
        });
    });

}

$('.supplierList').on('change', 'input[type=checkbox]', function() {
    supplierCheckboxChange(this);
});

function sortSingle(array, key) {
    return array.sort(function(a, b) {
        var x = a[key]; var y = b[key];
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        });
    }

    function supplierCheckboxChange(currEl) {
        var cText = $( currEl ).siblings("label").text();
        var cID = "id" + currEl.value;

        if(currEl.checked) {
            selectedSuppliers[cID] = cText;
        }
        else {
            delete selectedSuppliers[cID];
        }

        var tmpSuppl = [];

        for (var key in selectedSuppliers) {
            tmpSuppl.push(selectedSuppliers[key]);
        }

        tmpSuppl.sort(function(a, b) {
            var x = a.toLowerCase(); var y = b.toLowerCase();
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        });

        var suppliers = tmpSuppl.join(', ');
        if (!suppliers) {
            suppliers = "no suppliers selected";
        }

        $('#checkedSuppliers').text(suppliers);
    }  

});

最佳答案

发生这种情况是因为您的 renderList 函数被调用了不止一次。首先 keyup 在你按下一个键时被触发,然后当文本框失去焦点时(当你点击复选框时) change 被触发。

这会导致您的 renderList 方法执行两次,并且选中的复选框被新的复选框替换。

要解决这个问题,只需更改

$("#SearchSupplierInput").on("change paste keyup", function() { ... }

$("#SearchSupplierInput").on("paste keyup", function() { ... }

看看这个 fiddle 并检查控制台。 https://jsfiddle.net/nh7u4Lck/2/

关于javascript - 复选框仅在搜索后第二次单击后才有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42772122/

相关文章:

javascript - 无法读取未定义的属性 'replace' - 替换 JS 生成的 HTML 中的文本

Javascript : How group and sum values from multidimensional array

jquery - 谷歌浏览器使用 jquery 在 css 更改上添加不需要的边距

jquery - 响应式菜单不起作用

javascript - 我无法让容器 <div> 的内容正确居中

php - 将 HTML header 分离到不同的 PHP 文档中

JavaScript 比较 2 个数组(某种意义上)

javascript - 如何重新启动 while 循环?

jquery - CKeditor 实例已存在

javascript - 单击jquery中的按钮后如何添加新的选择框