I want to get the closest object tag from the currently selected object tag. But it has to be strictly above. Suppose I have the object with id A. How can I get the closest object tag above it? In this case I want to get the object tag with id B. Each div container can contain a object tag or something else.
<div class="message">
<span></span>
</div>
<div class="message">
<object id="C"></object>
</div>
<div class="message">
<object id="B"></object>
</div>
<div class="message">
<span></span>
</div>
<div class="message">
<object id="A"></object>
</div>
<div class="message">
<object id="Z"></object>
</div>
Assuming this is the object with ID A
$(this).closest('.message').prevUntil('.message:has(object)').prev().find('object');
FIDDLE
traverses up to the closest .message then checks previous elements until it finds one that contains an object tag, then it stops, but it stops at the element before that tag, so we call prev to go one step further, and then use find to find the object tag.
Another option:
var objs=$('object').toArray();
$('.message').on('click',function(){
var elem=$(this).children().get(0);
if(objs.indexOf(elem)-1>=0){
console.log(objs[objs.indexOf(elem)-1]);
console.log(objs[objs.indexOf(elem)-1].id);
}
});
You can use prev() to get the previous sibling element. That will get you partway there, but since each 'message' div is not guaranteed to contain an object element you'll need to use prevUntil() or run your own iteration/search.
For instance:
var lastObj = $("#A");
var parent = lastObj.parent();
var previousObject = parent.prevUntil(".message:has(object)").prev().find("object");
Or without prevUntil():
var lastObj = $("#A");
var parent = lastObj.parent();
var previousObject = undefined;
while (parent.length > 0 && ! previousObject) {
parent = parent.prev();
if (parent.find("object").length > 0) {
previousObject = parent.find("object");
}
}
Or as a runnable code snippet (using classes instead of object tags):
$(".object").click(function(){
var myId = this.id;
var prevId = undefined;
var parent = $(this).parent();
var previousObject = undefined;
while (parent.length > 0 && ! previousObject) {
parent = parent.prev();
if (parent.find(".object").length > 0) {
previousObject = parent.find(".object");
prevId = previousObject.attr("id");
}
}
alert("clicked=" + myId + ", previous=" + prevId);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="message">
<span></span>
</div>
<div class="message">
<span class="object" id="C">C</object>
</div>
<div class="message">
<span class="object" id="B">B</object>
</div>
<div class="message">
<span></span>
</div>
<div class="message">
<span class="object" id="A">A</object>
</div>
<div class="message">
<span class="object" id="Z">Z</object>
</div>
Related
How can you replace HTML tag with all tags branching inside using Javascript with other HTML code?
example:
<div class="a">
<div class="sub-a1">
<div class="sub-a12">
</div>
</div>
<div class="sub-a2">
<div class="sub-b">
</div>
</div>
I wanna replace all tags from tag div class 'a' including all sub nodes with another code.
is that's possible?
please help me.
const target = document.querySelector(".a");
target.innerHTML = //place your html here as string
Yes, this is possible. If you want to keep the div.a elements and just change the "subnodes" you have to use innerHTML in stead of outerHTML.
const divs = [...document.getElementsByClassName("a")]; //make a copy of the HTML collection so that they can be removed without being removed in the array
const newElement = "<h1>Replaced Element</h1>"; //this is your replacement element
for (let i = 0; i < divs.length; i++) { // loop through all the divs
divs[i].outerHTML = newElement; // set the outer html for the div to the replacement elemzent
}
You can do with .replaceWith() with a valid HTML code.
function replace() {
var para = document.createElement("P"); // Create a <p> element
para.innerText = "This is a paragraph"; // Insert text
document.querySelector(".a").replaceWith(para);
}
<div class="a">
<div class="sub-a1">
<div class="sub-a12">
<h4>Sample content1</h4>
</div>
</div>
<div class="sub-a2">
<div class="sub-b">
<h4>Sample content2</h4>
</div>
</div>
</div>
<button onclick="replace();"/>Click to Replace</button>
I have:
<div class="f0">
<div class="input-text">
<t>Text</t>
</div>
</div>
var h = 0;
for(h;h<inputstext.length;h++){
var str = 'f' + h;
var currentDiv = document.getElementById(str);
}
How do I get only the input-text elements value that is in f0?
Output should be Text.
Thanks.
You can use the element[property*="val"] to select all elements with property beginning with "val" - in this case, any class that starts with "f", and then select their .input-text children.
Also, you're trying to get elements with id f0, when these divs are marked with class f0.
const inputs = document.querySelectorAll('[class*="f"] .input-text');
for (const element of inputs)
console.log(element.textContent.trim());
<div class="f0">
<div class="input-text">
inside f0
</div>
</div>
<div class="f1">
<div class="input-text">
inside f1
</div>
</div>
I'm trying to retrieve the ID of one element, store it as a variable and then use that ID value to interact with other elements in that section with the same ID.
<div class="mainContent">
<div class="articleContent">
<h1>header1</h1>
<p class="articlePara" id="one">para1</p>
</div>
<div class="articleFooter" id="one" onclick="readMore()">
</div>
</div>
<div class="mainContent">
<div class="articleContent">
<h1>header2</h1>
<p class="articlePara" id="two">para2</p>
</div>
<div class="articleFooter" id="two" onclick="readMore()">
</div>
</div>
And then the JS/jQuery
function readMore() {
var subID = event.target.id;
var newTarget = document.getElementById(subID).getElementsByClassName("articlePara");
alert(newTarget.id);
}
At this point I'm only trying to display the ID of the selected element but it is returning undefined and in most cases people seem to notice that jQuery is getting confused because of the differences between DOM variables and jQuery ones.
jsfiddle: https://jsfiddle.net/dr0f2nu3/
To be completely clear, I want to be able to click on one element, retrieve the ID and then select an element in the family of that clicked element using that ID value.
just remove the getElementsByClassName("articlePara"); in end of the newTarget .already you are call the element with id alert the element of the id is same with target.id
function readMore() {
var subID = event.target.id;
var newTarget = $('[id='+subID+'][class="articlePara"]')
console.log(newTarget.attr('id'));
console.log(newTarget.length);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mainContent">
<div class="articleContent">
<h1>header</h1>
<p class="articlePara" id="one"></p>
</div>
<div class="articleFooter" id="one" onclick="readMore()">click
</div>
</div>
As you have read before, you should keep your id's unique, and you should avoid using onclick in html, but you could do it like this.
With querySelector you get the element and then with parentElement you can retrieve the parent of that element.
function readMore(el) {
var articleFooterId = el.id;
var articlePara = document.querySelector(".articleContent #"+articleFooterId);
var articleContent = articlePara.parentElement;
console.log('articleFooter', articleFooterId);
console.log('articlePara', articlePara);
console.log('articleContent', articleContent);
}
In your html you can return the 'this' object back to the function by doing readMore(this).
<div class="mainContent">
<div class="articleContent">
<h1>header1</h1>
<p class="articlePara" id="one">para1</p>
</div>
<div class="articleFooter" id="one" onclick="readMore(this)">footertext</div>
</div>
<div class="mainContent">
<div class="articleContent">
<h1>header2</h1>
<p class="articlePara" id="two">para2</p>
</div>
<div class="articleFooter" id="two" onclick="readMore(this)">footertext</div>
</div>
jsfiddle
if you're using Jquery:
$(function () {
$('div.articleFooter').click(function () {
var para = $(this).prev().find('p.articlePara').text();
alert('T:' + para);
});
})
$('.articleFooter').click(function() {
var b=subId; //can be any
var a="p[id="+b+"]"+"[class='articlePara']";
$(a).something;
});
You have forgotten to pass in event as parameter in your onclick= call in html.
In your javascript, you need to include event in the parenthesis as well.
window.readMore = function(event) {...}
if you write document.getElementById(subID).getElementsByClassName("articlePara"); That's saying you want to get your clicked element's CHILD elements that have class equal to articlePara . There is none. So you get undefined.
If you want to find all element with a ID one and a class articlePara, it can be done easily with jQuery:
newtarget = $("#one.articlePara");
You can insert a line: debugger; in your onclick handler function to trigger the browser's debugging tool and inspect the values of variables. Then you will know whether you are getting what you want.
Using the following code I was expecting to get an object which contains the sub elements
var MemberDiv=document.getElementById("idProfileMainContainer");
console.log(MemberDiv.length);
Using the above code I get "undefined". I'm confused. I thought it should have an object array that contains all sub elements.
Ultimately I am trying to find the sub <div /> with the <span /> that has "Board Position" in it.
<div id="idContainer8592665" class="fieldContainer simpleTextContainer">
<div class="fieldSubContainer labeledTextContainer">
<div class="fieldLabel">
<span id="FunctionalBlock1_ctl00_ctl00_MemberForm_memberFormRepeater_ctl22_titleLabel" title="Cannot be edited, Administrator access only">Board Position</span>
</div>
<div class="fieldBody">
<span id="FunctionalBlock1_ctl00_ctl00_MemberForm_memberFormRepeater_ctl22_DropDownLabel8592665">Webmaster</span><input name="FunctionalBlock1$ctl00$ctl00$MemberForm$memberFormRepeater$ctl22$ctl03" type="hidden">
</div>
</div>
</div>
The return value of getElementById is not an array, but one node (or none) as you can find on MDN:
Returns a reference to the element by its ID
To get the element you are targetting, you could use this ES6 script:
// Select all div.fieldLabel descendants of #idContainer8592665 and find one that has
// the text content we look for.
var div = Array.from(document.querySelectorAll('#idContainer8592665 div.fieldLabel'))
.find( div => div.textContent.includes('Board Position'));
// Show the text of the div element we found
console.log(div.textContent.trim());
<div id="idContainer8592665" class="fieldContainer simpleTextContainer">
<div class="fieldSubContainer labeledTextContainer">
<div class="fieldLabel">
<span id="FunctionalBlock1_ctl00_ctl00_MemberForm_memberFormRepeater_ctl22_titleLabel" title="Cannot be edited, Administrator access only">Board Position</span>
</div>
<div class="fieldBody">
<span id="FunctionalBlock1_ctl00_ctl00_MemberForm_memberFormRepeater_ctl22_DropDownLabel8592665">Webmaster</span><input name="FunctionalBlock1$ctl00$ctl00$MemberForm$memberFormRepeater$ctl22$ctl03" type="hidden">
</div>
</div>
</div>
In ES5 compatible script it would look like this:
// Select all div.fieldLabel descendants of #idContainer8592665 and find one that has
// the text content we look for.
var parent = document.getElementById('idContainer8592665');
var div = [].filter.call(parent.getElementsByClassName('fieldLabel'),
function (div) {
return div.textContent.indexOf('Board Position') != -1;
}).pop();
// Show the text of the div element we found
console.log(div.textContent.trim());
<div id="idContainer8592665" class="fieldContainer simpleTextContainer">
<div class="fieldSubContainer labeledTextContainer">
<div class="fieldLabel">
<span id="FunctionalBlock1_ctl00_ctl00_MemberForm_memberFormRepeater_ctl22_titleLabel" title="Cannot be edited, Administrator access only">Board Position</span>
</div>
<div class="fieldBody">
<span id="FunctionalBlock1_ctl00_ctl00_MemberForm_memberFormRepeater_ctl22_DropDownLabel8592665">Webmaster</span><input name="FunctionalBlock1$ctl00$ctl00$MemberForm$memberFormRepeater$ctl22$ctl03" type="hidden">
</div>
</div>
</div>
What I've done is get the collection of span elements. I then step through this collection, checking if the textContent is 'Board Position'. If so, I walk back up the DOM tree until I reach a div node. I then print it's class (the only attribute it has in your html) and also, the outerHTML.
If there may be more that one matching element, result should be initialized to [], you should check for .length > 0 instead of == undefined, you should push the element into result result.push(elem) instead of setting it to the elem with result = elem and finally, you should iterate through the results, rather than showing the only single one.
function byId(id){return document.getElementById(id)}
function allByTag(tag,parent){return (parent == undefined ? document : parent).getElementsByTagName(tag)}
// useful for HtmlCollection, NodeList, String types - (array-like objects)
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
window.addEventListener('load', onDocLoaded);
function onDocLoaded(evt)
{
var spans = allByTag('span');
var result=undefined;
forEach(spans, findParentIfMatching);
if (result != undefined)
{
console.log(result.className);
console.log('*******************************');
console.log(result.outerHTML);
}
function findParentIfMatching(elem,index,collection)
{
if (elem.textContent == 'Board Position')
{
while (elem.nodeName != 'DIV')
elem = elem.parentNode;
result = elem;
}
}
}
<div id="idContainer8592665" class="fieldContainer simpleTextContainer">
<div class="fieldSubContainer labeledTextContainer">
<div class="fieldLabel">
<span id="FunctionalBlock1_ctl00_ctl00_MemberForm_memberFormRepeater_ctl22_titleLabel" title="Cannot be edited, Administrator access only">Board Position</span>
</div>
<div class="fieldBody">
<span id="FunctionalBlock1_ctl00_ctl00_MemberForm_memberFormRepeater_ctl22_DropDownLabel8592665">Webmaster</span><input name="FunctionalBlock1$ctl00$ctl00$MemberForm$memberFormRepeater$ctl22$ctl03" type="hidden">
</div>
</div>
</div>
I'm building an online store with javascript shopping cart. However, the script doesn't allow printing only one or two values when displaying cart, but I need to do this.
Here's what the cart looks like:
<div class="simpleCart_items">
<div>
<div class="headerRow">
<div class="item-name">Tuote</div>
<div class="item-price">Hinta</div>
<div class="item-decrement">-</div>
<div class="item-quantity">Määrä</div>
<div class="item-increment">+</div>
<div class="item-total">Yhteensä</div>
<div class="item-remove">Poista</div>
</div>
<div class="itemRow row-0 odd" id="cartItem_SCI-1">
<div class="item-name">Teipit</div>
<div class="item-price">€0.00</div>
<div class="item-decrement"><img src="css/minus.png" alt="minus">
</div>
<div class="item-quantity">3</div>
<div class="item-increment"><img src="css/plus.png" alt="plus">
</div>
<div class="item-total">€0.00</div>
<div class="item-remove"><img src="css/remove.png" alt="Remove">
</div>
</div>
<div class="itemRow row-1 even" id="cartItem_SCI-3">
<div class="item-name">Car Speaker -hajuste</div>
<div class="item-price">€4.00</div>
<div class="item-decrement"><img src="css/minus.png" alt="minus">
</div>
<div class="item-quantity">1</div>
<div class="item-increment"><img src="css/plus.png" alt="plus">
</div>
<div class="item-total">€4.00</div>
<div class="item-remove"><img src="css/remove.png" alt="Remove">
</div>
</div>
<div class="itemRow row-2 odd" id="cartItem_SCI-5">
<div class="item-name">Teipit (Musta hiilikuitu)</div>
<div class="item-price">€0.00</div>
<div class="item-decrement"><img src="css/minus.png" alt="minus">
</div>
<div class="item-quantity">1</div>
<div class="item-increment"><img src="css/plus.png" alt="plus">
</div>
<div class="item-total">€0.00</div>
<div class="item-remove"><img src="css/remove.png" alt="Remove">
</div>
</div>
</div>
</div>
NOTE: The cart is written via javascript so it isn't visible in page source, only in inspect mode of the browser.
So how would I gather the item-name, item-priceand item-quantity?
I've tried this:
var name = $('.item-name');
var price = $('.item-price');
var quantity = $('.item-quantity');
var data = name + price + quantity;
$('#items').html(data);
But this won't actually do anything.
When doing this -> $('.item-name');
You are just capturing the element as object but not the value.
Now that you got your element as object, you need to extract the value and, in this case, your element object is a div so you can try .text() or .html() (to get the text or html inside the div).
(For this situation I will use text() cause you are working just with values and there is nothing related to html)
Try this:
var name = $('.item-name');
var price = $('.item-price');
var quantity = $('.item-quantity');
var data = name.text() + price.text() + quantity.text();
$('#items').html(data);
Better solution:
This will make clickable the div in which you have the product and match the cartItem_SCI pattern.
So, when user clicks any of the elements of your cart, you will get the name, price and quantity values that will be attached to the $('#items') div using append() method instead of html() (because using this will replace the product information each time the user clicks a div)
$(document).ready(function() {
$('div[id^="cartItem_SCI-"]').css({ cursor:'pointer' });
$('div[id^="cartItem_SCI-"]').click(function() {
var name = $(this).find('.item-name');
var price = $(this).find('.item-price');
var quantity = $(this).find('.item-quantity');
var data = name.text() + ' - ' + price.text() + ' - ' + quantity.text();
$('#items').append(data + '<br/>');
});
});
You are just getting a reference to the class, add .html() to get the inner html of the element that the class applied to.
var name = $('.item-name').html();
For one item you can get like this.But since you have multiple items make one object like this .
var item={};
$('.item-name').each(function(){item.name=$(this).html()});
$('.item-price').each(function(){item.price=$(this).html()});
$('.item-quantity').each(function(){item.quantity=$(this).html()});
var data='';
for(var i=0;i<item.length;i++)
{
data+=item[i].name+item[i].price+item[i].quantity;
}
$('#items').html(data);