I have some jQuery script in which I'm adding some rows to a table (when the user press a button). My problem is that I want to change the id of the elements inside the rows dynamically. I have set a global variable i which I set as an id to some elements inside my table. The problem is that after some debugging I found out that the id doesn't change at all and stays as the letter i (and not the variable i set to 0 and increase every time the user press the button). Any ideas?
var i=0;
var a1=i.toString().concat("1");
var a2=i.toString().concat("2");
var a3=i.toString().concat("3");
$("#table1").append("<tr><td><center><input id=\"a1\"></input></center></td><td>
center><button id=\"a2\">Load</button></center></td><td ><img id=\"a3\"></td>
</tr>");
$("#a2").click(function(){
$z=$("#a1").val();
$("#a3").attr("src",$z);
i++;
});
That's because you're writing those directly as strings. You need to concatenate them into the actual string. You can concatenate strings together using +.
$("#table1").append(
"<tr>" +
"<td>" +
"<center><input id=\"" + a1 + "\" /></center>" +
"</td>" +
"<td>" +
"<center><input id=\"" + a2 + "\" /></center>" +
"</td>" +
"<td>" +
"<center><input id=\"" + a3 + "\" /></center>" +
"</td>" +
"</tr>"
);
For what it's worth, the <center> tag is deprecated and should not be used. You may also consider creating some kind of template rather than generating your HTML as strings directly inside of JavaScript.
Related
I am using simple JavaScript code to submit a form and storing the form data into an array in the form of objects and later showing the data on click of a button. I also have provided two buttons -'EDIT' and 'DELETE' for each elements while showing the data in tabular form under 'Action' header.
I can pass the corresponding ids to those methods to perform edit and delete operation on specific entries/object and based on that I want to keep data in final array and want to show them after the operation.
However I have done the 'delete' functionality but I could not get any lead to implement the 'EDIT' button functionality.
I want to know- is it possible to prepopulate the form with data available and make the changes and again save it back when I click on edit button?
Note: I am not using any database connection for this. Here in the below code I am storing the objects in dataArray
sample form object- I am storing dataArray after submit:
0: CreateUser
description: "I am Web developer"
email: "test#gmail.com"
english: "english"
gender: "Male"
hindi: "hindi"
id: "12312"
name: "test"
othersLang: "others"
role: "dev"
Please have a look at it ---
function getEmployeeDetails() {
let totalLength = userArray.length;
if (totalLength === 0) {
alert("No user Data Found");
return;
}
let tbody = document.getElementById("tbody");
tbody.innerHTML = "";
for (let i = 0; i < userArray.length; i++) {
let tr = `<tr id=` + userArray[i].id + `>`;
tr +=
"<td class='table-data'/td>" +
userArray[i].id +
"</td>" +
"<td class='table-data'/td>" +
userArray[i].name +
"</td>" +
"<td class='table-data'/td>" +
userArray[i].email +
"</td>" +
"<td class='table-data'/td>" +
userArray[i].gender +
"</td>" +
"<td class='table-data'/td>" +
userArray[i].role +
"</td>" +
"<td class='table-data'/td>" +
userArray[i].english +
userArray[i].hindi +
userArray[i].othersLang +
"</td>" +
"<td class='table-data'/td>" +
userArray[i].description +
"</td>" +
`<td class="table-data">
<button onclick="deleteUser(` +
userArray[i].id +
`)">Delete</button> || <button onclick="editUser( ` +
userArray[i].id +
`)">Edit</button>
</td>`;
tbody.innerHTML += tr;
}
}
function deleteUser(id) {
console.log('ID',id);
userArray = userArray.filter(x => x.id === id);
console.log("aftre", userArray);
let elem = document.getElementById(id);
elem.remove();
return userArray;
}
function editUser(id) {
console.log("edit", id);//prints corresponding id
}
I am not sure if this can be achieved or not.
Any suggestion on this is highly appreciated.
I'm not sure I understand what you're trying to achieve, but if you're trying to prepopulate your page without the use of any database, you could use a file with some json data in it.
see JavaScript: Create and save file
Or you could pretty much hardcode it into your page on an on-load event.
On a side note, if you know you're not going to work with Internet Explorer you could use the find() function instead of the filter(), as find() will stop its iteration on the array once it finds the FIRST occurrence of whatever you passed in its function, and filter() will just keep going.
Seeing as you're trying to get data using a unique ID, it might be better to use it instead :)
see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
I have a document that uses the jscolor.com library, for the user to be able to select and store a color. I'm also using a JQuery function to add rows to the screen, so the user can create and define a number of colors. The problem is, when the new row is added, the Javascript isn't re-initialized for the added elements.
Here is the code in question:
<script type="text/javascript">
$(document).ready(function(){
var i=1;
$("#add_row").click(function(){
$('#addr'+i).html("<div id='addr" + i + "'>" +
"<div class='col-xs-4'>" +
"<input type='text' name='config_color[" + i + "][css]' id='input-color[" + i + "][css]' class='form-control' />" +
"</div>" +
"<div class='col-xs-2'>" +
"<input type='text' name='config_color[" + i + "][value]' id='input-color[" + i + "][value]' class='form-control jscolor' />" +
"</div>" +
"<div class='col-xs-2'>" +
"<input type='text' name='config_color[" + i + "][default]' id='input-color[" + i + "][default]' class='form-control' />" +
"</div>" +
"<div class='col-xs-4'>" +
"<input type='text' name='config_color[" + i + "][notes]' id='input-color[" + i + "][notes]' class='form-control' />" +
"</div>" +
"</div>");
$('#tab_logic').append('<div id="addr'+(i+1)+'"></div>');
i++;
});
$("#delete_row").click(function(){
if(i>1){
$("#addr"+(i-1)).html('');
i--;
}
});
}).trigger('change');
</script>
I've made an simplified example of what I'm talking about on JSFiddle - you can see in the first row, if you click in the color cell, it gives you a pop up color palette.
If you add additional rows, the popup picker doesn't work.
However, all of the data stores in the database properly, so i have an instance where some elements added by Javascript work properly and others don't?
(Also full disclosure, I asked on Reddit first - this is therefore a cross-post.
In their examples, jscolor has one called "Instantiating new Color Pickers" which shows you how to do it.
You're adding the new row as a string, which I wouldn't recommend, because if you created each input separately using jQuery it would be easier to call jscolor() on only one element, but this works too.
Just add the following to your click handler:
// Get all the inputs first
var allInputs = $('.jscolor');
// From there, get the newest one
var newestInput = allInputs[allInputs.length - 1];
// And call jscolor() on it!
new jscolor(newestInput);
Here's an updated fiddle
Generally Abe Fehr answer helped me too, but i had slightly other problem. My elements already had default values from database so
new jscolor(newestInput);
initialized them but with default FFFFF
So in my case twig (html) looks like this:
<button class="jscolor {value:'{{ category.color }}'} btn btn-sm disabled color-picker" data-color="{{ category.color }}"></button>
And then I reinitialize all the colors like this:
let all_pickers = $('.color-picker');
if ($(all_pickers).length !== 0) {
$(all_pickers).each((index, element) => {
let color = $(element).attr('data-color');
new jscolor(element, {'value': color});
});
}
I have a Html Table which displays data and is having delete and update functionality as below,
function DesignBTable(data) {
$("#ExpTableBody tr").remove();
var rowIndex = 0;
$.each(data, function (index, value) {
var fromDt = moment(value.from_date).format("MMM/YYYY");
var toDt = moment(value.to_date).format("MMM/YYYY");
$("#ExpTableBody").append("<tr>" +
"<td>" + value.org_name + "</td>" +
"<td>" + fromDt + "</td>" +
"<td>" + toDt + "</td>" +
"<td>" + value.designation + "</td>" +
"<td>" + value.location + "</td>" +
"<td>" + value.is_relevant + "</td>" +
"<td>" + '<input type="button" value = "X" class="btn btn-danger btn-sm" onClick="Javacsript:deleteRow(\'' + value.exp_id + '\',\'' + value.from_date + '\')">' + ' ' +
'<input type="button" value = "E" class="btn btn-info btn-sm" onClick="Javacsript:editRow(\'' + value + '\')">' + "</td>" +
"</tr>");
//alert(moment(value.from_date).format("MM/YYYY"));
rowIndex++;
});
};
The value object contains various fields.
On the Click event of the delete button I send value.exp_id and value.from_date as parameter to deleteRow function.
I want to add Edit functionality where if I click on the edit button it should send the value as object so that I can access all the fields in it.
When I try to send value as parameter to the JS function it errors out as undefined.
To create a string for code that uses the object, you would need to create a string representation of the object:
... onClick="editRow(' + JSON.stringify(value) + ')" ...
(Note: The JSON object is not supported in some older browsers.)
If you create elements directly instead of creating a string that you create elements from, you can bind the event directly and use the object without creating a string representation of it:
$("#ExpTableBody").append(
$("<tr>").append([
$("<td>").text(value.org_name),
$("<td>").text(fromDt),
$("<td>").text(toDt),
$("<td>").text(value.designation),
$("<td>").text(value.location),
$("<td>").text(value.is_relevant),
$("<td>").append([
$("<input>", { type: "button", value: "X", className: "btn btn-danger btn-sm" }).click(function(){
deleteRow(value.exp_id, value.from_date)
}),
$("<input>", { type: "button", value: "E", className: "btn btn-info btn-sm" }).click(function(){
editRow(value);
})
])
])
);
As a side effect, by using the text method to put the values in the cells, it's protected agains script injection. If you actually have HTML code that you want to put in a cell, you would use the html method instead. That naturally means that you should encode it properly when you create that HTML code to protect against script injection.
Side note: The javascript: pseudo protocol is only used when you put code in an URL, i.e. a href attribute. If you use it anywhere else it becomes a label instead. This is not harmful, but useless and confusing.
the problem of 'value' accessibility is it's defined only inside the function not outside.
I see you use JQuery, so you can use JQuery.data to make a link between an html object and a custom value. In your case you can add the value directly to the button at the end of the row.
This question already has answers here:
Adding onClick event dynamically using jQuery
(7 answers)
Closed 8 years ago.
I want to fetch the json data from serve and then loop the rows of table. the html code is like:
<table id="topics_list_table">
<thead>
<tr><th>Topic Title</th>
<th>Author Name</th>
<th>Likes</th>
<th>Created Time</th>
<th>Actions</th>
</tr></thead>
<tbody>
</tbody>
</table>
the jQuery part:
$.ajax({
url: some url here,
type:'GET',
success:function(res){
$.each(res, function(index, value){
$('#topics_list_table > tbody:last').
append(
"<tr>" +
"<td>" + value.title + "</td>"+
"<td>" + value.author_name + "</td>"+
"<td>" + value.likes + "</td>"+
"<td>" + value.created + "</td>"+
"<td>" +
"<a href='/components/topics/" + value.id + "' class='mini ui black buttons' id='detail_check'>check</a>"+
"</td>"+
"</tr>"
);
});
}
});
I could get all the data from the remote side, but the key question is this part
<a href='/components/topics/" + value.id + "' class='mini ui black buttons' onclick='somefunction()'>check</a>
I inspect this page and found, sth like
<a href="/components/topics/53cf67fad0c0f7fdda3ef8d5" class="mini ui black buttons" onclick='somefunction()'>check</a>
already exists in the dom.
but
1, the style class="mini ui black buttons" can not be applied.
2, when you try to click the "check" and want to trigger the somefunction(). it doesnt work.
so, why couldn't i get the dom element after appending the rows? OR, is there any other better way to loop rows after fetching the data?
thx
onclick attributes only work in the initial HTML, not in appended elements. See this question.
Instead, add the event handler using .click() or .on('click'):
success:function(res){
$.each(res, function(index, value){
var $row = $("<tr>" +
"<td>" + value.title + "</td>"+
"<td>" + value.author_name + "</td>"+
"<td>" + value.likes + "</td>"+
"<td>" + value.created + "</td>"+
"<td>" +
"<a href='/components/topics/" + value.id + "' class='mini ui black buttons' id='detail_check'>check</a>"+
"</td>"+
"</tr>");
$row.find('.mini.ui.black.buttons').on('click',somefunction);
$('#topics_list_table > tbody:last').
append($row);
});
}
Or, if it's the same function for every such link, just add it using event delegation:
$('#topics_list_table').on('click', '.mini.ui.black.buttons', somefunction);
In javascript I am creating a li element as per below which contains only the problem I am seeing.
The data-videoUrl is showing the full url, so all good there.
The issue is the entry.link and entry.title, while debugging, I verified the strings are within quotes. i.e. "This is a pod cast." The data-videoTitle and data-videoDesciption are being truncated though. i.e. "This" will show from the previous example.
I'm not sure what is occuring in the latter two data assignments as I've verified the text is not double quoted etc. What is occuring with the html5 data elements? I can provide a more complete example if needed.
var podItem = document.createElement("li");
podItem.innerHTML = entry.title
+ "<a data-videoUrl=" + entry.link + " "
+ "data-videoTitle=" + entry.title + " "
+ "data-videoDescription=" + entry.contentSnippet + " "
+ "</a>";
document.getElementById("podCastList").innerHTML += podItem.innerHTML;
Here is a the html being generated.
<a data-videourl="http://rss.cnn.com/~r/services/podcasting/studentnews/rss/~3/d3y4Nh_yiZQ/orig-sn-060614.cnn.m4v" data-videotitle="CNN" student="" news="" -="" june="" 6,="" 2014="" data-videodescription="For" our="" last="" show="" of="" the="" 2013-2014="" school="" year,="" cnn="" takes="" a="" look="" back,="" ahead,="" and="" at="" stories="" making="" ...="" <=""></a>
I'm sure there's something I'm not fully understanding. Why would the first data element get the text correctly, and the next two data elements break up the text as in: [data-videotitle="CNN" student="" news=""]. The text is a straight forward sentence quoted i.e. "CNN student news..."
Why would videoUrl work correctly and the other two not?
You need to add some quotes around the attributes...
podItem.innerHTML = entry.title
+ "<a data-videoUrl=\"" + entry.link + "\" "
+ "data-videoTitle=\"" + entry.title + "\" "
+ "data-videoDescription=\"" + entry.contentSnippet + "\" "
+ "</a>";
You'll also want to make sure you escape any quotes that are inside the attributes as well.