Click function not registering correctly in Jquery - javascript

I have a function that should be triggered on click of productid...
$("[id^='productid']").click(function(){
var numberPattern = /\d+/g;
match = this.id.match(numberPattern)
})
The products are generated using Jquery pagination as given below....
function createproducts(jsondata){
transactiondata = jsondata
$("<div id='product-container'></div>").appendTo("#product-list");
$('#pagination').pagination({
items: jsondata.length
,itemsOnPage: 12
,onInit:redrawData
,onPageClick: redrawData
,cssStyle: 'light-theme'});
}
function redrawData(pageNumber,event){
if (pageNumber) {
slicedata = transactiondata.slice(pageNumber*12,
Math.min((pageNumber+1)*12,transactiondata.length));
}
else {
slicedata = transactiondata.slice(0,12)
}
$("#product-container").empty()
slicedata.forEach(function(e,i,a){
var obj = e;
$("<div id = productid" + i + " class = product-cards </div>").appendTo('#product-container')
//-working$("<div id='product" + i + "left' class='product-cards-left' style='background-image:url( " + imagepath_start + obj.image_caption + ")'> </div>").appendTo('#product' + i);
//lightbox is the jquery plugin that we use..The below line is very sensitive...
//-lightbox working$(" <div id='product" + i + "left' class='product-cards-left' style='background-image:url( " + imagepath_start + obj.image_caption + ")' > </div>").appendTo('#product' + i);
$("<div id='product" + i + "left' class='product-cards-left' style='background-image:url( " + imagepath_start + obj.image_caption + ")'> </div>").appendTo('#productid' + i);
$("<div id = product" + i + "right class = product-cards-right> </div>").appendTo('#productid' + i )
$("<label><b> Price: <b></label> <label>" + '$' + obj.price + "</label><br>").appendTo('#product' + i +"right" )
$("<label><b> Old Price: <b></label> <label>" + '$' + obj.old_price + "</label><br>").appendTo('#product' + i +"right" )
$("<label><b> Author Name: <b></label> <label>" + obj.author_name + "</label>").appendTo('#product' + i +"right" )
$("<div id= elementid style='display:none' >"+ obj.id+" </div>").appendTo('#product' + i +"right" )
//$("<label>" + obj.name + "</label>").appendTo('#product' + i +"right" )
})
Problem:-
When I click the productid the click function is correctly working and calculates "match" correctly..But once I move to next page(Onpageclick is triggered) and click productid, the click function is not working anymore..Why would this happen?

You can use $(document) handler so that your click handler is not lost.
$(document).on("click", "[id^='productid']", function(){
var numberPattern = /\d+/g;
match = this.id.match(numberPattern)
});

You need to use a delegated event handler like this:
$(document).on("click", "[id^='productid']", function(){
var numberPattern = /\d+/g;
match = this.id.match(numberPattern)
});
It works by listening for events bubbled up to a non-changing ancestor element, then applying the jQuery selector on the chain of elements that caused the event, then applies the function to any matching elements that caused the event.
You would normally attached the delegated event to the nearest non-changing ancestor element, but the fallback is document if nothing is convenient to use. Do not ever use body for delegated events as it has a bug with some events (due to styling).

When you change the page you lose the hook jquery adds on the DOM which is triggering the click. Just recall the method that listens to clicks on page change.

Related

Find all div's beginning with id="string", iterate through result and change their id's

I have a button which creates div's with numbered id's (div0, div1, div2). Each div contains a button to delete the div. The buttons are also numberes (delete_div0, delete_div1, delete_div2).
After delete e.g. div0, I want to reorganize everything so it starts from 0 again (in this case div1 -> div0 and div2 -> div1.
Another example: Delete div1, div0 -> div0, div2 -> div1.
Any help?
var counter_div = 0;
$("#add_div").click(() => {
$("#divs").append("<div id='div" + counter_div + "'>Div " + counter_div + " <button id='delete_div" + counter_div + "' type='button'>X</button></div>");
//add listener
$("#delete_div" + counter_div).click((event) => {
nr = event.target.id.substring(
event.target.id.length - 1,
event.target.id.length
);
$("#div" + nr).remove();
})
// this is where I am struggling reorganizing divs
function reorganize() {
$("div[id^=div]").each((element) => {
$(this).prop("id", "div" + element);
});
}
reorganize();
counter_div++;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id='add_div' type='button'>Add div</button></div>
<div id='divs'></div>
EDIT:
Thanks to everbody, I found a mix out of every solution.
$("#delete_div" + counter_div).click((event) => {
//remove div
$(event.currentTarget).parent().remove();
//reorder all ingredients
$("div[id^=div]").each((element) => {
$(this)
.find("div[id^='div']")
.eq(element)
.prop("id", "div" + element);
};
});
Probalby not the most beautiful solution, but it works. What I did not understand yet is why $(this) in the each-function gives different results depending on which syntax I use.
$("div[id^=div]").each(function(element) {console.log($(this))};
is different to
$("div[id^=div]").each((element) => {console.log($(this))};
You can perform delete with $(event.currentTarget).parent().remove();.
Similarly if you want to select any input from on such button click you can use $(event.currentTarget).parent().find("input").
Or you want to loop over divs and find all inputs then you can use :
$('#divs > div[id^=div]').each(function(k) {
var allInputs = $(this).find('input');
});
var counter_div = 0;
$("#add_div").click(() => {
$("#divs").append("<div id='div" + counter_div + "'>Div " + counter_div + " <button id='delete_div" + counter_div + "' type='button'>X</button></div>");
//add listener
$("#delete_div" + counter_div).click((event) => {
$(event.currentTarget).parent().remove();
})
counter_div++;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id='add_div' type='button'>Add div</button></div>
<div id='divs'></div>
First call your reorganize on remove
$("#div" + nr).remove();
reorganize();
})
then:
var numDivsNum=-1;
//set first id -1
function reorganize() {
[...document.querySelectorAll("#divs > div[id^='div']")].forEach(el => {
el.id="div"+(++numDivsNum);
// for each element add new id +1
el.innerHTML=el.innerHTML + "New id= " +numDivsNum;
});
}
And your selector was wrong, it should be:
div[id^='div']
not
div[id^=div]
var counter_div = 0;
$("#add_div").click(() => {
$("#divs").append("<div id='div" + counter_div + "'>Div " + counter_div + " <button id='delete_div" + counter_div + "' type='button'>X</button></div>");
//add listener
$("#delete_div" + counter_div).click((event) => {
nr = event.target.id.substring(
event.target.id.length - 1,
event.target.id.length
);
$("#div" + nr).remove();
reorganize();
})
// this is where I am struggling reorganizing divs
var numDivsNum=-1;
function reorganize() {
[...document.querySelectorAll("#divs > div[id^='div']")].forEach(el => {
el.id="div"+(++numDivsNum);
el.innerHTML=el.innerHTML + "New id is id='div" +numDivsNum+"'";
});
}
counter_div++;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id='add_div' type='button'>Add div</button></div>
<div id='divs'></div>
You can re-index them like this:
$('div[id^="div"]').each(function(k) {
$(this).prop('id', 'div' + k);
});
But personally I'd give them all a class so you don't have to rely on the begins with div selector, and then consider using data-id instead of id. data-id will be easier to extract as an integer later and that appears to be your goal. Maybe something like this?
$('div.my_class').each(function(k) {
$(this).data('id', k);
});
$("#delete_div" + counter_div).click((event) => {
//remove div
$(event.currentTarget).parent().remove();
//reorder all ingredients
$("div[id^=div]").each((element) => {
$(this)
.find("div[id^='div']")
.eq(element)
.prop("id", "div" + element);
};
});
You have almost done
But there are some stuff that needs to be fixed
$(this).parent('div').eq(0).remove();

Want to add delete functions for a list of date displayed

to summarize my problem ... I have made a calendar with contains the from - to date range. Now the selected dates are displayed in a div with a delete button for each. But as the id of the button is the same for all the dates ....it deletes the entire date range. I have attached the screenshot as well.
I also tried taking a loop and giving each date a div so that the Del function will work properly. but I wasn't successful. I will mention code for the same
$(document).ready(function () {
var i = 0;
$.each(between, function (key, value) {
var rest = $('#target').append($('<div id="r' + i +value+ '" class="ansbox">
</div>'));
console.log(between);
var template = '<div id="ChildTarget_' + i + '"><span>key + ":" + "' + value + '"
</span><button id="tr' + i + '" class="target">X</button></div><br></div>';
i++;
$('#target').on('click', function () {
console.log("hola");
$('#target').remove();
You should add click event for the button itself.
var template = `
<div id="ChildTarget_' + i + '">
<span>key + ":" + "' + value + '"</span>
<button id="tr' + i + '" class="deleteButton">X</button>
</div>`;
$(".deleteButton').on('click', function() {
// do deletion here
});
First of all ,
The 'X' button should have different id
$.each(between, function (key, value){
$('#results').append(key+":"+value+'<br>');
$('#results').html(between.join('<button id="result"+key+"" > X </button><br>')
here you can see i am adding key to the Button Id making it unique. Use that id to remove the value, that you dont want. Hope this helps

JQuery "Attribute Starts With" Selector Undefined

I have a modal dialog (Bootstrap) that has a list-group with custom list-group-items inside of it (populated by loop using append after adding data from my server).
Inside each list-group-item, I have a Checkbox that will be used to "select" the result. As I populate the items, I hook up the JQuery click event to the respective Checkbox:
// Add to search results
$('#search-results').append(
'<a id="centroid-list-item-' + featureAttrs['ObjectID'] + '" href="\\#"' + 'class="list-group-item" style="outline: 0">' +
'<table style="background: transparent">' +
'<tr>' +
'<td>' +
'<input id="centroid-checkbox-' + featureAttrs['ObjectID'] + '" type="checkbox" value=""> ' +
'</td>' +
'<td>' +
'<h4 class="list-group-item-heading">' +
featureAttrs['UNIQUEID'] +
'</h4>' +
'<p id="centroid-item-text-' + featureAttrs['ObjectID'] + '"' + 'class="list-group-item-text">' +
featureAttrs['NAME'] +
'</p>' +
'</td>' +
'</tr>' +
'</table>' +
'</a>'
);
// When the DOM is ready, add event
$(document).ready(function () {
$('#centroid-checkbox-' + featureAttrs['ObjectID']).click(function (event) {
var objectId = $(this).attr('id').replace(/^\D+/g, '');
console.log(objectId + " was clicked");
if ($(this).is(':checked')) {
// Enable the 'Set Target' button
$('#btn-set-target').removeAttr('disabled');
// Disable all other choices
$('[id^="centroid-checkbox-"]').each(function (event) {
console.log("Picked up values for checkboxes");
if ($(this).attr('id') != ('centroid-checkbox-' + objectId)) {
$(this).attr('disabled', true);
}
});
}
else {
$('#btn-set-target').attr('disabled', 'disabled');
// Enable all text boxes
$('[id^="centroid-checkbox-"]').each(function () {
if (this.attr('id') !== ('centroid-checkbox-' + objectId)) {
this.removeAttr('disabled');
}
});
}
});
});
The problem I am having is that when I call $('[id^="centroid-checkbox-"]') it is returning undefined. However, at the time is gets called, there are about 30 "centroid-checkbox-XXXXX" checkboxes. What am I doing wrong here?
The $ function never returns undefined.
But this in the callback you pass to each is an element, not a jQuery object.
Which means you must use this.id instead of this.attr('id') and $(this).removeAttr('disabled') instead of this.removeAttr('disabled') (and you probably want this.disabled=false or $(this).prop('disabled', false)).
objectId never gets defined because you need to quote enclose the regular expression you're using for replace():
var objectId = $(this).attr('id').replace(/^\D+/g, '');
should be:
var objectId = $(this).attr('id').replace('/^\D+/g', '');
DEMO: http://jsfiddle.net/4fUvn/8/

How to listen for events in this case

I am dynamically building required components as per css
provided , this way dynamically
for (var i = 0; i < responseinner.length; i++) {
for (var k = 0; k < responseinner[i].type.length; k++) {
random_number += 1;
htmlbuilder.append('<div data-role="collapsible"><h3>' + obj.name + '</h3><div class="prd-items-detials"><ul><li class="head"><form><input type="checkbox" class="checkboxclas" name="checkbox-mini-0" id="' + random_number + '" data-mini="true"><label for="checkbox-mini-0">' + responseinner[i].type[k] + '</label></form></li><li class="prd-items-qt"><div class="col"><i class="minus"></i><i class="qt">1</i><i class="plus"></i></div><div class="col"></div><div id ="' + responseinner[i].type[k] + '" class="col">Rs: ' + responseinner[i].price[k] + '/-</div></li></ul></div></div>');
}
}
Finally . i have registered with the click event for the above generated checkbox .
$(document).on("click", ".checkboxclas", function (e) {
if($(this).is(':checked'))
{
}
});
Is there any way i can access data present at below div
<div id ="' + responseinner[i].type[k] + '" class="col">Rs: ' + responseinner[i].price[k] + '/-</div>
http://jsfiddle.net/PpKpa/
Very Simple Question. Search before posting a question.
Any way, Use Child Selector / Children Method with HTML Method
If you use the change event, which fires when a checkbox or radio button changes from not checked to checked, you do not have to test for if :checked. You are sure if the change event triggered, then the element is checked.
$(function() {
$(document).on("change", ".checkboxclas", function (e) {
//if($(this).is(':checked'))
//{ no need for this if
//YOUR CODE HERE
//}
});
});

JQuery UnBind Works, Attempt to "re" bind does not

I'm working my way through a JQuery Solution and for the most part it works but I"m stumped on seemingly a small detail I know I'm overlooking. Heck, maybe my implementation/approach needs to be reconsidered.
Here's the flow of what works.
1. Click an anchor that adds to a table.
2. Add CSS Class.
3. Disable (Unbind) click on after preappend().
4. From the table of dynamically added record remove table based on ID.
5. delete class that was added in step 2.
6. Bind 'click'
However, although I can bind the click and alert on it. The expected functionality does not allow me to step through the above process again.
The code in question:
HTML SAMPLE:
link that starts the process:
table that holds new records after click of link
<table id="carrier-table"><tbody></tbody></table>
JQUERY and Custom Javascript Function
<script type="text/javascript" id="removeCarrier">
function removeCarrierFromList(obj) {
var i = obj.parentNode.parentNode.rowIndex;
document.getElementById('carrier-table').deleteRow(i);
$('a#' + obj.id).removeClass('delete-carrier-company');
//alert(obj.id); //.hasClass('add-carrier-company').tostring() ); //
$('a#' + obj.id).bind('click', function() {
//alert('User clicked on ' + obj.id);
});
}
</script>
<script type="text/javascript" id="carrierListJS">
$(function() {
// Link
// This adds a carrier to a list
$('.add-carrier-company').click(
function() {
var target = $(this).attr("id");
alert(target);
$("#carrier-table").prepend("<tr id='carrierRow_" + target + "'>" +
"<td><a href='#' id='" + target + "' class='delete' onclick='removeCarrierFromList(this)'> </a></td>" +
"<td class='carrier-list-text'>" + target + " " + $("#name_" + target).val() + "</td>" +
"</tr>");
return false;
});
$('.add-carrier-company').click(
function() { $(this).addClass('delete-carrier-company').unbind('click'); }
);
});
</script>
There were a few issues I noticed with the code. For one thing, as #RussellUresti mentioned, you create two tags with the same ID. For another thing, if you're using ID's in a selector in jQuery, don't include the tag name, just use the id (ie. use $('#id') not $('a#id')) it will be faster (it won't break your code though).
I have created a jsfiddle to answer your question (though I rewrote most of it). :) I think it's what you're looking for.
Here's the code:
Test HTML
aa
bb
cc
10002
10003
<table id="carrier-table" style="border:1px solid #000"><tbody></tbody></table>
JavaScript
function addCarrier() {
var target = $(this).attr("id");
$("#carrier-table").prepend("<tr id='carrierRow_" + target + "'>" + "<td><a href='#' id='a" + target + "' class='delete'> </a></td>" + "<td class='carrier-list-text'>" + target + " " + $("#name_" + target).val() + "</td>" + "</tr>");
$('#a' + target).click(removeCarrierFromList);
$(this).addClass('delete-carrier-company').unbind('click');
return false;
}
function removeCarrierFromList() {
var $this = $(this);
var id = $this.attr('id').replace("a","");
$this.closest('tr').remove();
$('#' + id).removeClass('delete-carrier-company').click(addCarrier);
}
$(function() {
// Link
// This adds a carrier to a list
$('.add-carrier-company').click(addCarrier);
});

Categories

Resources