I have two different IDs. One auto increment (using jquery) from an ID called id="H+currentRow+"(+currentRow+ is the current row). And another that does an ajax request to PHP that appends the form with an id="Z#"(# will be depending on the ID in the database).
Ive done this:
$(document).ready(function(){
$("input").change(function(){
var sum=0;
$("[id^=H]").each(function(){
sum=sum+(+parseInt(this.value));
});
var sum2=0;
$("[id^=Z]").each(function(){
sum2=sum2+(+parseInt(this.value));
});
var total = sum + sum2;
if(isNaN(total)) {
var total = 0;
}
$("#total").text(total);
});
});
But thats not working. It works for the first fields but it work for anything else thats being appended. Anyone know whats going on and why its not working?
when you bind an event direct to an element, new elements appended to page will not trigger the event. you have to bind a parent element where inputs are appended to.
Try this bind:
$('body').on('change', 'input', function () {
// your code remain the same here...
});
you can be more specifc than body, binding the event to parent elements of input.
Related
(simplified) Scenario: a remote MySql DB and an HTML page with 2 buttons: SHOW and SELECT. The SHOW loads a single record and displays the fields in a form.
Everything is ok on this side.
The SELECT was made with a new approach for me:
I pass a parameter to a PHP function to query the DB and create an html file with the resuls.
This file is a series of <UL><LI><a id="1"...data..</LI></UL> to be inserted within a DIV.
One of the <LI> contains a link that, when clicked, calls the SHOW function. The record identification is made by mean of the ID associated to the anchor.
This procedure works fine; I get the new HTML segment (that I can check on the remote web server).
It is inserted (???) inside my DIV and the content is correctly displayed on screen, but... it does not exist.
Clicking on the links does not activate the SHOW procedure (actually, an Alert with the calling ID is never shown).
Looking to the html page source from Mozilla it still shows the previous content, without the new added (or replaced) code.
This is the reason for this post's title: I see something that really is not there.
Possibly, I should have AJAX to 'refresh' its visibility of the DOM, but and do not understand how.
This is the piece of JQuery script that I use to get the new content:
$("#select").click(function() {
$.ajax({
url: "new_record_list.php",
cache: false,
success:
function(recNumber)
{
$("#selected").val(recNumber); //ok
$("#recordList").load("list.txt"); //'list.txt is created by new_record_list.php
alert($("#recordList").html()); //this is OK
}
});
});
Everything is ok, but where is the meat?
Most likely the listener you created did not attach to the new dom nodes.
You can fix this by attaching a listener to a parent element that exists at page creation or even the document like so:
$(document).on('click', '.show', function() {
//click event
});
Replace ".show" with the jquery selector for the links
Since I'm unable to comment on your new post due to rep:
Remove the click event handler inside the loadRecord function.
The click event was already bound at the top of your script. What happens is that you click, activate the load record function which binds a new click handler, triggering the action on all the clicks following it.
The load record should look like this instead:
function loadRecord(){
ind = $(this).attr("id");
$("#thisRecord").val(ind); //shows the clicked record
$.get("show_record.php",{id:ind}, function(gotString)
{
ptr=0; //used to fetch fields
pos=0;
lun = gotString.length;
if (lun==0) {
alert ("Empty string!");
return false;
};
// fetch received keys and values then fills the fields
while (ptr < lun) {
..... //not interesting here
}; //while
});
return false; //required!
};
Also, you should replace
$(document).on('click', '.compLink', function() {
loadRecord();
});
with
$(document).on('click', '.compLink', loadRecord);
And loadRecord will be passed the mouse event as an argument. $(this) will also refer to the link you clicked inside the loadrecord function.
Otherwise you need to pass the element clicked into that function.
One issue I can see straight away is the AJAX call, it should be along the lines of:
$( "#select" ).on( "click", function ()
{
$.ajax( {
url: "new_record_list.php?record=MY_RECORD_VALUE",
type: "GET",
success: function ( response )
{
$( "#selected" ).val( response );
$( "#recordList" ).html( function ()
{
$.ajax( {
url: "list.txt",
typ: "GET",
success: function ( response2 )
{
$( "#recordList" ).html( response2 );
}
} );
} );
alert( $( "#recordList" ).val() );
},
beforeSend: function()
{
$( "#recordlist" ).html( "Loading..." );
$( "#selected" ).val( "Loading..." );
}
} );
} );
This will give a better result from the $.ajax call that you have made.
The .load() method can be quite unreliable at times, hence why it is (IMO) better to make an ajax within an ajax, because that's what your doing with less control effectively.
Where you have done the function(recNumber) is kinda wrong I'm afraid, whats brought back from the AJAX call is the response, everything that would be shown should you be using it as an actual page, e.g. if you had:
<table>
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
</table>
<input id="id_valued" value="2" />
Then this whole thing would be returned, not just the id_valued input field.
I followed the hints from Erin plus some other suggestion found on this forum and now the program ALMOST works.
Actually it does, but when a new set of records is loaded, to update the display (that is to call the loadRecord function) it is necessary to click twice on a link, the very first time only. All next clicks reacts immediately.
I try to post the entire script, for you experts to see what I hardly did:
<script type="text/javascript">
$(document).ready(function()
{
$(document).foundation();
var $scrollbar = $("#scrollbar1"); //other stuff
$scrollbar.tinyscrollbar();
//Erin suggestion + my understanding
$(document).on('click', '.compLink', function() {
loadRecord();
});
/* =========== ADD Rows ============================== */
/* action called by hitting the "selectRow" button.
/* query the DB and get a list of rows (5 fields each)
/* that are then inserted into the '#recordList' DIV.
/* Each rows has format:
/* <UL><LI><A id="xxx" class="compLink" ...>item xxx</A></LI><LI>....</LI></UL>
*/
$("#selectRow").on( "click",function()
{
$.ajax(
{
url: "new_record_list.php",
type: "GET",
success: function(recNumber) //if ok, we get the number of records
{
$("#selectedRecords").val(recNumber); //show how many records we got
$("#recordList").load("newRecords.txt"); //loads the remote text file into the DIV
}
});
});
/* ====================================================== */
/* =========== LOAD Record ============================== */
/* loads and displays an entire record from DB,
/* based on the ID of clicked link with class="compLink"
/* in '#recordList' DIV.
/* Example: <a id="1" class="compLink" ...>
*/
function loadRecord(){
$(".compLink").click(function(event)
{
ind = $(this).attr("id");
$("#thisRecord").val(ind); //shows the clicked record
$.get("show_record.php",{id:ind}, function(gotString)
{
ptr=0; //used to fetch fields
pos=0;
lun = gotString.length;
if (lun==0) {
alert ("Empty string!");
return false;
};
// fetch received keys and values then fills the fields
while (ptr < lun) {
..... //not interesting here
}; //while
});
return false; //required!
});
};
/* ====================================================== */
return false;
});
</script>
I hope this is clear enough. Thanks
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 9 years ago.
I have a working jQuery function that creates a div when another div is clicked.
When this div is clicked...
<div class='col_1' data-parent_id='parent' data-child_id='1002'>List 1</div>
this div is created using the function below and some php.
<div class='col_2' data-parent_id='1002' data-child_id='1003'>List 2</div>
jQuery
$(function() {
$('.col_1').click(function(){
var parent_id = $(this).data("parent_id");
var child_id = $(this).data("child_id");
$.post("array-2.php",{parent_id: parent_id, child_id: child_id},
function(data){
$('#column_2').empty();
$('#column_2').append(data);
});
});
});
$(function() { //// New part:Trys to make the created div functional,
$('.col_2').click(function(){
var parent_id = $(this).data("parent_id");
var child_id = $(this).data("child_id");
$.post("array-2.php",{parent_id: parent_id, child_id: child_id},
function(data){
$('#column_3').empty();
$('#column_3').append(data);
});
});
});
I want the new div to function identically as the first div to make a 3rd div/list as well (and even more created columns of lists). So I added the second half of the jQuery but it doesn't seem to function. Does anyone have any ideas why this won't work, or how I could make it better? Thanks.
You can see basically what I'm trying to do here. actual project
Since the col_2 elements are created dynamically you need to use event delegation to register event handlers to these elements.
When you use $('.col_2').click(....); to register an event handler it will register the handle to only those elements which are already present in the dom at the time of the code execution, in you case since these elements are created after that the handlers will not get attached to the newly created elements
$(function () { //// New part:Trys to make the created div functional,
$('#column_2').on('click', '.col_2', function () {
var parent_id = $(this).data("parent_id");
var child_id = $(this).data("child_id");
$.post("array-2.php", {
parent_id: parent_id,
child_id: child_id
},
function (data) {
$('#column_3').empty();
$('#column_3').append(data);
});
});
});
Instead of using $('.col_2').click(function(){..});
Try $(document).on("click",".col_2",function(){..});
Because you are trying to bind click event to an element, even when it is not present in the DOM.
Try to use this
$(document).on("click",".col_2",function(){
..............
});
rather than
$('.col_2').click(function(){
..............
});
Check this jsfiddle
I'm hoping someone can point me in the right direction. I'm primarily a PHP developer but I'm really trying to get my head around jquery and javascript more due to the increasing number of AJAX work requests we receive.
Basically I have a sidebar filter that works fine. It is based on 3 things. A group, category and sub category. So for example, Boots as the category, Leather (type) as a sub category and Black (colour) as tertiary filter. At the moment it works based on a GET form. However I want to use live filters instead so as they click a checkbox, it updates the results based on a query. I can write all the PHP for this but I'm struggling to get the data together by jQuery. I've looked at using jQuery .each and .change.
There are 3 groups of checkboxes and they are all based on arrays. So for example again: category[], subcategory[], tertiary[].
Thanks in advance for the help.
Some example HTML
<input id="$ProdCatLabel" class="side_filter_checkbox" name="ProdCatFil[]" type="checkbox" value="$ProdCat">
<input id="$ProdSubCatLabel" class="side_filter_checkbox" name="ProdSubCatFil[]" type="checkbox" value="$ProdSubCat">
<input id="$BrandingLabel" class="side_filter_checkbox" name="BrandFil[]" type="checkbox" value="$Branding">
My attempts:
var prodcats = $('side_filter_prodcats[name="ProdCatFil[]"]:checked')
.map(function() { return $(this).val() })
.get()
.join(",");
var prodsubcats = $('side_filter_prodsubcats[name="ProdSubCatFil[]"]:checked')
.map(function() { return $(this).val() })
.get()
.join(",");
$.ajax({
type: "POST",
url: "[ENTER PHP URL HERE]",
data: "ProdCats=" + prodcats + "ProdSubCats=" + prodsubcats,
success: function(msg) { $(".content_area").html(msg); }
});
Am I barking up the right tree here?
Ok let's say your checkboxes have the classes category, subcategory and tertiary. You could attach a click event handler to each group that calls the function to load in the correct data, passing the checkbox value and a class or data-attribute to the function as parameters.
// Your main DOM ready function
$(document).ready(function() {
// Checkboxes click function
$('input[type="checkbox"]').on('click',function(){
// Here we check which boxes in the same group have been selected
// Get the current group from the class
var group = $(this).attr("class");
var checked = [];
// Loop through the checked checkboxes in the same group
// and add their values to an array
$('input[type="checkbox"].' + group + ':checked').each(function(){
checked.push($(this).val());
});
refreshData(checked, group);
});
function refreshData($values, $group){
// Your $values variable is the array of checkbox values
// ie. "boot", "shoe" etc
// Your $group variable is the checkbox group
// ie. "category" or "subcategory" etc.
// Now we can perform an ajax call to post these variable to your php
// script and display the returned data
$.post("/path/to/data.php", { cats: $values, type: $group }, function(data){
// Maybe output the returned data to a div
$('div#result').html(data);
});
}
});
Here's an example of the checkbox click function in action: http://jsfiddle.net/F29Mv/1/
I have a multiselect drop down, on selecting multiple items from it, i need to pass the value of this multiselect into an ajax file, and create divisions dynamically and load the data retreived from the ajax files into these dynamic divisions.
var itemvalues= [];
$('#MultiSelectItemID :selected').each(function(i, selected) {
itemvalues[i] = $(selected).val();
});
$('#itemContent').html(LoadHTML);
$('#itemDetailsContainer').fadeIn('',function(){
$('#itemContent').load('ajax_calls/item_details.php?ItemID='+$('select[name=MultiSelectItemID]').val() || [],
function(){
$(this).show('highlight');
}); });
Now , i want to loop through each value in the itemvalues[] array and pass it to my php file and get the data and load it into a new division.
Please help.
Will this do the job? (Note I 've changed "MultiSelectItemID" to simply "ItemID" and serialize()d it.)
http://jsfiddle.net/svzsY/8/
var itemvalues = [];
$('#itemContent').html(LoadHTML);
$('#itemDetailsContainer').fadeIn('', function() {
$('#itemContent').load('ajax_calls/item_details.php', ($('select[name=ItemID]').serialize() || []), function() {
$(this).show('highlight');
});
});
I have a problem with the jQuery's live() function.
I'm creating the shopping basket with PHP and make a json call to the php script to add specific item to the basket. Rather than re-binding the click to the button ( tag) I've decided to use live(), however it doesn't seem to like it.
Here's my call:
if ($('.add_to_basket').length > 0) {
$('.add_to_basket').live('click', function() {
var button = $(this);
var id = $(this).attr("rel");
$.getJSON("/basket/action/add/id/" + id, function(data) {
if (!data.error) {
$('.basket_no_of_items').text(data.no_of_items);
$('.basket_items_total').text(data.total);
button.text('Remove from the basket');
}
});
return false;
});
}
Any idea what I might be doing wrong?
I've checked with firebug and it seem to post the request to only /basket/action/add - without id bit.
The whole idea of using live() is to register a function on the occurrence of an event (eg. click) on a set of elements whether they exist or not at the time of creation of the function.
Adding ($('.add_to_basket').length > 0) will check whether this particular set of elements exist or not. This is counter productive as per my description above. So, either:
Remove ($('.add_to_basket').length > 0) and this should work for all .add_to_basket elements
Change $('.add_to_basket').live('click', function() {...}); to $('.add_to_basket').click(function() {...}); and wrap it around with a $(document).ready() to ensure that all DOM elements have loaded when the function is registered to the click.
Hope this makes sense.
Sumit
Try removing the "length" check, I bet it's interfering with the .live() function.
change $.getJSON("/basket/action/add/id/" + id, function(data) {})
to $.getJSON("/basket/action/add/id/" ,{ pid : id}, function(data) {})