how to overide childnode value with dynamic content using javascript - javascript

My requirement is to update the dynamic content to the child element. I tried to iterate the parent elements one by one and trying to update the child elements but I am unable can anyone guide me please?Thanks
<section id="parent_sec">
<div id="parent1">
<div id="childdiv">default1</div>
</div>
I tried like belo
function getTragetElement(elem, tem){
var tem1 = 'childiv';
for (i = 0; i <= elem.length - 1; i++) {
if(elem[i].childdiv!= undefined && elem[i].childdiv!= null){
elem[i].childdiv.innerHTML = "12345";
break;
}else{
getTragetElement(elem[i], tem1);
}
}
}
var parentDiv = document.getElementById("parent_sec");
var childElements = parentDiv.children;
getTragetElement(childElements[0], 'childdiv')

first when you pass in the array as a parameter don't declare an index value just pass in the array and let only the function declare the value (as your function is already doing).
And also take out the .childdiv when changing the content of the child div, because this doesn't work and there is no need for calling the child div, because the array with the index declaration, in your case - elem[i] - already contains the child div itself.
so here is a edited example:
function getTragetElement(elem, tem){
var tem1 = 'childiv';
for (i = 0; i <= elem.length ; i++) {
if(elem[i]!= undefined && elem[i] != null){
elem[i].innerHTML = "12345";
}else{
getTragetElement(elem[i], tem1);
}
}
}
var parentDiv = document.getElementById("parent1");
var childElements = parentDiv.children;
//passing in the array childElenents without an index value
getTragetElement(childElements, 'childdiv')

Related

Javascript For loop appending child only appends first element, then throws error

I'm looping through a js object with a nested for loop, stated below, it appends the first element correctly, but then throws the following error:
Can't set the property className of an undefined reference or empty reference. (not sure if exact error, translating from Dutch...)
function allVideos() {
var sql = "SELECT videos.VideoName, videos.VideoPath FROM videos";
var resultSet = db.query(sql, {json:true}); //returns: [{"VideoName":"timelapse aethon2","VideoPath":"videos\\Roermond Papier\\160424 Time laps Aethon2.avi"},{"VideoName":"timelapse aethon3","VideoPath":"videos\\Roermond Papier\\160424 Time laps Aethon2.avi"}]
var parsed = JSON.parse(resultSet);
var parsedlength = arrLenght(parsed);
//alert(resultSet);
for(var i = 0; i < parsedlength; i++) {
var obj = parsed[i];
//alert(i);
var videoElement = document.getElementById("allVideos");
for (var key in obj) {
if(obj.hasOwnProperty(key)) {
videoElement.appendChild(document.createElement('div'));
videoElement.children[i].id='allVid' + i;
videoElement.children[i].className='col-md-4 col-xs-12';
//alert(typeof key)
var card = document.getElementById('allVid' + i);
alert(i);
card.appendChild(document.createElement('div'));
card.children[i].className='card card-block';
card.children[i].innerHTML = "<h3 class='card-title'>" + obj['VideoName'] + "</h3><button class='btn btn-primary'>Selecteren</button>"
}
}
}
}
[EDIT] added screenshot of how it looks
Your code has some significant logic issues. You're using nested loops, but appending to an element assuming that the outer loop counter will let you index into that element's children to get the element you just appended. Later, you try to get that same element again using getElementById. Then, you append a new element to your newly-created element, but try to access that new element using children[i] on the one you just created — at that point, the card element will only have a single child, so as of the second outer loop, it will fail.
createElement returns the element to you, so there's no reason at all to try to access it via children[i] (either time) or getElementById.
See comments:
function allVideos() {
var sql = "SELECT videos.VideoName, videos.VideoPath FROM videos";
var resultSet = db.query(sql, {json:true});
var parsed = JSON.parse(resultSet);
var parsedlength = arrLenght(parsed);
for(var i = 0; i < parsedlength; i++) {
var obj = parsed[i];
//alert(i);
var videoElement = document.getElementById("allVideos");
for (var key in obj) {
if(obj.hasOwnProperty(key)) {
// Create the card, give it its id and class
var card = document.createElement('div');
card.id='allVid' + i;
card.className='col-md-4 col-xs-12';
// Create the div to put in the card, give it its class and content
var div = document.createElement('div');
card.appendChild(div);
div.className='card card-block';
div.innerHTML = "<h3 class='card-title'>" + obj['VideoName'] + "</h3><button class='btn btn-primary'>Selecteren</button>"
// Append the card
videoElement.appendChild(card);
}
}
}
}
Side note: arrLenght looks like a typo (it should be th, not ht), but moreover, there's no reason to use a function to get the length of an array; it's available via the array's length property: parsedLength = parsed.length.
Side note 2: You may find these ways of looping through arrays useful.
Your problem is the if within the nested for:
if(obj.hasOwnProperty(key)) { ...
The variable i is increased even if the property is not "owned" (when the if condition returns false), so next time that the condition is true, i is out of bounds.

Error while selecting allElementsByID and adding a class to them

Hello I'm trying to add a class to all of my elements on a webpage. The overall goal is to grab all the elements on a webpage and add in a class. The class containing a font size will be changed to hide a message.
I'm getting this error
Uncaught TypeError: Cannot set property 'innerHTML' of null
I've tried moving my script outside the body tag of my index.html but its still not working.
Another problem is I can't add a class to all of the IDs I'm selecting. I can add classes manually like
$("#iconLog").addClass("style"); //this works
but when I try to add a class like this
empTwo = "#" + temp; //where empTwo is a string that equals "#iconLog"
$("empTwo").addClass("style") //this does not work
I'll post my entire script below for reference
$(function() {
var hideMsg = "f";
var n = hideMsg.length;
var i;
var j;
var holder;
var hideHolder;
// on button click - hide msg
$('#btnHide').on('click', function() {
//grab all IDS ON WEBPAGE
var allElements = document.getElementsByTagName("*");
var allIds = [];
for (var i = 0, n = allElements.length; i < n; ++i) {
var el = allElements[i];
if (el.id) {
allIds.push(el.id);
}
}
//ERRORS HAPPENING IN THIS LOOP
for(var i = 0; i < allElements.length; ++i)
{
console.log(allIds[i]);
try{
var temp = document.getElementById(allIds[i]).id;
}
catch(err){
document.getElementById("*").innerHTML = err.message;
}
tempTwo = "#" + temp;
console.log(tempTwo);
//$("#iconLog").addClass("style") //this works
$("tempTwo").addClass("style"); //this does not work
}
for(i = 0; i < n; i++) {
//set var holder to first value of the message to hide
holder = hideMsg.charCodeAt(i);
for(j = 7; -1 < j; j--) {
//set hideHolder to holders value
hideHolder = holder;
//mask hideHolder to grab the first bit to hide
hideHolder = hideHolder & (1<<j);
//grab the first element ID
if(hideHolder === 0) {
// embed the bit
// bitwise &=
} else {
//embed the bit
// bitwise ^=
}
}
}
});
});
To add a class to all elements you don't need a for loop. Try this:
$("*").addClass("style");
Same for setting the inner html of all elements. Try this:
$("*").html("Html here");
Remove the double quotes from empTwo .You don't need quotes when you are passing a varible as a selector. The variable itself contains a string so you don't need the quotes.
empTwo = "#" + temp;
$(empTwo).addClass("style") //this will work
Try this:
$(empTwo).addClass("style")
Note: You used string instead of variable:
well,
try this...
You were passing the varibale in the quotos because of that instead of getting value to empTwo it was searching directly for "empTwo".
$(empTwo).addClass("style");
to get all element try this-
var allElements = = document.body.getElementsByTagName("*");
Hoping this will help you :)
empTwo = "#" + temp; //where empTwo is a string that equals "#iconLog"
$("empTwo").addClass("style") //this does not work
You made mistake in the second Line.
The variable empTwo already is in string format.
So all you need to do is
$(empTwo).addClass("style") //this works because empTwo returns "#iconLog"

Trouble with changing the text of an element based off of a text form .val()

My app dynamically creates and deleted new elements based on the + / - buttons.
Inside the dynamically created elements are text forms. I want whatever the user types into the text form to be displayed in another dynamically created element.
$('.LName').keyup(function(event) {
var crazy = {};
for (var x = 1; x < i; x++) {
crazy[x] = function() {
$('#sideChange'+ x).keyup(function(event) {
var value = $(this).val();
$('.sLoan'+ x).text(value);
})
}
}
for (var p = 1; p < i; p++) {
crazy[p]();
}
});
For example, I accomplished this for changing the text in the previous element by including the function in the html onkeyup attribute, but I don't know how to accurately target other elements.
var changeTitle = function() {
var loanTitle = $(this).val();
var code = $("input[type='text'][name='loanName']").keyCode || $("input[type='text'][name='loanName']").which;
var length = loanTitle.length;
console.log(length);
if(length < 1 || code == 8) {
$(this).prev().text('Loan');
}
else {
$(this).prev().text(loanTitle);
}
};
What youll probably want to do is data bind the two elements with some sort of ID you generate. In the fiddle below, I just use an incrementing number. When the keyup happens, I grab that elements data-id and use it to find its "mirrored" input.
$('.mirror[data-id="'+id+'"]').val(text);
Your question was a bit vague but I think this is what you were asking for.
http://jsfiddle.net/swoogie/f8cd4voz/

having trouble with document.getElementById for dynamic client id

Do you have to do anything special while passing in a dynamically created string as a clientID for document.getElementById?
I have a asp:gridview control that has a textbox column and a checkbox column. I added an onclick event to the checkboxes to set the textbox value of that row to the max value of all checked rows +1. I pass in the IDs of the grid and the controls of the row that was selected. I can getElementByID fine for these controls, but When I dynamically build the IDs of the other controls, I keep getting null, even though I know that the IDs are correct. My code is bellow.
function SetPriority(cbID, tbID, gridID) {
var cb = document.getElementById(cbID);
if (cb.checked) {
var tb = document.getElementById(tbID);
var grid = document.getElementById(gridID);
var maxv = 0;
for (var i = 0; i < grid.rows.length; i++) {
var indexID = 102 + i;
var cbClientID = 'LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ct' + indexID + '_chkGroup';
var tbClientID = 'LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ct' + indexID + '_txtPriority';
console.log("row" + i);
//just for example of how it should be working
console.log(cbID);
var cbx = document.getElementById(cbID);
console.log(cbx);
//get row checkbox
console.log(cbClientID);
var thisCB = document.getElementById(cbClientID);
console.log(thisCB);
//get row textbox
var thisTB = document.getElementById(tbClientID);
console.log(thisTB);
if (thisCB) {
if (thisCB.type == "checkbox") {
if (thisCB.checked) {
if (thisTB.value > maxv)
maxv = thisTB.value;
}
}
}
}
tb.value = parseInt(maxv) + 1;
}
}
Here is how its showing up in the console, where you can see the IDs for the first row are the same
For Those wondering about How I am calling the function, I am adding it on to a checkbox in a .net gridview control on row databind. It renders as follows:
<input id="LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ctl02_chkGroup" type="checkbox" name="LeaveInfo$pnlMain$wgbLeaveSummary$gridSubmitted$ctl02$chkGroup" onclick="javascript:SetPriority('LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ctl02_chkGroup','LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ctl02_txtPriority','LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted');">
The vb .net code to add the function is this...(on-_RowDataBound)
Dim chk As CheckBox = CType(e.Row.FindControl("chkGroup"), CheckBox)
Dim tb As TextBox = CType(e.Row.FindControl("txtPriority"), TextBox)
chk.Attributes.Add("onclick", String.Format("javascript:SetPriority('{0}','{1}','{2}');", chk.ClientID, tb.ClientID, gridSubmitted.ClientID))
No, you don't have to do anything special when dynamically building a string. A string in javascript is the same string whether it was built dynamically or specified directly in your code. If document.getElementById() is not working, then one of the following is likely the cause:
Your string isn't what you think it is so it doesn't match the target id.
Your DOM id isn't what you think it is.
You have multiple elements with the same id (not likely here because you won't get null)
You are calling getElementById() before the DOM is ready or before the desired elements have been added to the DOM.
In this case, it seems more likely that 1) or 2) are the issues here, but you don't show us any context to know whether 4) could be the problem.
Not 100% sure, but I think it could be a context issue. Try this:
function ( id ) {
var ID = document.getElementById;
this.id = id;
this.newvar = ID.call( document, this.id );
...
}
Also, this question may help you — it has a good explanation on context and assigning a var to getElementById Why can't I directly assign document.getElementById to a different function?
I couldnt figure out why my IDs that seemed identical were not. I will leave this question open for anyone to add insight on how to remedy this. I ended up just getting my elements by cell and not by ID.
function SetPriority(cbID, tbID, gridID) {
var cb = document.getElementById(cbID);
if (cb.checked) {
var tb = document.getElementById(tbID);
var grid = document.getElementById(gridID);
var maxv = 0;
if (grid.rows.length > 0) {
for (row = 1; row < grid.rows.length; row++) {
var thisCB = grid.rows[row].cells[5].childNodes[1];
if (thisCB == cb) {
continue;
}
var thisTB = grid.rows[row].cells[6].childNodes[1];
if (thisCB.type == "checkbox") {
if (thisCB.checked) {
if (thisTB.value > maxv)
maxv = thisTB.value;
}
}
}
}
tb.value = parseInt(maxv) + 1;
}
}

getting text from selective nodes in javascript

From below HTML code I want to get all the text except that in 'text_exposed_hide' span elements.
Initially I tried to get the text from span with no class names.
But this method misses the text which is not within any span but just in div.
How can I get the required text. I need this code in pure javascript
<div id="id_4f1664f84649d2c59795040" class="text_exposed_root">
9jfasiklfsa
<span>CT:PFOUXHAOfuAI07mvPC/</span>
<span>NAg==$1ZUlmHC15dwJX8JNEzKxNDGGT</span>
dwL/L1ubjTndn89JL+M6z
<span class="text_exposed_hide">...</span>
<span class="text_exposed_show">
<span>MDmclkBPI/</span>
<span>s4B7R9hJyU9bE7zT10xkJ8vxIpo0quQ</span>
55
</span>
<span class="text_exposed_hide">
<span class="text_exposed_link">
<a onclick="CSS.addClass($("id_4f1664f84649d2c59795040"), "text_exposed");">See More</a>
</span>
</span>
</div
Edit :
I tried removing nodes with class name 'text_exposed_hidden' and then getting text from remaining nodes. Below is the code. But its not working
Control is not entering for loop. Even visibleDiv.removeChild(textExposedHideNodes[0]) is not working. I am running this in Chrome Browser 16.0
//msg is the parent node for the div
visibleDiv = msg.getElementsByClassName("text_exposed_root");
textExposedHideNodes = visibleDiv.getElementsByClassName("text_exposed_hide");
for(var n = 0;n < textExposedHideNodes.legth ; n++ ) {
console.log("Removing");
msg.removeChild(textExposedHideNodes[n]);
}
return visibleDiv.innerText;
This code will collect all text from text nodes who don't have a parent with the class="text_exposed_hide" and put the results in an array.
It does this non-destructively without removing anything:
function getTextFromChildren(parent, skipClass, results) {
var children = parent.childNodes, item;
var re = new RegExp("\\b" + skipClass + "\\b");
for (var i = 0, len = children.length; i < len; i++) {
item = children[i];
// if text node, collect its text
if (item.nodeType == 3) {
results.push(item.nodeValue);
} else if (!item.className || !item.className.match(re)) {
// if it doesn't have a className or it doesn't match
// what we're skipping, then recurse on it to collect from it's children
getTextFromChildren(item, skipClass, results);
}
}
}
var visibleDiv = document.getElementsByClassName("text_exposed_root");
var text = [];
getTextFromChildren(visibleDiv[0], "text_exposed_hide", text);
alert(text);
If you want all the text in one string, you can concatenate it together with:
text = text.join("");
You can see it work here: http://jsfiddle.net/jfriend00/VynKJ/
Here's how it works:
Create an array to put the results in
Find the root that we're going to start with
Call getTextFromChildren() on that root
Get the children objects of that root
Loop through the children
If we find a text node, collect its text into the results array
If we find an element node that either doesn't have a className or who's className doesn't match the one we're ignoring, then call getTextFromChildren() recursively with that element as the new root to gather all text from within that element
Is this what you're looking for?
/*Get Required Text
Desc: Return an array of the text contents of a container identified by the id param
Params:
id = Container DOM object id
*/
function getRequiredText(id)
{
/*Get container, declare child var and return array*/
var el = document.getElementById(id),
child,
rtn = Array();
/*Iterate through childNodes*/
for(var i = 0; i < el.childNodes.length; i++){
/*Define child*/
child = el.childNodes[i]
/*If node isn't #text and doesn't have hidden class*/
if(child.nodeName !="#text" && child.className != "text_exposed_hide")
rtn.push(child.textContent);
}
/*Return results*/
return rtn;
}
This will go through all childNodes, including nested childNodes and place all text into an array. if you want to exclude nested children replace the "if" statement with.
if(child.nodeName !="#text" && child.className != "text_exposed_hide" && child.parentNode == el)
Instead of removing the node, why not set its innertext/html to empty string:
//msg is the parent node for the div
visibleDiv = msg.getElementsByClassName("text_exposed_root");
textExposedHideNodes = visibleDiv.getElementsByClassName("text_exposed_hide");
for(var i = 0;i < textExposedHideNodes.legth ; i++ ) {
//store to temp for later use
textExposedHideNodes[i].txt = textExposedHideNodes[i].innerHTML;
textExposedHideNodes[i].innerHTML = '';
}
return visibleDiv.innerText;

Categories

Resources