Dynamically add "select" with "default Text" in table through javascript - javascript

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/

Related

textarea clears when using innerhtml [duplicate]

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.

AJAX / JQuery - Print each nested child on new table row

I've been tearing my hair out over this seemingly simple problem, but I can't wrap my head around it.
I'm trying to generate a table in HTML using AJAX and some JQuery. The XML holds the data that I want rendered, each Child Node being rendered on a new line. The AJAX does all of the heavy lifting and generates the table.
XML Code:
<?xml version="1.0" encoding="utf-8"?>
<shows>
<show>
<title>Title</title>
<light>
<rule>Rule 1</rule>
<rule>Rule 2</rule>
</light>
<medium>
<rule>Rule 3</rule>
<rule>Rule 4</rule>
</medium>
<hard>
<rule>Rule 5</rule>
<rule>Rule 6</rule>
</hard>
<extreme>
<rule>Rule 7</rule>
</extreme>
</show>
</shows>
Obviously, I'll have more than this tiny bit of data down but that's besides the point.
Pertinent HTML
<table id="rules"></table>
And the Javascript:
$(xml).find('shows > show').each(function () {
var title = $(this).find('title').text();
title = "<tr>" + "<th>" + "</th>" + "<th>" + "<h1>" + title + "</h1>" + "</th>" + "</tr>";
category = "<tr>" + "<th>" + "</th>" + "<th>" + "Category Title: " + "</th>" + "</tr>";
rule = $(this).find('light > rule').text(); //problem is here?
punish = punish + "<tr>" + "<td>" + ruleCount + "</td>" + "<td>" + rule + "</td>" + "</tr>";
There's much more to the Javascript than this, but the line with the comment above I believe is the culprit of my headache. It's also essentially copied and pasted 3 more times in the script and modified to generate rules for medium, hard and extreme.
Here's the problem:
The Title, Category labels (table headers), rows, cells all generate just fine, but the data needs to be rendered so that each node (rule) is created on a new line (or new table row, essentially). Instead, the rule = $(this).find('light > rule').text(); line is cramming Rule 1 and 2 together, 3 and 4 together, etc (when reused further in the script obviously). The resulting HTML is a bit like this:
<table id="rules">
<tr><th></th><th><h1>Title</h1></th></tr>
<tr><td>1</td><td>Rule1Rule2</td></tr>
</table>
What I really want is for each rule to be on it's own table row. Like this:
<table id="rules">
<tr><th></th><th><h1>Title</h1></th></tr>
<tr><td>1</td><td>Rule1</td></tr>
<tr><td>2</td><td>Rule2</td></tr>
</table>
Any idea what I'm doing wrong??
Thanks in advance.
rule = $(this).find('light > rule').text();
This selects the two rule elements in light. text() returns a concatenation of the text of all elements in the wrapped set. You'll need to iterate over each rule using each()
$(this).find('light > rule').each(function() {
punish += "<tr><td>" + ruleCount + "</td><td>" + $(this).text() + "</td></tr>";
});
You need to use a loop to iterate through each rule
$(this).find('light > rule').each(function () {
punish = punish + "<tr>" + "<td>" + (ruleCount++) +"</td>" + "<td>" + $(this).text() + "</td>" + "</tr>";
})

Counting the number of appended elements for form submission

I have a web page that is a dynamic form. It allows users to specify any number of Attributes to devices. These attributes can be select option lists. When the user selects this, they are presented with a button to add options.
My problem is that I need to know how many options there are for each attribute. I have tried using var counter=$('.class-name').next().val(); to try and count them alert(counter); to see if it works. But all I get is an alert of undefined so the var counter is not being initalised.
I need to know the number of options for each select list to be able to group them together and know which options go with a particular attribute. I cannot think of a way to do this through JS or PHP. I can get the options posted in the php but I can't identify what options go with each attribute.
Here is a fiddle!
Here is the code to get the lengths for each of the respective options.
$('.tattribute option:selected[value="text"]').length
$('.tattribute option:selected[value="checkbox"]').length
$('.tattribute option:selected[value="select-list"]').length
$('.tattribute option:selected[value="notes"]').length
Fiddle
Here is a fiddle with a hidden field added to keep track of the options count. Every time an option is added or removed the value of the hidden field is incremented or decremented. The changes are in the code below
var template="<div class=\"new-attribute\">"
+ "<h3>New Attribute</h3>"
+ "<label for=\"attributeName[]"+"\">Name:</label>"
+ "<input class=\"attribute\" type=\"text\" name=\"attributeName[]"+"\">"
+ "<input class=\"attribute_count\" type=\"hidden\" name=\"attributeCount[]"+"\">"
+ "<label for=\"attributeType[]"+"\">Type:</label>"
+ "<select class=\"tattribute\" name=\"attributeType[]"+"\">"
+ "<option value=\"text\" selected>Text</option>"
+ "<option value=\"checkbox\">Checkbox</option>"
+ "<option value=\"select-list\">Select Option List</option>"
+ "<option value=\"notes\">Notes</option>"
+ "</select>"
+ "<div class=\"option\"></div>"
+ "<button type=\"button\" class=\"remove\">Delete</button>"
+ "</div>";
And
//Add action
$("#attributes").on('click', '.btn', function () {
add = "<div class=\"op\"><label for=\"attributeOption[]" +"\">Name:</label>"
+ "<input class=\"option-input\" type=\"text\" name=\"attributeOption[]" + "\">"
+"<button type=\"button\" class=\"remove-option\">remove</button></div>";
$(this).after(add);
//COUNT NUMBER OF OPTIONS
$opt = $(this).closest('.option')
$opt.siblings('.attribute_count').val($opt.find('.op').length)
alert($opt.siblings('.attribute_count').val());
});
//Remove input
$("#attributes").on('click', '.remove-option', function () {
$(this).closest('.op').remove();
$opt = $(this).closest('.option')
$opt.siblings('attribute_count').val($opt.find('.op').length)
});

Create an editable HTML table

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>

Javascript DOM Trickiness

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

Categories

Resources