javascript - jQuery .change DRY code -


i have put checkboxes using 'bootstraptoggle' plugin. building mongodb query based on boxes checked.

the code works flawlessly hate repeating .change, there way make dry?

i have following code

html

<div id="checkboxcontainer" class="container">      <label class="checkbox-inline">           <input type="checkbox" id="optionone" data-onstyle="success" data- offstyle="danger" data-toggle="toggle">      </label>      <label class="checkbox-inline">           <input type="checkbox" id="optiontwo" data-onstyle="success" data- offstyle="danger" data-toggle="toggle">      </label> </div> 

js

$('#optionone').change(function() {     if ($(this).prop('checked') == true) {         querybuilder.push($(this).attr("id"));     } else if ($(this).prop('checked') == false) {         querybuilder.splice($(this).attr("id"));     }     console.log(querybuilder); });   $('#optiontwo').change(function() {     if ($(this).prop('checked') == true) {         querybuilder.push($(this).attr("id"));     } else if ($(this).prop('checked') == false) {         querybuilder.splice($(this).attr("id"));     }     console.log(querybuilder); }); 

i have searched , tried following no luck.

$('document').on('change','#checkboxcontainer', function() {           if ($(this).prop('checked') == true) {         querybuilder.push($(this).attr("id"));     } else if ($(this).prop('checked') == false) {         querybuilder.splice($(this).attr("id"));     }     console.log(querybuilder);  }); 

is there way make dry?

$('#optionone, #optiontwo').change(...); 

that's called selector group. none of code in change handler specific element hooked to, purely matter of hooking both elements.


unrelated, but: line suspect:

querybuilder.splice($(this).attr("id")); 

splice expects @ least 2 arguments: index start doing things at, , number of elements delete @ location (which might 0, if you're going have more arguments specify things insert).

if goal remove $(this).attr("id")'s value array, won't it. instead:

var index = querybuilder.indexof($(this).attr("id")); if (index != -1) {     querybuilder.splice(index, 1); } 

that finds if it's there, , removes it.


side note:

as squint said, $(this).attr("id") long way write this.id, , $(this).prop("checked") long way write this.checked. :-)

there's never reason write == true when doing comparison (there is, rarely, reason write === true).

finally, checked can ever true or false, there's no need second if.

so:

$('#optionone, #optiontwo').change(function() {     var index;     if (this.checked) {         querybuilder.push(this.id);     } else {         index = querybuilder.indexof(this.id);         if (index != -1) {             querybuilder.splice(index, 1);         }     }     console.log(querybuilder); }); 

or shorter:

$('#optionone, #optiontwo').change(function() {     var index;     if (this.checked) {         querybuilder.push(this.id);     } else if ((index = querybuilder.indexof(this.id)) != -1) {         querybuilder.splice(index, 1);     }     console.log(querybuilder); }); 

over-analyzing markedly, i'll note if think there's chance of being in array when checkbox isn't checked, should bit more defensive avoid putting in twice:

$('#optionone, #optiontwo').change(function() {     var index = querybuilder.indexof(this.id);     if (this.checked && index == -1) {         querybuilder.push(this.id);     } else if (!this.checked && index != -1) {         querybuilder.splice(index, 1);     }     console.log(querybuilder); }); 

okay, i'll stop now. :-)


gah, 1 more thing: very old browsers don't have array#indexof, if need support them, you'll need add shim or use jquery's badly misnamed $.inarray instead. use inarray, change querybuilder.indexof(this.id) $.inarray(querybuilder, this.id) (nothing else needs changing).


Comments