I have a DOM with different nested divs and inputs (with values):
<div id ="div_id1">
<div id ="div_id2">
<table>
<tr>
<td>input 1:</td>
<td><input id="i1" type="text"/></td>
</tr>
<tr>
<td>input 2:</td>
<td><input id="i2" type="text"/></td>
</tr>
<tr>
<td>input 3:</td>
<td><input id="i3" type="text"/></td>
</tr>
</table>
<div id ="div_id3">
<table>
<tr>
<td>input 4:</td>
<td><input id="i4" type="text"/></td>
</tr>
<tr>
<td>input 5:</td>
<td><input id="i5" type="text"/></td>
</tr>
</table>
</div>
</div>
How to make XML string recursively according to this structure?
Like this:
<div_id1>
<div_id2>
<i1>value 1</i1>
<i2>value 2</i2>
<i3>value 3</i3>
<div_id3>
<i4>value 4</i4>
<i5>value 5</i5>
</div_id3>
</div_id2>
UPD:
I tried function like this:
function makeXml(nodes) {
var $result = $('<' + nodes.attr('id') + '>');
$.each(nodes, function(i, node) {
var nodeId = node.getAttribute('id');
var $el = $('<' + nodeId + '>').text($('#' + nodeId).val());
alert(nodeId + $('#' + nodeId).val());
$el.appendTo($result);
var $children = $(node).children();
if ($children.length > 0) {
makeXml($children).appendTo($el);
}
});
return $result;
};
But it does not work properly (does not correctly handle nested divs).
Does anyone have any solution?
One of the options (create a XML-string):
var str = '';
function makeXml(obj) {
var children = obj.children();
if (children.size() != 0) {
$.each(children, function(i, v) {
var $val = $(v), id = $val.attr('id');
if (typeof($val.attr('id')) !== "undefined") {
str += '<' + id + '>' + $('#' + id).val();
makeXml($val);
str += '</' + id + '>';
} else {
makeXml($val);
}
});
}
}
Related
I am appending a row on a given "id" after entering the input field but it's not appending.
function myfunction() {
var obj = "<tr><td>" + document.getElementById("name").value + "</td><td>" + document.getElementById("num").value + "</td><td>" + document.getElementById("address").value + "</td></tr>";
document.getElementById("table").innerHTML = obj;
}
<table>
<tr>
<td>Name: <input type="text" id="name"></td>
<td>Age:<input type="number" id="num"></td>
<td>Address:<input type="text" id="address"></td>
<td><input type="button" onclick="myfunction()" value="click on me"></td>
</tr>
<tbody id="table">
</tbody>
</table>
EDIT : you have several typo:
You write "innnnerHtml" (3n) instead of "innerHtml"
By writing innerHtml = obj you replace all html inside the selected div (the table in your case) you must use "+="
You use innerHtmlproperty instead of appendfunction.
function myfunction(){
var obj = "<tr><td>" + document.getElementById("name").value + "</td><td>" + document.getElementById("num").value + "</td><td>" + document.getElementById("address").value + "</td></tr>";
document.getElementById("table").innerHTML += obj;
}
// an other way to do it
function myfunction2() {
var line = document.createElement("tr");
var td1 = document.createElement("td");
td1.append(document.getElementById("name").value);
var td2 = document.createElement("td");
td2.append(document.getElementById("num").value);
var td3 = document.createElement("td");
td3.append(document.getElementById("address").value);
line.append(td1);
line.append(td2);
line.append(td3);
document.getElementById("table").append(line)
}
<table>
<tr>
<td>Name: <input type="text" id="name"></td>
<td>Age:<input type="number" id="num"></td>
<td>Address:<input type="text" id="address"></td>
<td><input type="button" onclick="myfunction()" value="click on me"></td>
<td><input type="button" onclick="myfunction2()" value="other way"></td>
</tr>
<tbody id="table">
</tbody>
</table>
It's better to call appendChild instead of innerHTML.
Using appendChild adds a new DOM element to the end of the parent node, while innerHTML takes the existing DOM content of the parent node, work with it as string, and overwrite the existing elements of the parent node with DOM generated elements from that string.
But, in Javascript we have a couple of functions like insertRow that helps you even more. See the example:
function myfunction() {
var name = document.getElementById("name").value,
num = document.getElementById("num").value,
address = document.getElementById("address").value;
var tbody = document.getElementById("table");
addRow(tbody, name, num, address);
}
function addRow(tbody, name, num, address){
var row = tbody.insertRow();
addCell(row, name, 0);
addCell(row, num, 1);
addCell(row, address, 2);
}
function addCell(row, cellText, index){
var cell = row.insertCell(index);
cell.appendChild(document.createTextNode(cellText));
}
<table>
<tr>
<td>Name: <input type="text" id="name"></td>
<td>Age:<input type="number" id="num"></td>
<td>Address:<input type="text" id="address"></td>
<td><input type="button" onclick="myfunction()" value="click on me"></td>
</tr>
<tbody id="table">
</tbody>
</table>
try this code
html code
<table id="table">
<tr>
<td>Name: <input type="text" id="name"></td>
<td>Age:<input type="number" id="num"></td>
<td>Address:<input type="text" id="address"></td>
<td><input type="button" onclick="myfunction()" value="click on me"></td>
</tr>
<tbody >
</tbody>
</table>
javascript function
function myfunction() {
var obj = "<tr><td>Name:" + document.getElementById("name").value + "</td><td>Age: " + document.getElementById("num").value + "</td><td>Address:" + document.getElementById("address").value + "</td></tr>";
$('#table tbody').append(obj);
// document.getElementById("table").innnerHTML = obj;
}
Try this code . It will helps you.
function myfunction() {
var obj = "<tr><td>" + document.getElementById("name").value + "</td><td>" +
document.getElementById("num").value + "</td><td>" +
document.getElementById("address").value + "</td></tr>";
table.innerHTML = obj;
}
Use this and watch out for the following:
Your table structure.
Typo in innerHTML
Your script was meant to overwrite not append.
function myfunction() {
var obj = "<tr><td>" + document.getElementById("name").value + "</td><td>" + document.getElementById("num").value + "</td><td>" + document.getElementById("address").value + "</td></tr>";
document.getElementById("table").innerHTML += obj;
console.log(obj);
}
<table>
<tbody id="table">
<tr>
<td>Name: <input type="text" id="name"></td>
<td>Age:<input type="number" id="num"></td>
<td>Address:<input type="text" id="address"></td>
<td><input type="button" onclick="myfunction()" value="click on me"></td>
</tr>
</tbody>
</table>
I would like to make a function which counts how many attributes I have with Attribute name&value I entered in html.
I don't know how to count by Attribute name&value!
like when i put "type" and "text" in this html then show 2!
I am very new to javascript! if you help me it would be very thankful! thanks
function javascript_click() {
if (document.getElementById("value3").value && document.getElementById("value4").value ) {
var attName=document.getElementById("value3").value;
var attValue=document.getElementById("value4").value;
if((attName && attValue) !==''){
var val3 = document.getElementById("value3");}
else {
document.getElementById("cnt").innerHTML +=
"wrong value of ID <br>";
}
}
}
<form action="">
<table class="tg" id="tg">
<tr>
<td>Attribute name</td>
<td><input type="text" id="value3"></td>
</tr>
<tr>
<td>attribute value</td>
<td><input type="text" id="value4"></td>
</tr>
</table>
<div id="cnt"></div>
</form>
<div class="button">
<button id='btn_javascript' onclick="javascript_click();">javascript</button>
</div>
Every time the user is entering a pair of attributes I'm pushing the attributes in an array attRy.
attRy.length will give you the number of attributes pairs.
let attRy = []
function javascript_click() {
if (value3.value && value4.value ) {
var attName = value3.value;
var attValue = value4.value;
if(attName !=='' && attValue !==''){
attRy.push(attName + ": " +attValue);
cnt.innerHTML = attRy.length +" attributes:<br>";
attRy.forEach((a) =>{
cnt.innerHTML += a + "<br>"
})
}
else {
cnt.innerHTML +=
"wrong value of ID <br>";
}
}
}
<form action="">
<table class="tg" id="tg">
<tr>
<td>Attribute name</td>
<td><input type="text" id="value3"></td>
</tr>
<tr>
<td>attribute value</td>
<td><input type="text" id="value4"></td>
</tr>
</table>
<div id="cnt"></div>
</form>
<div class="button">
<button id='btn_javascript' onclick="javascript_click();">javascript</button>
</div>
I hope I understand you right
function javascript_click() {
if (document.getElementById("value3").value && document.getElementById("value4").value) {
var attName = document.getElementById("value3").value;
var attValue = document.getElementById("value4").value;
var value = "[" + attName + "=" + attValue + "]";
var num2 = document.querySelectorAll(value).length;
document.getElementById("cnt").innerHTML += "선택하신 노드는 " + num2 + "개 입니다. By javascript<br>";
} else {
document.getElementById("cnt").innerHTML += "wrong value of ID <br>";
}
}
<form action="">
<table class="tg" id="tg">
<tr>
<td>Attribute name</td>
<td><input type="text" id="value3"></td>
</tr>
<tr>
<td>attribute value</td>
<td><input type="text" id="value4"></td>
</tr>
</table>
<div id="cnt"></div>
</form>
<div class="button">
<button id='btn_javascript' onclick="javascript_click();">javascript</button>
</div>
I am trying to dynamically add rows to a table to take orders and have created a javascript function for it.
function addnewrow()
{
var lastid = $("#table tr:last").attr("id");
var newid=lastid+1;
var newcolumn = document.createElement("tr");
newcolumn.id=newid;
newcolumn.innerHTML = "<td id='no"+newid+"'><a class='cut'>-</a>"+newid+"</td>"+
"<td>"+
"<ajaxToolkit:ComboBox ID='prod"+newid+"' runat='server' DataSourceID='SqlDataSource2' DataTextField='pname' DataValueField='pid' MaxLength='0' style='display: inline;'></ajaxToolkit:ComboBox>" +
"</td>"+
"<td><input type='number' required='required' min='1' name='quantity" + newid + "' /></td>" +
"<td id='price" + newid + "'></td>" +
"<td id='amount" + newid + "'></td>";
document.getElementById("table").appendChild(newcolumn);
}
I am doing this to get the values of all the elements in the code behind file to put them in database.
but due to this i get an error in the aspx.designer.cs page saying semicolon expected
protected global::AjaxControlToolkit.ComboBox prod" + newid + ";
ASP.NET Code
<table class="Grid" id="table">
<tr>
<td colspan="5">Enter Order Details</td>
</tr>
<tr>
<th>Sr No.</th>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
<th>Amount</th>
</tr>
<tr id="1">
<td><a class="cut">-</a>1</td>
<td>
<ajaxToolkit:ComboBox ID="prod1" runat="server" DataSourceID="SqlDataSource2" DataTextField="pname" DataValueField="pid" MaxLength="0" style="display: inline;"></ajaxToolkit:ComboBox>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:micoConnectionString %>" SelectCommand="SELECT [pid], [pname] FROM [Products]"></asp:SqlDataSource>
</td>
<td><input type="number" required="required" min="1" name="quantity1" /></td>
<td id="price1"></td>
<td id="amount1"></td>
</tr>
</table>
<a class="add" onclick="addnewrow()" href="#">+</a>
Check this
$("#btnAddSchedule").click(function () {
var trs = $("[id^=trSchedules]");
var numberofrows = trs.length;
var newtr = $('#' + trs[0].id).clone();
$(newtr).attr('id', $(newtr).attr('id').replace(/\d+/, numberofrows));
newtr.find("input,select,img").each(function () {
$(this).attr('id', $(this).attr('id').replace(/\d+/, numberofrows));
$(this).attr('name', $(this).attr('name').replace(/\d+/, numberofrows));
if ($(this).attr('type') != "hidden") {
$(this).val('');
}
else if ($(this).attr('id').indexOf('DataExportQueueID') == -1) {
$(this).val('');
}
if ($(this).attr("type") == "checkbox") {
$(this).removeAttr("checked");
$(this).parent().html($(this).parent().html().replace(/\d+/g, numberofrows));
}
if ($(this).attr("type") == "button") {
$(this).attr("onclick", "deleteSchedule(this,0);");
}
});
$('#' + trs[numberofrows - 1].id).after(newtr);
CrossCheckScheduleRows();
});
function CrossCheckScheduleRows() {
$('[id^=trSchedules]').each(function () {
var row = $(this);
var index = row[0].rowIndex - 2;
row.attr('id', row.attr('id').replace(/\d+/, index));
row.find("input,select,img").each(function () {
$(this).attr('id', $(this).attr('id').replace(/\d+/, index)).attr('name', $(this).attr('name').replace(/\d+/, index));
});
});
}
I use this for the same purpose, maybe it will help you
I have a problem not getting the <input> inside a specified <td>. Through jQuery, I want once an "input search" entered, get just those <tr> that have these entries.Then when the input is empty return all the entries.
Here is my code :
<table id="hosts">
<tr>
<th>First</th>
<th>Second</th>
</tr>
<tr>
<td id="host"><input type="text" id="inputhost" value="214215" size="16"></td>
<td id="rand"><input type="text" id="inputrand" value="442" size="16"></td>
</tr>
<tr>
<td id="host"><input type="text" id="inputhost" value="1252512" size="16"></td>
<td id="rand"><input type="text" id="inputrand" value="556" size="16"></td>
</tr>
<tr>
<td id="host"><input type="text" id="inputhost" value="2114" size="16"></td>
<td id="rand"><input type="text" id="inputrand" value="4666" size="16"></td>
</tr>
<tr>
<td id="host"><input type="text" id="inputhost" value="3245466" size="16"></td>
<td id="rand"><input type="text" id="inputrand" value="22654" size="16"></td>
</tr>
<tr>
<td id="host"><input type="text" id="inputhost" value="24588" size="16"></td>
<td id="rand"><input type="text" id="inputrand" value="54877" size="16"></td>
</tr>
</table>
<br />
<input type="text" id="search" placeholder=" live search"></input>
and this is my jQuery code:
function removeHighlighting(highlightedElements) {
highlightedElements.each(function () {
var element = $(this);
element.replaceWith(element.html());
})
}
function addHighlighting(element, textToHighlight) {
var text = element.text();
var highlightedText = '<em>' + textToHighlight + '</em>';
var newText = text.replace(textToHighlight, highlightedText);
element.html(newText);
}
$("#search").on("keyup", function () {
var value = $(this).val();
removeHighlighting($("table tr em"));
$("#hosts tr").each(function (index) {
if (index !== 0) {
$row = $(this);
var $host = $row.find("#host input#inputhost");
var $dest = $row.find("#rand input#inputrand");
var host_id = $host.text();
var dest_id = $dest.text();
var hostIndex = host_id.indexOf(value);
var destIndex = dest_id.indexOf(value);
if ((hostIndex == -1) && (destIndex == -1)) {
$row.hide();
}
else if ((hostIndex != -1) && (destIndex != -1)) {
addHighlighting($host, value);
addHighlighting($dest, value);
$row.show();
}
else if (hostIndex != -1) {
addHighlighting($host, value);
$row.show();
}
else {
addHighlighting($dest, value);
$row.show();
}
}
});
});
Duplicate IDs! You don't really need them; remove them and then your code will be:
var $host = $row.find("td:first input");
var $dest = $row.find("td:eq(1) input");
UPDATE
You also have to update your code to:
var host_id = $host.val();
var dest_id = $dest.val();
DEMO
You cant give Id like that. Id should be unique. change them to class. then it will work. Then your selector will be
$(this).find(".host input.inputhost")
I GET a HTML response from AJAX over cors and the response is a table. Each category has its title and sub elements. The title names vary quite a bit and are likely to change in the future. The sub elements in each title change almost on a daily basis, but the DOM structure doesn't.
Is there a way I could get rid of this if statement and replace it with code that isn't element specific? Some way of selecting DOM elements I'm not aware of?
Relevat JS
classifiedFilter: function( response ) {
var Classified = {
ClaAdministrative: [],
Paraeducator: [],
Clerical: [],
Custodial: [],
NonRep: [],
Maintenance: [],
ClaSubstitute: [],
Coaching: []
},
response = $(response).find("table tbody tr td").html();
$(response).find("#isHeadType").remove();
$(response).find("font:contains(Open to all)").parent().parent().remove();
//Filter each span title and classify sub items
$(response).find("span").parents("tr").each( function() {
//Find categories and separate by class
var rowtext = $(this).find("span").text(),
position = "";
position = rowtext.replace(/-/gi, "").replace(/\s/g, "");
$(this).nextAll("tr").addClass(position);
//Push content into Classified
((position === "Administrative") ? $(this).nextUntil(".Paraeducator").each( function() {
Classified.ClaAdministrative.push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
}) :
((position === "Paraeducator") ? $(this).nextUntil(".Clerical").each( function() {
Classified.Paraeducator.push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
}) :
((position === "Clerical") ? $(this).nextUntil(".Custodial").each( function() {
Classified.Clerical.push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
}) :
((position === "Custodial") ? $(this).nextUntil(".NonRep").each( function() {
Classified.Custodial.push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
}) :
((position === "NonRep") ? $(this).nextUntil(".Maintenance").each( function() {
Classified.NonRep.push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
}) :
((position === "Maintenance") ? $(this).nextUntil(".Substitute").each( function() {
Classified.Maintenance.push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
}) :
((position === "Substitute") ? $(this).nextUntil(".Coaching").each( function() {
Classified.ClaSubstitute.push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
}) :
((position === "Coaching") ? $(this).nextAll().each( function() {
Classified.Coaching.push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
}) : [] ) ) ) ) ) ) ) );
});
//remove title from array
Certificated.Elementary.shift();
Certificated.MiddleSchool.shift();
Certificated.HighSchool.shift();
Certificated.K12.shift();
Certificated.Substitute.shift();
}
Summarized HTML GET response (added spaces for visual aid)
<table border="0" cellspacing="0" cellpadding="0" style="MARGIN-TOP: 10px;">
<tr>
<td>
<font class="HeadTitle">External Positions: Open to all applicants.</font><br>
</td>
</tr>
<tr>
<td height="20" nowrap="nowrap">
<i><span id="ExternalJobs__ctl1_BargainGroup" class="BodyText">Administrative</span></i>
<br/><br/>
</td>
</tr>
<tr>
<td nowrap="nowrap" style="padding-left:20px;" class="BodyText">
<b><a href='jobs.aspx?id=3660&type=2&int=External'>Administrative Assistant I, Health Tech-Leave Replacement-2 hours - ME1214</a></b>
</td>
</tr>
<tr>
<td height="20" nowrap="nowrap">
<i><span id="ExternalJobs__ctl2_BargainGroup" class="BodyText">Paraeducator</span></i>
<br/><br/>
</td>
</tr>
<tr>
<td nowrap="nowrap" style="padding-left:20px;" class="BodyText">
<b><a href='jobs.aspx?id=3544&type=2&int=External'>Paraeducator, SpEd IP/ELL-6.5hours - MC1223</a></b>
</td>
</tr>
<tr>
<td nowrap="nowrap" style="padding-left:20px;" class="BodyText">
<b><a href='jobs.aspx?id=3603&type=2&int=External'>Special Ed Paraeducator, School Adjustment Program (SA-)-6.5 hours - MK1215</a></b>
</td>
</tr>
<tr>
<td height="20" nowrap="nowrap">
<i><span id="ExternalJobs__ctl3_BargainGroup" class="BodyText">Clerical</span></i>
<br/><br/>
</td>
</tr>
<tr>
<td nowrap="nowrap" style="padding-left:20px;" class="BodyText">
<b><a href='jobs.aspx?id=3481&type=2&int=External'>Admin Assistant IV-8 hours - IT1209</a></b>
</td>
</tr>
<tr>
<td height="20" nowrap="nowrap">
<i><span id="ExternalJobs__ctl5_BargainGroup" class="BodyText">Non-Rep</span></i>
<br/><br/>
</td>
</tr>
<tr>
<td nowrap="nowrap" style="padding-left:20px;" class="BodyText">
<b><a href='jobs.aspx?id=2732&type=2&int=External'>Licensed Practical Nurse (Pool position) - 2012LPNPool</a></b>
</td>
</tr>
<tr>
<td nowrap="nowrap" style="padding-left:20px;" class="BodyText">
<b><a href='jobs.aspx?id=3472&type=2&int=External'>Certified Occupational/Physical Therapist Assistant- POOL - COTA2012Pool</a></b>
</td>
</tr>
<tr>
<td height="20" nowrap="nowrap">
<i><span id="ExternalJobs__ctl7_BargainGroup" class="BodyText">Substitute</span></i>
<br/><br/>
</td>
</tr>
<tr>
<td nowrap="nowrap" style="padding-left:20px;" class="BodyText">
<b><a href='jobs.aspx?id=26&type=2&int=External'>Substitute Food Service Helpers - FSSub</a></b>
</td>
</tr>
<tr>
<td nowrap="nowrap" style="padding-left:20px;" class="BodyText">
<b><a href='jobs.aspx?id=28&type=2&int=External'>Substitute Custodians - MTSub</a></b>
</td>
</tr>
</table>
This seems equivalent to the core of your current code:
$(this).each( function() {
Classified[position].push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
});
[Edit] I don't see where you declare your arrays, you might actually need this:
$(this).each( function() {
Classified[position]=Classified[position]||[];
Classified[position].push( $.trim( "<tr>" + $(this).html() + "</tr>" ) );
});
[Update] Based on the comments, this loop updates position whenever it hits a span:
var position = "";
$(response).find("tr").each( function() {
var currentTR=$(this);
// catch span if any
var rowtext = currentTR.find("span").text().replace(/-/gi, "").replace(/\s/g, "");
if (rowtext) {
position = rowtext;
Classified[position]=[];
}
// Collect rows
Classified[position].push( "<tr>" + $.trim($(this).html()) + "</tr>" );
});
I think, you can use CSS class names in find function instead of tag names.