Please have a look to this DOM Tree...
<div>
<div>
<span> Home1 </span>
</div>
<span> Home2 </span>
<span> Home3 </span>
</div>
Now suppose I have a scenario where somehow I got the innerHTML of first span Home1.
Is it possible to get the element span and its parent div by using only this (Home1) information.
Here is what you want.
Here is html:
<label>opal fruits</label>
Here is jQuery:
$("label:contains(opal fruits)")
var mySpans = document.getElementsByTagName(span);
for(var i=0;i<mySpans.length;i++){
if(mySpans[i].innerHTML == 'Home1'){
var parent = mySpans[i].parentNode;
break;
}
}
this selects the parent of span having innerHTML Home1
There are so many ways to get info about your elements.
Using the innerHTML as an identifier is not a good solution.
You probably need some sort of event to that makes you search for that "Menu1"
So here is a click handler that works also on other events that give you information about what you have clicked.
function handler(e){
var txt='You clicked on a '+e.target.nodeName+'\n';
txt+='The innerHTML is '+e.target.innerHTML+'\n';
txt+='The text is '+e.target.textContent+'\n';
txt+='The parentNode is '+e.target.parentNode.nodeName+'\n';
alert(txt)
}
document.addEventListener('click',handler,false)
DEMO
function handler(e) {
var txt = 'You clicked on a ' + e.target.nodeName + '\n';
txt += 'The innerHTML is ' + e.target.innerHTML + '\n';
txt += 'The text is ' + e.target.textContent + '\n';
txt += 'The parentNode is ' + e.target.parentNode.nodeName + '\n';
alert(txt)
}
document.addEventListener('click', handler, false)
<div>
<div><span>Menu1</span></div><span>Menu2</span><span>Menu3</span>
</div>
If you want that your script searches for that "Menu1" you should consider adding that "Menu1" as an attribute on the span or parentNode.
<div id="Menu1">
<span>Home1</span>
</div>
and then call
document.getElementById('Menu1');
Which is very fast.
innerHTML method return String type. It don't associate with DOM tree.
You can use jQuery and it contains selector(fiddle):
$(":contains('Home1')").last()
var divRef; //Reference to the container of your div / span elements
var spans = divRef.getElementsByTagName("span");
var spanContainer;
for(var i = 0; i < spans.length; i++){
if(spans[i].innerHtml == "Home 1"){
spanContainer = spans[i].parentNode;
break;
}
}
if(spanContainer){
alert("Element has been found!");
}
function findNodeByInnerHTML(nodelist, innerHTML){
for(let ii = 0; ii < nodelist.length; ii++){
if(nodelist[ii].innerHTML === innerHTML)
return nodelist[ii]
}
}
let span = findNodeByInnerHTML(document.querySelectorAll('span'), 'home')
Related
I have a div in which I render through javascript inputs and text dynamically. I am trying to capture the text of this div (both input values and text).
My first step if to capture the parent div:
let answerWrapper = document.getElementById("typing-answer-wrapper");
The issue now is that using the innerHTML will give me the whole html string with the given tags and using the inerText will give me the text, excluding the tags.
In the following case scenario:
the console inspect is:
What is the way to capture: $2.4 if the inputs have 2 and 4
and $null.null if the inputs are blank.
Any help is welcome
You could iterate over all of the element's child nodes and concatenate their wholeText or value else 'null'. For inputs the wholeText will be undefined. If they have no value we'll return 'null'. Be aware that spaces and line-breaks will also be included so you may want to strip these later (or skip them in the loop) but as a proof of concept see the following example:
var typingAnswerWrapper = document.getElementById("typing-answer-wrapper");
function getVal(){
var nodeList = typingAnswerWrapper.childNodes;
var str = "";
for (var i = 0; i < nodeList.length; i++) {
var item = nodeList[i];
str+=(item.wholeText || item.value || "null");
}
console.log(str);
}
getVal();
//added a delegated change event for demo purposes:
typingAnswerWrapper.addEventListener('change', function(e){
if(e.target.matches("input")){
getVal();
}
});
<div id="typing-answer-wrapper">$<input type="number" value=""/>.<input type="number" value="" />
</div>
Here's how you could do it :
function getValue() {
var parent = document.getElementsByClassName('typing-answer-wrapper')[0],
text = [];
const children = [...parent.getElementsByTagName('input')];
children.forEach((child) => {
if (child.value == '')
text.push("null")
else
text.push(child.value)
});
if (text[0] != "null" && text[1] == "null") text[1] = "00";
document.getElementById('value').innerHTML = "$" + text[0] + "." + text[1]
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<div class="typing-answer-wrapper">
$
<input type="number"> .
<input type="number">
</div>
<button onclick="getValue()">get value</button>
<div id="value"></div>
You can fetch input feild values by their respective ids $('#input_feild_1').val() will give the first feild value and similarly $('#input_feild_2').val() for second feild and contruct use them to construct whatever as u wish. As in your case this should work
value_1 = $('#input_feild_1_id').val()
value_2 = $('#input_feild_2_id').val()
you need something like "$ + value_1 + . + value_2"
I have the following HTML string:
<div><p>Hello <b>how are</b> you?</div>
I would like to loop the HTML string DOM and wrap each word with a span tag and the word number as id so result will be like this:
<div><p><span id="word-1">Hello</span> <b><span id="word-2">how</span> <span id="word-3">are</span></b> <span id="word-4">you?</span></div>
I've tried to use the JQuery method $.parseHTML but no luck to count the words because DOM node value can contain more than one word in it..
In addition, if inside the word there is inline tags such <b> / <i> so from DOM point of view each tag has a different node value even when its the same word)
Any idea how to solve this issue? how to count words inside a HTML DOM string?
Thanks
Try this.
HTML
<div id="content">
<div><p>Hello <b>how are</b> you?</div>
</div>
Script
var textNodes = $("#content *").contents().filter(function() {
return this.nodeType === 3;
});
var counter = 1;
for(var i = 0;i<textNodes.length;i++)
{
var val = $(textNodes).eq(i).text();
var words = val.split(" ");
var final = "";
for(var j = 0;j<words.length;j++)
{
if(words[j].trim() != "")
{
final += "<span id='"+ counter +"'>"+ words[j] +" </span>";
counter++;
}
}
$($(textNodes)[i]).replaceWith(final);
}
Jsfiddle Link
As of my understanding of your question this should work.
var allText = $("body").text().replace(/<[^>]*>/g, "");
var words = allText.split(' ');
for(var i=0;i<words.length;i++)
{
$(div).append("<span id = 'word-'"+i+">"+words[i]+"</span>")
}
I have this array:
var names = [
"Name1",
"Name2",
"Name3"
];
I converted this to Unorder List for HTML:
for(i = 0; i < names.Length; i++){
text += "<li>" + names[i] + "</li>";
}
text += "</ul>";
document.getElementById("choices").innerHTML = text;
Now, I got this:
Name1
Name2
Name3
And I am happy with the result. But now I want if someone click on Name2 so it alert me the index of the value. What I want is it should in Mobile App (Cordova) so that when user click on List Item it will show details on other activity (Some other page).
PS:
I checked:
var index = $( "li" ).index( this );
and
var index = $("ul li.active").index();
But seems like these are not made for me.
May be I should Dynamically assign ID's to each <li> item? What should I do now?
You can directly get index using index method.
$("li").click(function () {
alert($(this).index());
});
If you have multiple ul elements on page and you want to bind click event to some specific element you can do this.
To bind click on element by id
$("#YourUlId li").click(function () {
alert($(this).index());
});
To bind click event by class
$(".YourUlClass li").click(function () {
alert($(this).index());
});
$( "li" ).index will return elements index with respect to all li elements in DOM.
You need to use .index() with jquery object of clicked element. It will return the elements index in its parent container:
var index = $(this).index();
Pass the id dynamically in for loop
for(i = 0; i < names.Length; i++){
text += "<li id="+i+">" + names[i] + "</li>";
}
assign the click event, u will get the id by below code
$(li).click(function(){
alert($(this).attr("id"));
});
use this for getting the current element
<ul>
<li>Male</li>
<li>Female</li>
</ul>
<script>
$("li").click(function(){
alert($(this).index())
})
</script>
See below working snippet
var names = [
"Name1",
"Name2",
"Name3"
];
var text='<ul>';
for(i = 0; i < names.length; i++){
text += "<li>" + names[i] + "</li>";
}
text += "</ul>";
document.getElementById("choices").innerHTML = text;
$('li').on('click',function(){
alert($(this).index())
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="choices"></div>
Using native javascript, you can just create a function that will alert the index of the array value corresponding the li element value/id
First you attach the function on the choices
document.getElementById('Name2').setAttribute('onclick','checkIndex(this)');
then loop through the array and hunt for the matching array value
function checkIndex(item){
for(i=0;i<names.length;i++){
if(names[i] == item.innerHTML){ //or item.id
alert(names.indexOf(names[i]));
}
}
}
I would handle it in a declarative way, using html data-attributes, handled by jquery. see here
Here's an example.
var names = ["jack", "mary", "lou", "andrew"];
var text = "<ul>";
for (var i = 0; i < names.length; i++) {
text += "<li data-id='" + i + "'>" + names[i] + "</li>";
}
text += "</ul>";
document.getElementById("choices").innerHTML = text;
$("li").click(function(e){
alert($(this).data("id"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
My Choice
<div id="choices"></div>
</body>
</html>
Of course you can change data-id with whatever you want, or either add other attributes (data-page ? data-txt ? ) and handle all this in a proper way.
Also, dynamically assign ids to your list is a possibility, but I prefer this because I find it more flexible.
I have created a html like this:
<body onload = callAlert();loaded()>
<ul id="thelist">
<div id = "lst"></div>
</ul>
</div>
</body>
The callAlert() is here:
function callAlert()
{
listRows = prompt("how many list row you want??");
var listText = "List Number";
for(var i = 0;i < listRows; i++)
{
if(i%2==0)
{
listText = listText +i+'<p style="background-color:#EEEEEE" id = "listNum' + i + '" onclick = itemclicked(id)>';
}
else
{
listText = listText + i+ '<p id = "listNum' + i + '" onclick = itemclicked(id)>';
}
listText = listText + i;
//document.getElementById("lst").innerHTML = listText+i+'5';
}
document.getElementById("lst").innerHTML = listText+i;
}
Inside callAlert(), I have created id runtime inside the <p> tag and at last of for loop, I have set the paragraph like this. document.getElementById("lst").innerHTML = listText+i;
Now I am confuse when listItem is clicked then how to access the value of the selected item.
I am using this:
function itemclicked(id)
{
alert("clicked at :"+id);
var pElement = document.getElementById(id).value;
alert("value of this is: "+pElement);
}
But getting value as undefined.
Any help would be grateful.
try onclick = itemclicked(this.id) instead of onclick = 'itemclicked(id)'
Dude, you should really work on you CodingStyle. Also, write simple, clean code.
First, the html-code should simply look like this:
<body onload="callAlert();loaded();">
<ul id="thelist"></ul>
</body>
No div or anything like this. ul and ol shall be used in combination with li only.
Also, you should always close the html-tags in the right order. Otherwise, like in your examle, you have different nubers of opening and closing-tags. (the closing div in the 5th line of your html-example doesn't refer to a opening div-tag)...
And here comes the fixed code:
<script type="text/javascript">
function callAlert() {
var rows = prompt('Please type in the number of required rows');
var listCode = '';
for (var i = 0; i < rows; i++) {
var listID = 'list_' + i.toString();
if (i % 2 === 0) {
listCode += '<li style="background-color:#EEEEEE" id="' + listID + '" onclick="itemClicked(this.id);">listItem# ' + i + '</li>';
}
else {
listCode += '<li id="' + listID + '" onclick="itemClicked(this.id);">listItem# ' + i + '</li>';
}
}
document.getElementById('thelist').innerHTML = listCode;
}
function itemClicked(id) {
var pElement = document.getElementById(id).innerHTML;
alert("Clicked: " + id + '\nValue: ' + pElement);
}
</script>
You can watch a working sample in this fiddle.
The problems were:
You have to commit the id of the clicked item using this.id like #Varada already mentioned.
Before that, you have to build a working id, parsing numbers to strings using .toString()
You really did write kind of messy code. What was supposed to result wasn't a list, it was various div-containers wrapped inside a ul-tag. Oh my.
BTW: Never ever check if sth. is 0 using the ==-operator. Better always use the ===-operator. Read about the problem here
BTW++: I don't know what value you wanted to read in your itemClicked()-function. I didn't test if it would read the innerHTML but generally, you can only read information from where information was written to before. In this sample, value should be empty i guess..
Hope i didn't forget about anything. The Code works right now as you can see. If you've got any further questions, just ask.
Cheers!
You can pass only the var i and search the id after like this:
Your p constructor dymanic with passing only i
<p id = "listNum' + i + '" onclick = itemclicked(' + i + ')>
function
function itemclicked(id)
{
id='listNum'+i;
alert("clicked at :"+id);
var pElement = document.getElementById(id).value;
alert("value of this is: "+pElement);
}
is what you want?
I am not sure but shouldn't the onclick function be wrapped with double quotes like so:
You have this
onclick = itemclicked(id)>'
And it should be this
onclick = "itemclicked(id)">'
You have to modify your itemclicked function to retrieve the "value" of your p element.
function itemclicked( id ) {
alert( "clicked at :" + id );
var el = document.getElementById( id );
// depending on the browser one of these will work
var pElement = el.contentText || el.innerText;
alert( "value of this is: " + pElement );
}
demo here
I am trying to make a recursive function in Javascript which should basically give me HTML like BELOW
<li><a class="expand">+</a> <span class="treeNodeInner"><a id="7471">Ringtones</a>
<ul>
<li><span class="treeNodeInner"><a id="7995">Top Tones</a></span></li>
<li><span class="treeNodeInner"><a id="8642">Country</a></span></li>
<li><span class="treeNodeInner"><a id="8640">Rock</a></span></li>
</ul>
</span></li>
I am using the below function to make the above html using javascript.
Its basically a tree view were we will have nodes and sub nodes kind of thing.
I am struggling the achieve the above HTML structure through below function, please advise modifications with the below function
function GenerateNodes(categItem) {
var parentNode = "<li>"; //parent li
if (categItem.SubCategory != null && categItem.SubCategory != undefined && categItem.SubCategory.Count > 0) {
parentNode = "<li><a class='expand'>+</a>";
}
parentNode += "<input type='radio' name='category' /><span class='treeNodeInner'><a id='" + categItem.ID + "'>" + categItem.name + "</a> "; //need to close the span
if (categItem.SubCategory != null && categItem.SubCategory != undefined && categItem.SubCategory.Count > 0) {
var subNode = "<span><ul>";
for (var index = 0; index < categItem.SubCategory.Count; index++) {
subNode += GenerateNodes(categItem.SubCategory[index]);
subNode += "</ul></span>"
}
parentNode += subNode
}
parentNode += "</span></li>"
}
Thanks
Simply looking at the code, I found out that you are not inserting the new li in your html. I'm not sure if you manage this somewhere out of your code. I'd copied your code and do some debug on it. Then I try to add the li on the html using some code. See code below:
//Insert this after parentNode += "</span></li>";
var newDiv = document.createElement('div');
newDiv.innerHTML = parentNode;
categItem.appendChild(newDiv.childNodes[0]);
//I assume that categItem is the id of the container as your sample html code
//above is not clear to me. So I did using sample html below
<div id="liContainer">
</div>
See this jsfiddle how the above code work. I know this is not exactly what you want, but I hope you can get some idea from this.