How to concat html object to html string using jquery? - javascript

I have created a loop and below is the part of the code between that loop
--- Loop Starts ---
var aElement = $('<a>');
aElement.attr('href', '#');
aElement.text(title);
aElement.click(function() {
alert("Hello World);
});
video_list_html += '<tr>' +
'<th scope="row">' + count + '</th>' +
'<td>' + aElement + '</td>' +
'</tr>';
--- Loop Starts ---
But as aElement is an object, it doesn't attach as html tag to the video_list_html but it attaches like this
[object Object]
How do I fix this, so that it attaches inside the video_list_html and also the .click() event stay working.

Try using aElement[0].outerHTML instead of aElement. Leave click handler as is.

The issue is because you cannot append an object to a string. The object gets coerced, ans the result is, as you've seen, [Object object].
A better solution to this problem would be to append the new HTML as one entire string, then use a delegated event handler to catch the events from those dynamically added elements. Try this:
var data = [{
videoId: 'abc123',
title: 'Video #1'
}, {
videoId: 'xyz987',
title: 'Video #2'
}]
var video_list_html = data.map(function(o, i) {
return '<tr><th scope="row">' + i + '</th><td>' + o.title + '</td></tr>';
}).join('');
$('#yourTable').append(video_list_html).on('click', 'a', function(e) {
e.preventDefault();
console.log($(this).data('videoid'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="yourTable"></table>

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 "

Dynamically generate table using Jquery

I use JQuery version 1.8.4 and jquery-ui-1.9.2
I have this array:
window.mapData.Layers = [{id:1,Title:water}{id:2,Title:land}{id:4,Title:data}{id:1,Title:info}]
I try to create table with some text and two buttons.
Each row in table have to display title the property of object from Layers array
and two buttons edit and delete.Each button have to sent as parameter the id of the property to handler when it clicked.
Here is the code:
(function () {
var content = $('<table>')
$(window.mapData.Layers).each(function (i, j) {
content += '<tr><td>' + j.Title + '</td><td>' + $('<button/>')
.text('Edit').onClick('eventHandler').params('j.id') +'</td>'+'<td>'+$('<button/>').text('Delete').onClick('eventHandler').params('j.id')+'</td>'+'</td></tr>'})
$('#vectorLayerslist').append(content);
}())
Here is result that I get:
water [object Object] [object Object]
land [object Object] [object Object]
data [object Object] [object Object]
info [object Object] [object Object]
But it's not works.As you can see above it's generate only text but not buttons.
Any idea why buttons not generated? If there is any more elegant way to achieve my task?
Build the table as string, then append the string once.
Make use of jQuery's event propagation for dynamically created elements.
var Layers = [{id:1,Title:'water'},{id:2,Title:'land'},{id:4,Title:'data'},{id:5,Title:'info'}];
var vectorLayersList = $('#vectorLayerslist');
// build the table
var content = '<table>';
content += '<thead><tr>';
content += '<th>Title</th>';
content += '<th colspan="2">Actions</th>';
content += '</tr></thead><tbody>';
$.each(Layers, function () {
// we'll store the ID in HTML5 data-attribute for later
content += '<tr data-id="' + this.id + '">';
content += '<td>' + this.Title + '</td>';
// give classes to your buttons for later
content += '<td><button type="button" class="edit">Edit</button></td>';
content += '<td><button type="button" class="delete">Delete</button></td>';
content += '</tr>';
});
content += '</tbody></table>';
// append the table once
vectorLayersList.append(content);
// attach event handlers
vectorLayersList.on('click', '.edit', function () {
var id = $(this).closest('tr').data('id');
console.log('editing ' + id);
});
vectorLayersList.on('click', '.delete', function () {
var id = $(this).closest('tr').data('id');
console.log('deleting ' + id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="vectorLayerslist"></div>

how to refresh the list in jquery javascript

Hi i m having one page with one textbox named search and one search button. When i'm searching anything for the first time it's showing me the right data but when i'm searching some other things for the next time then the elements which was listed before are also appended below of that new list. Suppose i'm searching state name by k it will give me right list of karnataka, kerala. But if i start to search again by g, it will show me in output as goa,gujrat,karnataka kerala. i tried using refresh option but it still not working. This is my js code
$.each(response.state, function (i, state) {
$('#statelist').append(
'<li>' +
'<a href="#">'
+
+'<b>'+ '<font color="green">'+'<h3>'+ state.Name +'</h3>'+'</font>' +'</b>'+
'</a>' +
'</li>'
);
});
$('li img').width(100);
$('.ui-li-icon li').click(function() {
var index = $(this).index();
text = $(this).text();
// alert('Index is: ' + index + ' and text is ' + text);
});
$("#statelist").listview("refresh");
and this is html
You are using .append() function. It appends whatever you append to the end of the list.
Check this link:
http://api.jquery.com/append/
Try using innerHTML property of the DOM model.
You could add
If(!('#statelist').html() == ""){
$(this).remove();
//execute rest of code that appends state list
}
Then do an else statement and execute your append code without removing()
UPDATE: a better option is to do this-
$.each(response.state, function (i, state) {
$('#statelist').html(
'<li>' +
'<a href="#">'
+
+'<b>'+ '<font color="green">'+'<h3>'+ state.Name +'</h3>'+'</font>' +'</b>'+
'</a>' +
'</li>'
);
});
$('li img').width(100);
$('.ui-li-icon li').click(function() {
var index = $(this).index();
text = $(this).text();
// alert('Index is: ' + index + ' and text is ' + text);
});

Jquery reading input field that was created from JSON loop

I cannot figure out for the life of me why this will not work. I am trying to pull the value of a textfield that was created with a loop from a json file.
In this code, at the very bottom I just do a simple click(function() {alert()} just to see if I can pull a value and its returning undefined. But if I remove '#name' and put in 'input' it captures it, but only for the first of several input fields.
Any help is really appreciated
JSON
{
"Controls": [{
"Button":[{ "Name":"Button", "x": "1","y": "2","width": "3","height": "4","Transition":"" }],
"Image":[{"x": "5","y": "6","width": "7","height": "8"}],
"TextField":[{"x": "9","y": "10","width": "11","height": "12","Rows":""}]
}]
}
The Code(there is soome getJSON stuff above this)
//Slide In Attributes Panel Based on Selected Object
$(document).on('click', '#code li', function () {
var index = $('#code li').index(this);
var selected = $(this).text();
switch (selected) {
case selected:
$('#options').hide();
hidePanels();
$('#temp').remove();
$('#objectAttributes').show("slide", 200);
break;
//If it does work show what variable is being used
default:
alert(selected);
break;
}
//Shows Selected LI Index
$('#codeIndex').text("That was div index #" + index);
//Pull list of Attributes for selected Object
$.getJSON('controls.json', function (data) {
//Build Attributes List
var attributeList = '<div id="temp">';
//Target based on selected object
var target = selected;
attributeList += '<div>' + target + '<div>';
$.each(data.Controls[0][target][0], function (kk, vv) {
attributeList += '<div style="float:right">' + kk + ':' + '<input type="text" id='+ kk + '>' + '</input>' + '</div>';
});
attributeList += '</div></div>';
attributeList += '</div>';
$('#objectAttributes').append(attributeList);
$('#temp').append('<div id="editIndex">'+"Modifying index" + " " +index+'</div>');
$(document).on('click', '#saveAttributes', function () {
var $x = $('#name').val();
alert($x);
})
});
});
Ok, so after a little hacking around with a jsfiddle the answer turned out to be a lot simpler than I first thought. Ever since HTML 4.01 class names and IDs have been case sensitive (reference), which means that your selector $('#name') wasn't matching the JSON Name.
So a simple change, such as in this simplified jsfiddle seems to work as desired. Hopefully this helps!

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

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 */
}

Categories

Resources