Attach event handlers to multiple textboxes (with similar patterned id)? - javascript

I have several textboxes that are generated dynamically based on some results I get from another source. I want to add some event handlers to these textboxes to catch any keypress, and ensure that anything entered is numeric.
I generate these textboxes based on the length of an array within a JSON response, like so:
for(i=0;i<data.routesout.length;i++)
{
content += '<label for="route' + i + '">' + data.routesout[i].name + '(%)</label>';
content += '<input type="text" name="route' + i + '" id="route' + i + '" value="' + data.routesout[i].percent>';
}
How can I attach a single event handler to all of these potential inputs?

You've tagged the question with jQuery, so I wonder why you're not using the library to build your content:
var content = [];
for (var i = 0; i < data.routesout.length; ++i) {
content.push($('<label/>', { 'for': 'route' + i, text: data.routesout[i].name }));
content.push($('<input/>', { change: yourEventHandler, type: 'text', name: 'route' + i, id: 'route' + i, value: date.routesout[i].percent, change: yourEventHandler }));
}
By doing it that way, you can bind the handler element by element as you construct them. (I used "change" as an example, but you could bind handlers for whatever event you want in the same way.)
At the end, you can append all the created elements however you want, or you could append them as you go instead of building an array.

You can use the starts with selector
$('input[id^="route"]').keyup(function(){...
Note that if you're creating these on the fly, you might need to attach the event using live:
$('input[id^="route"]').live('keyup', function(){...

What about this?
for(i=0;i<data.routesout.length;i++){
content += '<label for="route' + i + '">' + data.routesout[i].name + '(%)</label>';
content += '<input onkeypress="doSomething(this)" type="text" name="route' + i + '" id="route' + i + '" value="' + data.routesout[i].percent + '>';
}
function doSomething(element){
/* this function will be called when user presess key inside a textbox */
}

Related

Adding onclick event on dynamically created HTML caused an error: Uncaught SyntaxError: Unexpected identifier

I'm using ajax to get an results from code behind, when I Get those results I'm creating an a divs. And this works fine, adding a div dynamically.
Now I Want to add on each div onclick event which should raise some method when it's clicked, so here is my full code:
<script>
function onSelectGroup(Id) {
$.ajax({
method: "GET",
url: "Product/GetProductsByGroupId",
data: { groupId: Id }
})
.done(function (response) {
$(".products").html("");
for (var i = 0; i < response.length; i++) {
//I wrote onclick = "addProduct(response[i])" to generate for each div each onclick event
let item = '<div class="col-md-3"> <div class="Product-holder" onclick="addProduct(' + response[i] + ')" id=' + response[i].ProductId + '><img class="img-responsive" src="images/maxresdefault.jpg"><p class="product-title" style="color:white;margin-top:5px;text-align:center;"> ' + response[i].Title + '</p></div></div>';
//Trying to append it to my .product class because it's parent of this divs above
$(".products").append(item);
}})};
function addProduct(product) {
console.log(product.Title);
}
</script>
But when I click on any of my generated divs I get an following error:
Uncaught SyntaxError: Unexpected identifier
I'm looking for issue for 3h allready, and I'm really stucked here..
Any kind of help would be great.
Thanks
P.S
CODE BEHIND - C # METHOD:
public ActionResult GetProductsByGroupId(int groupId)
{
var products = ProductController.GetProductsByGroupId(groupId);
if(products)
{
List<Product> productlist = new List<Product>();
foreach (var item in products)
{
Product product = new Product();
product.ProductId = Convert.ToInt32(item.Id);
product.Price = Convert.ToDecimal(item.Price);
product.Title = item.Title;
productlist.Add(product);
}
return Json(productlist, JsonRequestBehavior.AllowGet);
}
return Json(products, JsonRequestBehavior.AllowGet);
}
Remove the onclick and use delegate, you are passing an object to a function which convert response[i] to text [Object object], use data-* attributes to hold data for each object and attach an event to the div with the class product, on click of the div we'll use $(this) to reference the current clicked div and access its data attributes.
$(".products").html("");
var response = [{ProductId:4, Title:"Doe", Price: 34.89}, {ProductId:6, Title:"Jane", Price: 20.99}];
for (var i = 0; i < response.length; i++) {
//I wrote onclick = "addProduct(response[i])" to generate for each div each onclick event
let item = '<div class="col-md-3"> <div class="Product-holder product" data-price="'+ response[i].Price +'" data-title="' + response[i].Title + '" id=' + response[i].ProductId + '><img class="img-responsive" src="images/maxresdefault.jpg"><p class="product-title" style="color:white;margin-top:5px;text-align:center;"> ' + response[i].Title + '</p></div></div>';
//Trying to append it to my .product class because it's parent of this divs above
$(".products").append(item);
//console.log(item);
};
$(document).on('click', '.product', function(){
var product = {Title: $(this).data('title'), ProductId: $(this).attr('id'), Price: $(this).data('price')};
console.log(product);
// here use ajax to add this product
});
body {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="products"></div>
Take a look at the Delegate jquery method!
Description: Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.
So you basically need to bind the onClick event to the parent div, and pass a selector that will appear later on the child divs.
<script>
function onSelectGroup(Id) {
$.ajax(
//Do your ajax call here
).done(function (response) {
for (var i = 0; i < response.length; i++) {
let item = '<div class="event-target"></div>'
$(".products").append(item);
}})};
// Here's where the magic happens.
// We bind the event to the elements that have the 'event-target' class
//inside the element that have the 'products' class.
$('.products').on('click', '.event-target', function(){
console.log(this);
})
</script>
Warning: take care using delegate, if you use the wrong selector you can end up triggering the event for each element on the page, or even recursivelly (belive me, have made it a lot...)
Use data attributes to store any data & on click retrieve the data attribute.The code is not tested but hopefully it will work
let item = '<div class="col-md-3">' +
' <div class="Product-holder" ' +
'onclick="addProduct(this)"' +
' data-title="'+response[i].Title+'"' +
' id=' + response[i].ProductId + '>' +
'<img class="img-responsive" src="images/maxresdefault.jpg">' +
'<p class="product-title" style="color:white;margin-top:5px;text-align:center;"> ' + response[i].Title + '</p>' +
'</div>' +
'</div>';
$(".products").append(item);
function addProduct(product) {
console.log($(product).data('title'));
}
Also you need to delegate the event since they are dynamically created element
$("body").on("click",".Product-holder",function(){
console.log($(product).data('title'));
})
In this case the inline event handler that is onclick function will be redundant
Let me going to explant your code.
for (var i = 0; i < response.length; i++) {
let item = '<div class="col-md-3"> <div class="Product-holder" onclick="addProduct(' + response[i] + ')" id=' + response[i].ProductId + '><img class="img-responsive" src="images/maxresdefault.jpg"><p class="product-title" style="color:white;margin-top:5px;text-align:center;"> ' + response[i].Title + '</p></div></div>';
$(".products").append(item);
}})};
On these line of code, I saw that you have added strings to a variable.
but more exception response[i].ProductId seem like response[i] was an object.
but in Javascript you can't add an object to String by + operator, it will be return "string [object] string". What is solution for that??
Convert your object to JSON String like {"id": 123, "name": "Product name"}, that will show in html code like this onclick='addProduct({"id": 123, "name": "Product name"})' remember that onclick = ' not "

Jquery Mobile dynamic created range change event not firing

I'm creating a Jquery Mobile range dynamic with this code:
$('<input data-type="' + elementType + '" id="' + name +' " min=' + value1 +' max=' + value2 + ' value="127" >').appendTo("fieldset");
Now I want to add a change event with this code:
$(".brightness").change(function() {
alert("changed");
});
I have no idea why it's not working, I tried to refresh the range after defining the event, I tried to bind the event to the range, nothing works. The function that contains the first code snippet, is getting called first, and the function that contains the second snipped is getting called second.
Does someone of you know what I'm doing wrong, or what I'm overlooking?
Two things you need to do
1. add css class brightness to your range input
$('<input class="brightness" data-type="' + elementType + '" id="' + name +' " min=' + value1 +' max=' + value2 + ' value="127" >').appendTo("fieldset");
Add event handler using on
$(document).on("change",".brightness",function() {
alert("changed");
});
EDIT - for id selector use # instead of .(dot) like below
$(document).on("change","#brightness",function() {
alert("changed");
});
Check jQuery Selector
Use on method for your dynamically created elements
$(".brightness").on('change',function() {
alert("changed");
});
I think you are giving id brightness and Calling Onchange Event by Class using dot(.).
if the name of the id is brightness then
you should use #
$("#brightness").on('change',function() {
alert("changed");
});
but if you want call onchange event by class only then you need to add class to your input and use dot(.)
$('<input class="brightness" data-type="' + elementType + '" id="' + name +' " min=' + value1 +' max=' + value2 + ' value="127" >').appendTo("fieldset");
$(".brightness").on('change',function() {
alert("changed");
});

Create a cloned div that works separately in the same page

I have a div in my page which contains a table with inputs (with ids), I have some conditions and functions on the inputs written in the Javascript code. What I'm trying to do is to make a button (add new) that clones exactly the same div in the page but with same conditions and functions on the new elements and the submit button to work for each separately.
I tried this :
$('#button-add').bind({
click: function()
{
$("#repeat").clone().appendTo("#add");
}
});
the problem is that I get the same appearance for the div but the functions are not working (because the inputs have the same id) and i cannot submit only that block (new div).
Is there a simpler way to achieve that?
Just in case if you ignore making clones.
The way of doing it using a dynamic id.
Say if appending div with different id for every element using random function in javascript.
$('#add-item').on('click', function (e) {
var num = Math.floor(Math.random() * 90000) + 10000;
var numtd = Math.floor(Math.random() * 50000) + 10000;
$('<tr id="trowdynamic_' + num + '">' +
'<td>' +
'<div class="input-group">' +
'<input type="hidden" id="selected_item_' + numtd + '" name="selected_name" />' +
'<input type="text" name="Inv_Itemsdetail" value="" class="Itemsdetail-typeahead_' + numtd + ' input-search" autocomplete="off" data-provide="typeahead" />' +
'<input type="hidden" id="Inv_Itemsdetail_' + numtd + '" class="auto-complete" name="Itemxx[]" />' +
'<span class="input-group-btn">' +
'<i class="fa fa-plus"></i>' +
'</span>' +
'</div>' +
'</td>' +'</tr>').appendTo('#yourcontainer_id');
});
Now using jQuery call for same id elements-
Now Note this way I have every element starting with same id name plus a random number.
$('input[id^="selected_item_"]')
Since you're going to duplicate the div, you should not use IDs, because their uniqueness would be compromised. But you can use css class names ($('.className')) or custom data attributes ($('[data-my-id=xxx]')) to address your inputs because they do not need to be unique.
Second, you need to clone your div so that the events attached to your inputs are cloned as well. Check out the jQuery doc for .clone([withDataAndEvents] [,deepWithDataAndEvents]) (http://api.jquery.com/clone/).
Since the new div is created in new space ie, in #add, select the new div as
#add #repeat
{
} // in css
in jquery use next or siblings or children etc to select the new div
For example
see the FIDDLE

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
//}
});
});

Javascript selected item value not pulling correctly

I'm doing a select box with a list of items(dynamically created from an XML created by a webservice), and I'm unable to pull the selected value correctly. Here is what is happening.
What I'm sending:
onchange="changeFunction(this.options[this.selectedIndex].value)"
What I'm receiving:
function (a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!=
I'm the only thing I'm using is some self built functions and jQuery.
Any help would be superb.
Edit: here is the change function. All it is intended to do is build a form populated with values for given selected item.
function changeFunction(selection) {
console.log(selection);
$('#right').empty();
var addNewFields = 'these will be the fields';
$('#right').append(addNewFields);
}
Here is the select in question:
<select class="userSelection" id="userSelection" size="10" style="width:150px;" onchange="changeFunction(this.options[this.selectedIndex].value)"></select>
This is literally all the code in the html part of it. It's being populated via ajax, and there are 2 divs, one for left, containing the select, and one for right, containing the content for the user.
Just for giggles, here is the code creating the options:
var optionTag = '<option value="' + $(this).find('optionID').text + '" >' + $(this).find('optionName').text() + '</option>';
$('#userSelection').append(optionTag);
var optionTag = '<option value="' + $(this).find('optionID').text + '" >' + $(this).find('optionName').text() + '</option>';
should be:
var optionTag = '<option value="' + $(this).find('optionID').text() + '" >' + $(this).find('optionName').text() + '</option>';
Notice that $(this).find('optionID').text should be $(this).find('optionID').text().
or even better, to avoid this soup:
var optionTag = $('<option/>', {
value: $(this).find('optionID').text(),
html: $(this).find('optionName').text()
});
When you set the event handler of a DOM object to a function it get passed an event object as it's argument.
selectBox.onchange = function(event) {
changeFn(this.options[this.selectedIndex].value);
};

Categories

Resources