I'm having a bit of trouble figuring out how to go about self-referencing a table row in Javascript.
Here's the boiled down code:
$( "#listitems tbody" ).append( "<tr onclick=\"editListItem(this)\">" +
"<td>" + id.val() + "</td>" +
"<td>" + title.val() + "</td>" +
"<td>" + description.val() + "</td>" +
"<td>" + TF + "</td>" +
"<td style=\"visibility: hidden;\">" + id.val() + "</td>" +
"</tr>" );
As you can see, I'm setting the contents of this table row and cells dynamically. However, I need to pass a reference to this table row into its onClick function, which calls this Javascript method:
function editListItem(obj) {
var id = obj.cells[4].innerHTML;
var cells = document.getElementById('listitems').rows[id].cells;
DATA[0] = cells[0].innerHTML;
DATA[1] = cells[1].innerHTML;
DATA[2] = cells[2].innerHTML;
DATA[3] = cells[3].innerHTML;
}
In this method, I need to access the value contained inside the 4th "hidden" cell of the table row that was clicked. I normally would just pass the ID variable into the onClick method, but this table's contents can be sorted and rearranged, so the ID variable will not necessarily correspond to the contents of the row.
I've been Googling for the past four hours but can't find any specific examples for this situation; everything I've tried just triggers a Javascript error proclaiming that obj.cells, obj[4], obj.childNodes, etc, does not exist, depending on which one I'm trying.
Does anyone know how you can access the innerHTML of table cell elements inside a table row element by passing "this" into the table row's onClick?
Please let me know if any part of this was confusing, I'm trying to get this done before I leave today or I know I'll forget it all and have to start all over.
how about:
$( "#listitems tbody" ).append(
$('<tr>....</tr>')
.bind('click', function(){
var tds = $(this).find('td'),
id = tds.eq(4).text();
})
);
And if that's not what you meant, let me know. I'm not 100% sure I understand what you're asking for :)
From the looks of your code, your using jQuery so you can easily grab the 5th td by using
$(this).children('td').eq(4)
and then do whatever you want with that jQuery element
checkout jQuery eq selector for more info
Create your <tr> element on its own first, and use proper JS to register the handler rather than embedding the handler in the element's attributes:
var tr = $('<tr>').click(editListItem);
$("#listitems tbody").append(tr);
$(tr).append( ... );
In editListItem, this will automatically apply to the whole row element:
function editListItem(row) {
var cells = $(this).children('td');
var id = $cells.eq(4).text();
var data = [];
data[0] = cells.eq(0).html();
}
Related
I have a problem concerning multiple file uploads in javascript. I am trying to create my own multiple file upload by dynamically adding inputs. This is all easy as pie, but the problem is that whenever I add a new , my previous input-fields of the type "file" get reset.
If I remove the last lines of code where I alter the innerHTML of my parent div, the values of my do not get reset. Does anyone know how this problem can be solved? The javascript code can be found below. Thanks in advance.
if(document.getElementById("upload_queue").innerHTML.indexOf(_item) == -1)
{
var _row = "<tr id='queue_row_" + items_in_queue + "'>";
_row += "<td>";
_row += "<div class='remove_uploaded_image' onclick='remove_from_queue(" + items_in_queue + ")'></div>";
_row += "</td>";
_row += "<td>";
_row += _item;
_row += "</td>";
_row += "</tr>";
document.getElementById("upload_queue").innerHTML += _row;
document.getElementById("upload_image_" + items_in_queue).style.display = "none";
items_in_queue++;
document.getElementById("uploader_holder").innerHTML +=
'<input id="upload_image_' + items_in_queue +
'" name="upload_image_' + items_in_queue + '" accept="image/jpeg" type="file"' +
'onchange="add_to_upload_queue()" style="display: inline;" />';
}
Yeah... you're going to want to use appendChild instead of modifying the inner HTML:
var myInput = document.createElement("INPUT");
// do stuff to my input
var myContainer = document.getElementById("uploader_holder");
myContainer.appendChild(myInput);
That's the general gist of what you have to do - let me know if you need somethign more specific, but it looks like you've got a good hold on JS already... You're going to want to do that in almost all cases rather than setting inner HTML... So, building your TR as well... you'll have to append the TD to the TR, you'll have to append the TD with your input, you'll have to append your targeted table with the TR, etc.
I've created a table using an AJAX request to the database of items in our inventory displaying a picture/part name/price/stock remaining. When the table displays I would like to be able to click on any part of one of the rows and have it link to the item page associated with that item but it won't work.
I've tried the on.click with a static table written right into the html and it worked fine. Also if I direct the on.click script to just the table id instead of the table id and tr i can make the entire table clickable to the first row's href. So it appears that since the tr doesn't really exist in the html the javascript won't find it. Is there a way to get the script to recognize each 's href attribute?
HTML CODE + on.click script:
<html>
<body>
<table id="ctable">
<tbody id="tbody1" class="tbody1">
</tbody>
</table>
<script>
$('#ctable tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
</script>
</body>
</html>
.JS File CODE that creates table from .php file/mysql database
document.addEventListener('DOMContentLoaded', function() {
$.post('test.php', function(data) {
$("#tbody1").empty();
$.each(JSON.parse(data), function (index, value){
var eachrow = "<tr>" +
"<td class=\"image\">" + '<img src="images/thumbs/' +
value.image + '">' + "</td>" +
"<td>" + '<a href="' + value.link + '">' + value.part + "
</td>" +
"<td>" + value.price + "</td>"
"<td>" + value.stock + "</td>"
"</tr>";
$('#tbody1').append(eachrow);
});
});
}, false);
If you are dynamically adding rows, you need to either restructure your click event to listen from the context of the parent as in:
$("#tbody1").on("click", "tr", function(e) {
});
Assuming #tbody1 is a good place to start since you probably don't want the header row to be clickable. Or, every time you dynamically add rows, since the code is rebuilding the table, you can reattach the click event handlers:
$("#tbody1").empty();
$.each(JSON.parse(data), function (index, value){
var eachrow = "..
$('#tbody1').append(eachrow);
});
// or .on("click", function() { })
$("#tbody1 tr").click(function() { });
If you attach click handler via on, it would be good to then do an off as in:
$("#tbody1").off("click", "tr");
To remove the existing click handlers.
How can I add dynamical drop down selects(set default selecte!) in dynamically table by using javascript and JSON.
I want to add many selects (dropdown) to every row in my table, and set the default text in the select. The table is created by using javascript append and has dynamic content imported from JSON files using Jquery.
I can import all content successfully, however the dropdowns can not set selected . I would appriciate if you guys can assist me to have the dropdown select. Thank you very much!
<script type="text/javascript">
...
$(target).append("<tr style='height:150px'>" +
"<td><input type='checkbox'></td>" +
"<td>pics</td>" +
"<td>" + menuItemName + "</td>" +
"<td id='"+menuItemId+"'>" +
"</td>" +
"<td class='menuItemPrice'>" + menuData.Categories[c].Items[i].Price + "</td>" +
"<td>mount</td>" +
"</tr>"
);
...
for (var o = 0; o < menuData.Categories[c].Items[i].Options.length; o++) {
var inputs = {isFirst: firstOption,
optionId: menuData.Categories[c].Items[i].Options[o].MenuItemOptionId,
optionName: menuData.Categories[c].Items[i].Options[o].MenuItemOptionName,
price: menuData.Categories[c].Items[i].Options[o].Price
};
$('#'+menuItemId).append("<div><select"+
"<option value='1'>small</option>" +
"<option value='2'>mid</option>" +
"<option value='3'>big</option>" +
"<option value='4'>very big</option>"+
"</select></div>"
);
here I want to set the default Select but can not success,please help me,Thank You!
$('#'+menuItemId).children(':selected').text(inputs.optionName);//here just can show the last size.
HTML
...
<tbody id="sortable">
First, your select tag does not have a closing angle bracket (>) so the HTML is malformed. It should be something like this:
$('#'+menuItemId).append("<div><select>"+
Second, you should use find instead of children because what you are looking for is multiple levels below the element identified by your selector, like so:
$('#'+menuItemId).find(':selected').text(optionName);
Here is a working example: https://jsfiddle.net/tLddsL2p/1/
I'm trying to follow the prof's example of creating an editable table on double clicking an entry in a HTML table. So my data method looks like this:
function formatData(message) {
var str = "<table border=1>";
for (var i = 0; i < message.length; i++) {
str += "<tr>" + "<td class='editable'>" + message[i].id + "</td>" +
"<td>" + message[i].name + "</td>" +
"<td class='editable'>" + message[i].url + "</td>" +
"<td class='editable'>" + message[i].desc + "</td>" +
"<td>" + "<a href='#' onclick='deleteRequest(this); return false' id='" + message[i].id + "'>delete</a>" + "</td>" +
" + "</td>" + "</tr>";
}
str += "</table>";
return str;
}
I bind a function edit() to the tags whose attributes are of class 'editable.' Then my edit function does:
function edit(elm) {
/* check to see if we are already editing */
if (elm.firstChild.tagName && elm.firstChild.tagName.toUpperCase() == "INPUT")
return;
/* save original content */
var orig = elm.innerHTML;
/* create edit field */
var input = document.createElement("input");
input.type = "text";
input.value = elm.innerHTML;
input.size = 20;
/* convert content to editable */
elm.innerHTML = '';
elm.appendChild(input);
/* position cursor and focus */
if (input.selectionStart)
input.selectionStart = input.selectionEnd = 0;
else
{
var range = input.createTextRange();
range.move("character", 0);
range.select();
}
input.focus();
/* set save trigger callback */
input.onblur = function(){save(elm, input,orig);};
}
I'm confused on how I would save the information and pass it to the web server to update. I need the id, url, and desc to update the web server. Since they double click on a table entry, that just gives me the element at that value, but I don't have the id. Do I change two lines in my formatData to:
"<td class='editable' id='" + message[i].id + "'>" + message[i].url + "</td>" +
"<td class='editable' id='" + message[i].id +"'>" + message[i].desc + "</td>" +
So that way I can ask the webserver for the url and desc with that id value? That seems like a bad way to do it since now two have the same id, but I'm not sure since I'm relatively new to AJAX, HTML, Javascript. Thanks.
Eh, I'll push a bit of help your way.
Basically, from what I gather you're binding a function to each td tag with editable. Well, you can determine the id inside that function.
B/c you can select the parentNode of the current node being edited, and then select the firstChild of that parentNode, so parentNode.firstChild which should be the first td, since remember on each row each of your td's will have a single parent tr. Then you select the firstChild of that td node, which is the text node it contains, and then grab its value, the id. So parentNode.firstChild.firstChild.nodeValue
This might not follow exactly with your code, as you only show parts of it... but this is the gist of the idea. Basically selecting nodes through the DOM and pulling the right one based on the current context.
I'd suggest playing around with it till you get it.
Here's a little bit of sample code for you to think about if you get stuck still. It's meant to be brief.
Basically, each middle column is tagged with the test function on the onfocus event (clicking inside the input). So it's on the input itself, and it pulls the parentNode td, then the next parentNode tr, then the firstChild of tr which is the first td then the firstChild of the first td which is the input on that row, then finally that input's value attribute.
<script>
function test(elem) {
alert( elem.parentNode.parentNode.firstChild.firstChild.value );
}
</script>
<table>
<tr><td><input value="1"/></td><td><input value="stuff" onfocus="test(this)"/></td><td>other stuff</td></tr>
<tr><td><input value="2"/></td><td><input value="stuff3" onfocus="test(this)"/></td><td>other stuff</td></tr>
<tr><td><input value="3"/></td><td><input value="stuff2" onfocus="test(this)"/></td><td>other stuff</td></tr>
</table>
This question comes after solving my last question, I'd like to get some values out of the hidden forms but when I try to retrieve them only empty strings come by, I've considered just using arrays to store the information as it is introduced but I'd like to know if it's possible just to retrieve it afterwards and how.
Also, There is a table that is generated on the fly with some javascript:
function createTable(){
if ( document.getElementById("invoiceFormat").rowNumber.value != ""){
rows = document.getElementById("invoiceFormat").rowNumber.value;
}
var contents = "<table id='mt'><tr>";
if ( document.getElementById("invoiceFormat").cb1[0].checked ){
contents = contents + "<td class='htd'>Quantity</td>";
}if (document.getElementById("invoiceFormat").cb1[1].checked ){
contents = contents + "<td class='htd'>Description</td>";
}if (document.getElementById("invoiceFormat").cb1[2].checked ){
contents = contents + "<td class='htd'>Unitary Price</td>";
}if (document.getElementById("invoiceFormat").cb1[3].checked ){
contents = contents + "<td class='htd'>Subtotal</td>";
}
for (i=4; i<=k; i++){
if (document.getElementById("invoiceFormat").cb1[i].checked ){
contents = contents + "<td>" + document.getElementById("invoiceFormat").cb1[i].value + "</td>";
}
}
contents = contents + "</tr>";
for (j=1; j<=rows; j++){
contents = contents + "<tr>";
for (l=0; l<=k; l++){
if (document.getElementById("invoiceFormat").cb1[l].checked ){
hotfix = l +1;
contents = contents + "<td> <input id='cell" + j + "_" + hotfix + "' name='cell' type='text' size='15' /> </td>";
}
}
contents = contents + "</tr>";
}
contents = contents + "</table>";
var createdTable = document.getElementById("mainTable");
createdTable.innerHTML = contents;
}
After it's created I've tried to access it but without luck so far, I just can't get what the user inputs in the input fields that are created. How can I do this?
I'm using raw javascript with jQuery so answers with or without the library are welcomed :)
document.getElementById("invoiceFormat").cb1[3].checked
First of all I do not know what ".cb1[3]" means here so I will ignore it and will tell you how I would solve this problem: (I assume that "invoiceFormat" is id of your form.)
1) in your form set name property of every field you have. that way you can reach them like document.getElementById("invoiceFormat").fieldName.value
if you will use this method make sure that put your form in a local variable. it will be a lot faster
var form = document.getElementById("invoiceFormat");
form.fieldName.value;
2) give every field you have a unique id and just use getElementById directly on fields not on form.
I am not sue if this method is better, but I am useing second one all the time. I just get used to it I guess.
3) there is one more way but it might be an overkill. when you create your form fields, you can put them in an object(not values but the elements themselves) and even hide it in a closure. That way you can call something like
formElements.formFieldOne.value;