I have a simple function that traverses up the DOM to get to a span element:
function getAttachmentControlBinding(theNode) {
//Find the <SPAN> tag that has the binding to the attachment control
//The attachment control is needed to be able to determine from which view
do {
//Navigate up to the parent node
theNode = theNode.parentNode;
//Should run into a <SPAN> tag, but if not we need to get out of the loop
} while (theNode.nodeName !== "SPAN" && theNode.nodeName !== '');
//Get the value of the binding attribute from the <SPAN> tag
return theNode.getAttribute("binding");
}
In the JS console, if I look at theNode, I get this:
<span id="svattachmentcontainer_0_1" binding="my:wsAttachmentCreditApplication"
The binding here is what I want the function to return; however I keeping getting an error of illegal return statement if I try to evaluate in the console. If I evaluate theNode.getAttribute("binding") in the console, I get what I want (my:wsAttachmentCreditApplication), but letting the code run jumps to a completely different section of code that would normally run if this function return was successful.
How can I return this value with this function?
Your code works fine
function getAttachmentControlBinding(theNode) {
//Find the <SPAN> tag that has the binding to the attachment control
//The attachment control is needed to be able to determine from which view
do {
//Navigate up to the parent node
theNode = theNode.parentNode;
//Should run into a <SPAN> tag, but if not we need to get out of the loop
} while (theNode.nodeName !== "SPAN" && theNode.nodeName !== '');
//Get the value of the binding attribute from the <SPAN> tag
return theNode.getAttribute("binding");
}
var binding = getAttachmentControlBinding(document.querySelector('.nesteddiv2'));
document.querySelector('.js-result').innerHTML = 'Binding found: ' + binding;
<span id="svattachmentcontainer_0_1" binding="my:wsAttachmentCreditApplication">
<div class="nesteddiv1">
<div class="nesteddiv2"></div>
</div>
</span>
<div class="js-result">aa</div>
Related
I have many of the below 'k-top' div elements, with the same inner div structure, except different unique text in two places, in 'k-in' and in my checkbox id.
<div class="k-top">
<span class="k-icon k-i-expand"></span><-------------- trigger click on this if below text is found
<span class="k-checkbox-wrapper" role="presentation">
<input type="checkbox" tabindex="-1" id="unique TEXT99" class="k-checkbox">
<span class="k-checkbox-label checkbox-span"></span>
</span>
<span class="k-in">unique TEXT99</span></div><- if this text is found in k-in trigger click on elem above
I want to iterate through all my span.k-ins until I find the innerText to match contains of 'unique' for instance, then once unique is found, I want to .click(); on it's sibling element '.k-i-expand' as seen in the mark-up above. I do not want to trigger a .click(); on all .k-i-expand just the specific one that has same parent as where my 'unique text' is found.
Thus far I have tried .closest, I have also tried sibling.parent.. both return null or undefined.. Note, I am not using jQuery.
The below works successfully to click all .k-i-expand - but I need to .click() only the one where k-in innerText contains 'unique'. Ideally I'd use starts with, or contains, but I'd specify the whole word if needed i.e. unique TEXT99
let exp = document.querySelectorAll('.k-i-expand');
let i;
for (i = 0; i < exp.length; ++i) {
exp[i].click();
};
More previous attempts can be seen here: how to run a .click on elems parent sibling selector?
I created a recursive function which checks all it's Siblings until it finds one with the specified innerHTML. If it does not find one, it does nothing:
function checkSibling(node) {
if (node.innerHTML == "unique TEXT99") {
return true;
} else if (node.nextSibling) {
return checkSibling(node.nextSibling);
} else {
return false;
}
}
async function clickOnNode() {
let exp = document.querySelectorAll(".k-i-expand");
for await (const node of exp) {
const hasText = await checkSibling(node);
if (hasText) {
console.log("Result: ", hasText);
node.click();
}
}
}
clickOnNode();
I also created a codepen with the code for you to play around. I guess the innerHTML check could be improved via a Regex.
Have you tried iterating over the .k-top elements and looking into each one to find your .k-in?
const expandItemsContaining = (text) => {
// Let's get all the .k-top divs
const kTops = document.querySelectorAll('.k-top');
// And peek into each and every one of them
kTops.forEach(kTop => {
// First we check whether there is a .k-in containing your text
const kIn = kTop.querySelector('.k-in');
const shouldClick = kIn && kIn.innerText && kIn.innerText.indexOf(text) !== -1;
// And if there is one we find the .k-i-expand and click it
if (shouldClick) {
const kExpand = kTop.querySelector('.k-i-expand');
if (kExpand) {
kExpand.click();
}
}
})
}
I would like to change my icon from expand_more to expand_less in following code
<li class="dropdown-bt" onclick="dropdown('content');">
<a>dropdown-content <i class="material-icons">expand_more</i></a>
</li>
I am going to use same code multiple times so it would be better to using function multiple times. I thought of using ID for every piece of code but it would be to hectic. So I want to write single function do it but I don't know how, so please help.
Just pass an object event as a parameter, say e to your dropdown() and use the textContent property to retrieve the current element content, check it's value and replace the content with another text content like this:
var btn = document.getElementById("dropdownBt");
function dropdown(e) {
var innerText = e.target.children[0];
if(innerText.textContent == "expand_more") {
innerText.textContent = "expand_less";
} else {
innerText.textContent = "expand_more";
}
}
btn.addEventListener('click', dropdown);
<li class="dropdown-bt" id="dropdownBt"><a>dropdown-content <i class="material-icons">expand_more</i></a></li>
I try to write a script based on JavaScript for replacing the current selected anchor element with it's inner HTML.
You can also find a simple running example in JSFiddle. To run the example, click on the first link, and the click the button.
So, for example, if I have the following HTML:
<p>
Wawef awef <em>replace</em> <strong>me</strong>
falwkefi4hjtinyoh gf waf eerngl nregsl ngsekdng selrgnlrekg slekngs ekgnselrg nselrg
<a href="http://www.anothersite.com/>replace me</a> klserng sreig klrewr
</p>
and I like when I click on some of the two anchors to remove the anchor with it's inner HTML. This mean, that if I click on the first anchor element, and click the appropriate button to replace the anchor the result should be like that:
<p>
Wawef awef <em>replace</em> <strong>me</strong> falwkefi4hjtinyoh gf waf eerngl
nregsl ngsekdng selrgnlrekg slekngs ekgnselrg nselrg <a href="http://www.anothersite.com/>replace me</a>
klserng sreig klrewr
</p>
My JavaScript code for this functionality is the following:
// Start tracking the click event on the document
document.addEventListener(
'click',
function(event)
{
// If right click, return
if(event.button == 2)
{
return;
}
// Get the current clicked document element
var link = event.target;
while(link && !(link instanceof HTMLAnchorElement))
{
link = link.parentNode;
}
// Get the element with ID wpf-remove-element-now
var clickedLink = document.getElementById("wpf-remove-element-now");
// If the element exists
if(clickedLink !== null)
{
// By executing this code, I am ensuring that I have only
// one anchor element in my document with this ID
// Remove the id attribute
clickedLink.removeAttribute('id');
}
// If ther is no link element
if(!link)
{
// Disable my "unlink" button
editor.commands.customunlinkcmd.disable();
// and return
return;
}
event.preventDefault();
event.stopPropagation();
// If the user has clickde on an anchor element then
// enable my "unlink" button in order to allow him to
// to replace the link if he like to.
editor.commands.customunlinkcmd.enable();
// Set the id attribute of the current selected anchor
// element to wpf-remove-element-now
link.setAttribute('id', 'wpf-remove-element-now');
}
);
var $unlink_button = document.getElementById('unlink');
$unlink_button.addEventListener(
'click',
function(event)
{
// Get the element with ID wpf-remove-element-now
var link = document.getElementById("wpf-remove-element-now");
// Create a new text node that contains the link inner HTML
var text = document.createTextNode(link.innerHTML);
// Make the replacement
link.parentNode.replaceChild(text, link);
}
);
Everything until now is correct, appart of the replacement of the link. I have try the above code, but the result I get is like the following one:
Wawef awef <em>replace</em> <strong>me</strong> falwkefi4hjtinyoh gf waf eerngl
nregsl ngsekdng selrgnlrekg slekngs ekgnselrg nselrg replace me klserng sreig klrewr
I mean the anchor is replaced with the text form of the inner HTML and not with the HTML form of the inner HTML.
So the question is, how can I do this kind of replacement.
You're creating a text node, so whatever you put in it will be interpreted as text. Instead, since you have the replacement tags predefined, you should create actual DOM elements to replace it with. Something like this could work: JSFiddle
var em_elem = document.createElement('em');
em_elem.appendChild(document.createTextNode("replace"));
var strong_elem = document.createElement('strong');
strong_elem.appendChild(document.createTextNode("me"));
var container_span = document.createElement('span');
container_span.appendChild(em_elem);
container_span.appendChild(strong_elem);
// Make the replacement
link.parentNode.replaceChild(container_span, link);
The answer was much simpler that I thought. I placed the solution below for anybody that need an equivalent solution :) :
$unlink_button.addEventListener(
'click',
function(event)
{
// Get the element with ID wpf-remove-element-now
var link = document.getElementById("wpf-remove-element-now");
// By this code you replace the link outeHTML (the link itself) with
// the link innerHTML (anything inside the link)
link.outerHTML = link.innerHTML;
}
);
Here you can find the running solution : JSFiddle
Note: The inspiration for this solution found in the web page.
I must have made a mistake somewhere so the document.getElementsByClassName().innerHTML is always returning undefined.
First i generate the <li> via javascript :
$('#list').append('<li class="box"><img class="picture" src="images/HotPromo/tagPhoto1.png"/><p class="name"><b>Name</b></p><p class="address">Address</p><p class="hidden"></p></li>');
Note that in the most right i have a <p> element with hidden class. I use this to get the id which i dont want to show to my users.
And this is the jQuery to generate the data on those <li> :
$(".box").each(function () {
var name, address, picture, id = "";
if (i < result.length) {
name = result[i].name;
address = result[i].address;
picture = result[i].boxpicture;
id = result[i].mallid;
}
$(this).find(".name").html(name);
$(this).find(".address").html(address);
$(this).find(".picture").attr("src", picture);
$(this).find(".hidden").html(id);
i++;
});
I have tried to check the data, and its working fine.
Now, lets say i want to alert the hidden id <p> when user clicks one of those <li class="box"> that i generated above:
$(".box").click(function () {
alert(document.getElementsByClassName('hidden').innerHTML);
});
However this alert always returning "undifined".
document.getElementsByClassName() returns a nodeList, not an element!
So it should be :
document.getElementsByClassName('hidden')[0].innerHTML
and as you probably have more .hidden elements, and only want the one inside the current .box (which would be this in the event handler)
this.getElementsByClassName('hidden')[0].innerHTML
but why not jQuery
$(".box").click(function(){
alert( $('.hidden', this).html() );
});
How can I get the text value from an elements's child?
Say I have this code on a page:
<div class='geshitop'>
[ CODE ] [ PLAIN-TEXT ]
</div>
<div class='geshimain'>
<pre><div class="text" style="font-family:monospace;">Code goes here...</div></pre>
</div>
The function copy():
<script type="text/javascript">
function copy() {
var text = this.parent.getElementsByName("text");
var code = text[0].value;
var popup = window.open("", "window", "resizeable,width=400,height=300");
popup.document.write("<textarea name='code' cols='40' rows='15'></textarea>");
popup.code.value = code;
}
How would I go about getting that child's data: the <div class "text">. How can I get that from the parent?
I'm still having problems. If there is two codeboxes on one page, then it does not work. Remember, I am unable to use ID's. It must be classes.
If I was able to use jQuery this would be easy.
Get a reference to the node you want to retrieve text from and try:
someNode.firstChild.nodeValue
When you have a node like this:
<span>Here is some text</span>
You're actually looking at two nodes, a span node which has a text node child. In DOM, that text node child's nodeValue is "Here is some text"
put an ID on the tag you want to get its data from.
this way will only grab the first child of the div node:
function copy(){
var text = document.getElementById( "YOU_TAG_NAME" ).firstChild;
//do stuff
}
this will grab all of the data in the node, but don't do this unless you have control over what goes into that div tag:
function copy(){
var text = document.getElementById( "YOU_TAG_NAME" ).innerHtml;
//do stuff
}
To clarify: Are you trying to get the css from the "text" class to display?
Just a thought, you could try using id attributes to get what you need.
Try this:
Change your HTML slightly. The "javascript:" prefix isn't necessary inside an onclick handler. Also, pass a reference of "this" to your copy function:
<div class='geshitop'>
[ CODE ] [ PLAIN-TEXT ]
</div>
<div class='geshimain'>
<pre><div class="text" style="font-family:monospace;">Code goes here...</div></pre>
</div>
Having done that, alter your copy function to accept the new parameter. Then you just have to locate the correct node. From the question, I think you are looking for the next <div class="text"> that is a child of the <div class="geshimain"> that is the next sibling of the parent node that contains the link that was clicked. This function should accomplish that:
function copy(node) {
node = node.parentNode; // <div class="geshitop">
// Loop over adjacent siblings, looking for the next geshimain.
while (node.nextSibling) {
node = node.nextSibling;
if (node.nodeName === 'DIV' && node.className === 'geshimain') {
break;
}
}
if (!node) {
throw new Error("Could not locate geshimain");
}
// Locate the <div class="text">
node = (function () {
var divs = node.getElementsByTagName('div');
for (var x = 0; x < divs.length; x++) {
if (divs[x].className === 'text') {
return divs[x];
}
}
return null;
}());
if (!node) {
throw new Error("Could not locate text");
}
node =
'<textarea name="code" cols="40" rows="15">' + node.innerHTML + "</textarea>";
popup = window.open("", "window", "resizeable,width=400,height=300");
popup.document.write(node);
popup.document.close();
}
Good luck!