I am trying to dynmaically create round checkboxes with tickMark which get appended to id="demo"
onclick of two buttons which call get(data)
method.
The issue is when two buttons called simulataneously, checkbox is not getting tick mark and causing call of getdata(idD + '_chckBox')
method twice or more as seen in console.log.
However, I am using e.preventDefault(); e.stopPropagation();
.
What is the issue here, the getdata(idD + '_chckBox')
is called twice or more and roundcheckbox is not getting checked?
I am trying to toggle checkbox and show tick mark. If any better way of doing this possible, is also welcomed.
what is the best and easiest way to bind onclick
and onscroll
method in dynamic htmls which are in for loop, so that a object can be passed as a parameter in called method onclick.
var data0 = [{
"title": "a"
},
{
"title": "b"
},
{
"title": "c"
},
{
"title": "d"
},
];
var data1 = [{
"title": "ads"
},
{
"title": "bd"
},
{
"title": "fc"
},
{
"title": "dg"
},
];
var html = "<div id='parent' ' + 'onscroll="loadMoreContent(event)" ></div>";
$(html ).appendTo('body');
$(document).on('click', '#btn11', () => {
get(data0, 'parent');
})
$(document).on('click', '#btn00', () => {
get(data1,'parent');
})
function loadMoreContent(event){
// gettting server data (data01 ) on ajax call
var data01 = [{
"title": "aaa"
},
{
"title": "sdw3b"
},
{
"title": "c433"
},
{
"title": "34d"
},
];
get(data01 , idToAppend)
}
function get(data, idToAppend) {
var html = '';
html += '<div class="col-12 parentdiv">';
$.each(data, function(key, msgItem) {
var idD = msgItem.title + key;
html += '<div class="flLeftBlock" style="width: 30px;margin-top: 36px;">';
html += '<div class="roundCheckboxWidget" id="' + idD + '_roundCheckboxWidget">';
html += '<input id="' + idD + '_chckBox" class="" type="checkbox" tid="" title="discard">';
html += '<label id="' + idD + '_chckBox_label" for="' + msgItem.title + '" ></label> ';
html += " " + msgItem.title;
html += '</div>';
html += '</div>';
html += '';
});
html += '</div>';
$('#'+ idToAppend).append(html);
$.each(data, function(index, element) {
var idD = element.title + index;
const self = this;
$(document).on('click', '#' + idD + '_chckBox_label', (e) => {
if (e.target.tagName === "LABEL") {
e.preventDefault();
e.stopPropagation();
console.log('#' + idD + '_chckBox_label');
getdata(idD + '_chckBox');
}
});
});
}
function getdata(id) {
console.log(id);
$("#" + id).prop("checked", !$("#" + id).prop("checked"));
return true;
}
.roundCheckboxWidget {
position: relative;
}
.roundCheckboxWidget label {
background-color: #ffffff;
border: 1px solid rgb(196, 196, 209);
border-radius: 50%;
cursor: pointer;
height: 22px;
left: 0;
position: absolute;
top: 0;
width: 22px;
}
.roundCheckboxWidget label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 4px;
opacity: 0;
position: absolute;
top: 6px;
transform: rotate(-45deg);
width: 12px;
}
.roundCheckboxWidget input[type="checkbox"] {
visibility: hidden;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
/* background-color: #6168e7 !important;
border-color: 1px solid #6168e7 !important; */
}
.roundCheckboxWidget input[type="checkbox"]:checked+label:after {
opacity: 1;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
background-color: #ff5b6a;
border-color: #ff5b6a !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Alternate click on two buttons without refreshing causing getdata() method call twice. </p>
<button id="btn11" onclick="get()">Try It</button>
<button id="btn00" onclick="get()">Try It2</button>
<div id="demo"></div>
There is several mistakes here.
id
that aren't unique. There is an attempt to make them unique, but you used the array key
, which is static. So on every button click, duplicate ids are produced. You need a counter..each()
loop to define a delegated event handler... Which is a misunderstanding of delegation.checkbox
state when the for=
attribute on the label
can do it without a single line of code.loadMoreContent()
function is unclear... I assumed you want an "infinite scroll"... So you have to check if the bottom of the page is reached to call the Ajax request... Else, you will fire tons of request on each scroll... up and down!So here is how to do it:
(See comment within code)
// checkbox title arrays
var data0 = [{ "title": "a" }, { "title": "b" }, { "title": "c" }, { "title": "d" }];
var data1 = [{ "title": "ads" }, { "title": "bd" }, { "title": "fc" }, { "title": "dg" }];
// Appends th "parent" div on load.
var html = "<div id='parent'></div>";
$(html).appendTo('body');
// Button handlers
$(document).on('click', '#btn11', () => {
get(data0,'parent');
})
$(document).on('click', '#btn00', () => {
get(data1,'parent');
})
// Simulated Ajax request... I assume.
function loadMoreContent(idToAppend){
// gettting server data (data01 ) on ajax call
var data01 = [{ "title": "aaa" }, { "title": "sdw3b" }, { "title": "c433" }, { "title": "34d" } ];
get(data01 , idToAppend)
}
// Main function. It needs a counter to create UNIQUE ids.
var checkbox_counter = 0;
function get(data, idToAppend) {
var html = '';
html += '<div class="col-12 parentdiv">';
$.each(data, function(key, msgItem) {
html += '<div class="flLeftBlock" style="width: 30px;margin-top: 36px;">';
html += '<div class="roundCheckboxWidget">';
html += '<input id="checkbox_'+checkbox_counter+'" type="checkbox" tid="" title="discard">';
html += '<label for="checkbox_'+checkbox_counter+'"></label> ';
html += " " + msgItem.title;
html += '</div>';
html += '</div>';
html += '';
// Increment the checkbox counter
checkbox_counter++;
});
html += '</div>';
$('#'+ idToAppend).append(html);
}
// Just to console log the id of the checkbox...
$(document).on('click', 'label', function(){
var checkbox_id = $(this).prev("[type='checkbox']").attr("id");
console.log(checkbox_id);
});
// On scroll handler, check if the bottom of the page is reached to load some more...
$(document).on('scroll', function(){
var scrolled = Math.ceil($(window).scrollTop());
var viewport_height = $(window).outerHeight();
var window_full_height = $(document).outerHeight();
//console.log(scrolled +" "+ viewport_height +" "+ window_full_height);
if(scrolled + viewport_height == window_full_height){
console.log("reached the bottom... Loading some more!");
// Call the Ajax request
loadMoreContent("parent");
}
});
.roundCheckboxWidget {
position: relative;
}
.roundCheckboxWidget label {
background-color: #ffffff;
border: 1px solid rgb(196, 196, 209);
border-radius: 50%;
cursor: pointer;
height: 22px;
left: 0;
position: absolute;
top: 0;
width: 22px;
}
.roundCheckboxWidget label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 4px;
opacity: 0;
position: absolute;
top: 6px;
transform: rotate(-45deg);
width: 12px;
}
.roundCheckboxWidget input[type="checkbox"] {
visibility: hidden;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
/* background-color: #6168e7 !important;
border-color: 1px solid #6168e7 !important; */
}
.roundCheckboxWidget input[type="checkbox"]:checked+label:after {
opacity: 1;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
background-color: #ff5b6a;
border-color: #ff5b6a !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Alternate click on two buttons without refreshing causing getdata() method call twice. </p>
<button id="btn11" onclick="get()">Try It</button>
<button id="btn00" onclick="get()">Try It2</button>
<div id="demo"></div>
CodePen
There are two problems with code:
onclick="get()"
and also adding click
event using jQuery so it will trigger twice. remove onclick ="get()"
get()
call it will add new click
listeners to checkboxes. To prevent that use a boolean in your array only apply click
event oncevar data0 = [{
"title": "a"
},
{
"title": "b"
},
{
"title": "c"
},
{
"title": "d"
},
false
];
var data1 = [{
"title": "ads"
},
{
"title": "bd"
},
{
"title": "fc"
},
{
"title": "dg"
},
false
];
$(document).on('click', '#btn11', () => {
get(data0);
})
$(document).on('click', '#btn00', () => {
get(data1);
})
function get(data) {
var html = '';
html += '<div class="col-12 parentdiv"';
$.each(data, function(key, msgItem) {
var idD = msgItem.title + key;
html += '<div class="flLeftBlock" style="width: 30px;margin-top: 36px;">';
html += '<div class="roundCheckboxWidget" id="' + idD + '_roundCheckboxWidget">';
html += '<input id="' + idD + '_chckBox" class="" type="checkbox" tid="" title="discard">';
html += '<label id="' + idD + '_chckBox_label" for="' + msgItem.title + '" ></label> ';
html += " " + msgItem.title;
html += '</div>';
html += '</div>';
html += '';
});
html += '</div>';
$('#demo').html(html);
if(data[data.length - 1]) return false;
$.each(data, function(index, element) {
var idD = element.title + index;
const self = this;
if(index === data.length - 1) return false;
$(document).on('click', '#' + idD + '_chckBox_label', (e) => {
if (e.target.tagName === "LABEL") {
e.preventDefault();
e.stopPropagation();
//console.log('#' + idD + '_chckBox_label');
getdata(idD + '_chckBox');
}
});
});
data[data.length -1] = true;
}
function getdata(id) {
//console.log(id);
$("#" + id).prop("checked", !$("#" + id).prop("checked"));
return true;
}
.roundCheckboxWidget {
position: relative;
}
.roundCheckboxWidget label {
background-color: #ffffff;
border: 1px solid rgb(196, 196, 209);
border-radius: 50%;
cursor: pointer;
height: 22px;
left: 0;
position: absolute;
top: 0;
width: 22px;
}
.roundCheckboxWidget label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 4px;
opacity: 0;
position: absolute;
top: 6px;
transform: rotate(-45deg);
width: 12px;
}
.roundCheckboxWidget input[type="checkbox"] {
visibility: hidden;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
/* background-color: #6168e7 !important;
border-color: 1px solid #6168e7 !important; */
}
.roundCheckboxWidget input[type="checkbox"]:checked+label:after {
opacity: 1;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
background-color: #ff5b6a;
border-color: #ff5b6a !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Alternate click on two buttons without refreshing causing getdata() method call twice. </p>
<button id="btn11">Try It</button>
<button id="btn00">Try It2</button>
<div id="demo"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With