I have an html code:
<div class="listing_detail col-md-4 propertyprice_display"><strong>Price:</strong>
<span class="price_label price_label_before">USD </span> UGS 6,000
<span class="price_label">per month</span></div>
Price:
UGS 6,000
per month
That is displayed as Price: USD UGS 6,000 per month
I am wondering if its actually possible to remove UGS if the span price_label price_label_before if not empty. If empty, UGS should not be removed using jQuery?
$(document).ready(function(){
var spanText = $('.price_label_before').text().trim();
if(spanText !== null){
var nHTML = $('.propertyprice_display').html();
nHTML = nHTML.replace('UGS','');
$('.propertyprice_display').html(nHTML)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="listing_detail col-md-4 propertyprice_display"><strong>Price:</strong>
<span class="price_label price_label_before">USD </span> UGS 6,000
<span class="price_label">per month</span></div>
<div class="listing_detail col-md-4 propertyprice_display"><strong>Price:</strong>
<span class="price_label price_label_before"> </span> UGS 7,000
<span class="price_label">per month</span></div>
Your html
<div class="listing_detail col-md-4"><strong>Price:</strong>
<div class='emptyclass'>
<span class="price_label price_label_before"> </span> UGS 6,000
<span class="price_label">per month</span></div>
</div>
Your JS
$(document).ready(function(){
if($('.price_label_before').html().trim()=="")// check if span is empty
{
$('.emptyclass').html('');//if yes then emtpty div
}
else
{
//your else defination
}
});
The simplest thing to do would be to wrap the text that may need to be removed in its own span element for easy removal, but assuming that you need to keep the HTML structure as is, you can access the plain text that is not wrapped by extracting a DOM node reference from the JQuery wrapped set of elements when needed.
Please see the comments in the code below for explanations:
// Just passing a function to the JQuery shortcut identifier: $ is the same
// thing as: $(document).ready(function()...
$(function() {
// Get reference to the element to check:
var $spanToCheck = $(".price_label.price_label_before");
// Check the element's text:
if ($spanToCheck.text() !== "") {
// Get reference to the text node that comes after the span. Note the [0] which
// extracts an element from the JQuery wrapped set and returns a regular DOM node:
let nodeToFix = $(".price_label.price_label_before")[0].nextSibling;
// Correct the node value of the node
nodeToFix.nodeValue = nodeToFix.nodeValue.replace("UGS", "");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="listing_detail col-md-4"><strong>Price:</strong>
<span class="price_label price_label_before">USD </span> UGS 6,000
<span class="price_label">per month</span></div>
<div class="listing_detail col-md-4"><strong>Area:</strong>
<span class="">10sqm </span>
</div>
You can use this snippet to achieve what you want:
$(document).ready(function(){
var spanText = $('.price_label.price_label_before').text().trim();
if(spanText !== ''){
var nHTML = $('.listing_detail').html();
nHTML = nHTML.replace('UGS','');
$('.listing_detail').html(nHTML)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="listing_detail col-md-4"><strong>Price:</strong>
<span class="price_label price_label_before">USD </span> UGS 6,000
<span class="price_label">per month</span></div>
Related
I am trying to get an span element which has a class of main-tag inside a nested div. But i don't want to get that element through querySelector as there are many elements in my html file with the same class and i don't intend to use IDs for that.
I know i am making some mistake in my recursive function. That's why this code is not working.
So for this i'm recursively calling a function to get the desired element. But undefined is returned by found variable.
function getElem(cell, name) {
let found;
if (cell.classList.contains(name)) return cell;
else if (cell.children.length === 0) return null;
else {
found = Array.from(cell.children).find((element) =>
element.classList.contains(name)
);
if (found === undefined) {
Array.from(cell.children).forEach((element) => {
found = getElem(element, name);
});
} else return found;
}
}
console.log(getElem(document.getElementById("block-one"), "main-tag"));
<div id="block-one">
<div class="something-one">
<span class="something-two">Hello</div>
<span class="abc">not found</div>
</div>
<div class="here">
<span class="main-tag">Yes, i am here</div>
<span class="bogus-tag">never find out</div>
</div>
</div>
Your markup is using </div> where </span> is expected.
You can use full CSS selectors with querySelector. So for instance, to find the first element with the class main-tag inside the element with id="block-one", you can do this:
const element = document.querySelector("#block-one .main-tag");
Live Example:
console.log(document.querySelector("#block-one .main-tag"));
<div id="block-one">
<div class="something-one">
<span class="something-two">Hello</span>
<span class="abc">not found</span>
</div>
<div class="here">
<span class="main-tag">Yes, i am here</span>
<span class="bogus-tag">never find out</span>
</div>
</div>
Or alternatively, you can call querySelector on an element to only look at its descendants:
const element = document.getElementById("block-one").querySelector(".main-tag");
Live Example:
console.log(document.getElementById("block-one").querySelector(".main-tag"));
<div id="block-one">
<div class="something-one">
<span class="something-two">Hello</span>
<span class="abc">not found</span>
</div>
<div class="here">
<span class="main-tag">Yes, i am here</span>
<span class="bogus-tag">never find out</span>
</div>
</div>
A key difference between those is that the second one will throw an error if there is no id="block-one" element; the first will just return null. You could fix that using the newish optional chaining operator:
const element = document.getElementById("block-one")?.querySelector(".main-tag");
element will be either A) The matching element if there is one; B) null if there's an id="block-one" element but there are no .main-tag elements in it; or C) undefined if there is no id="block-one" element at all. (Even though document.getElementById returns null when it doesn't find something, the optional chaining operator results in undefined when its left-hand operand is either undefined or null.)
Or just use the document.querySelector option (the first one above), which gives you the matching element or null.
You don't seem to want this from your HTML, but: If you want to allow for the possibility the element itself has the class (getElem seems to allow for that possibility), you can use a group selector:
const element = document.querySelector("#block-one.main-tag, #block-one .main-tag");
Live Example:
console.log(document.querySelector("#block-one.main-tag, #block-one .main-tag"));
<div id="block-one" class="main-tag">
<div class="something-one">
<span class="something-two">Hello</span>
<span class="abc">not found</span>
</div>
<div class="here">
<span class="main-tag">Yes, i am here</span>
<span class="bogus-tag">never find out</span>
</div>
</div>
That works because the first member of the group, #block-one.main-tag (without a space) only matches the id="block-one" element if it has the class. If block-one doesn't have the class but one of its descendants does, that's found by the other member of the group, #block-one .main-tag (with the space). If the block-one element has the class and one of its descendants does, the block-one element is the one found, since it's first in document order (a parent is before its children in document order).
Your HTML is invalid.
When fixed, you can get the span using selectors directly
console.log(document.querySelector("#block-one > div.here > span.main-tag").textContent)
<div id="block-one">
<div class="something-one">
<span class="something-two">Hello</span>
<span class="abc">not found</span>
</div>
<div class="here">
<span class="main-tag">Yes, I am here</span>
<span class="bogus-tag">never find out</span>
</div>
</div>
I'm trying to only show class="important" whenever certain text/products like 'KR-KJSC-MICROBIT' and 'KR-KJSC-D' are on the page. When those texts are not on the page then this element should be hidden. Can anyone please assist me with this?
<div class="important">SHOW IF CERTAIN PRODUCTS ARE IN THE CART/THANK YOU PAGE</div>
<div class="cart-line-product-info>
<span class="cart-product-code">
<a class="product-code">Code: KR0KJSC-MICROBIT</a>
</span>
</div>
<div class="cart-line-product-info>
<span class="cart-product-code">
<a class="product-code">Code: KR-KJSC-D</a>
</span>
</div>
You can set a variable with the specific words you want to match.
Get html elements.
Iterates throught the product codes (anchors).
If words array includes the textContent of an anchor element, then display the importants elements:
let words = ['KR0KJSC-MICROBIT', 'KR-KJSC-D']
let anchors = document.querySelectorAll(".product-code")
let importants = document.querySelectorAll(".important");
for(let i = 0; i < anchors.length; i++){
if(words.includes(anchors[i].textContent.replace('Code: ', ''))){
importants.forEach(x => x.style.display = 'block')
} else {
importants.forEach(x => x.style.display = 'none')
}
}
<div class="important">SHOW IF CERTAIN PRODUCTS ARE IN THE CART/THANK YOU PAGE</div>
<div class="cart-line-product-info">
<span class="cart-product-code">
<a class="product-code">Code: KR0KJSC-MICROBIT</a>
</span>
</div>
<div class="cart-line-product-info">
<span class="cart-product-code">
<a class="product-code">Code: KR-KJSC-D</a>
</span>
</div>
Here is a way to do it. Not really the best solution but will work if you add the js script at end of page.
const codeElements = document.querySelectorAll(".product-code");
let codes = []
codeElements.forEach( element => codes.push(element.innerHTML))
if(!codes.includes("Code: KR-KJSC-D")) {
document.querySelector(".important").style.display = "none"
}
<div class="important">SHOW IF CERTAIN PRODUCTS ARE IN THE CART/THANK YOU PAGE</div>
<div class="cart-line-product-info>
<span class="cart-product-code">
<a class="product-code">Code: KR0KJSC-MICROBIT</a>
</span>
</div>
<div class="cart-line-product-info>
<span class="cart-product-code">
<a class="product-code">Code: KR-KJSC-D</a>
</span>
</div>
let pageSource = document.documentElement.innerHTML
// regex match for target strings against page source
if(pageSource.match(/KR0KJSC-MICROBIT|KR-KJSC-D/g)){
$('.important').show()
}
I want to look for the span element _fieldName and if it is followed by a .mandatory span element then do nothing. But if _fieldName is not followed by .mandatory span element then I want to add a text string immediately after the ._fieldName element. Here is the HTML:
<div class="container">
<span class="_fieldName">Name</span>
<span class="mandatory">*</span>
<span class="_fieldName">Email address</span>
</div>
This code works:
<script>
if($("span._fieldName").next("span.mandatory").length > 0)
{
$("span._fieldName")
}
else {
$( "<p>(Optional)</p>" ).insertAfter( "span._fieldName" );
}
</script>
But it adds (Optional) after every span._fieldName. I only want to add it after the Email address field because it does not have span.mandatory immediately after it. Is this possible?
Use: not !, .next() and .is()
$('._fieldName').each(function() {
if( !$(this).next().is('.mandatory') ) {
$(this).after('<p>(Optional)</p>');
}
});
<div class="container">
<span class="_fieldName">Name</span>
<span class="mandatory">*</span>
<span class="_fieldName">Email address</span>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
The main issue is that you're dealing with all span._fieldName elements at once. You need to loop through them and individually check them to see what their next element is. To do that you can use each(), like this:
$('span._fieldName').each(function() {
if ($(this).next('span.mandatory').length == 0) {
$("<p>(Optional)</p>").insertAfter(this);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<span class="_fieldName">Name</span>
<span class="mandatory">*</span>
<span class="_fieldName">Email address</span>
</div>
When a user clicks on a link. I am trying to find the closest span value by class and then get that classes text. Currently it is just returning empty text:
Here is the HTML:
<div class="plan recommended">
<div class="recommended-badge"><span>DOUBLE DATA</span></div>
<div data-equalizer-listener="plan-heading" class="plan-header">
<div class="prices">
<div class="col total">
<div class="price"><sup>$</sup> <span class="amount">85</span> <span class="caption">per month</span></div>
</div>
<p class="min-payment">Min. Total Cost is $2,040 over 24 months.</p>
</div>
</div>
<div class="features">
<div class="feature included_data PO_Included_Data standard first" data-equalizer-selector="PO_Included_Data" style="height: 247px;">
<div class="description"><span class="highlight-text">28GB TOTAL DATA</span><br>
<span class="legal">Includes 14GB + 14GB bonus data for 24 mths<br>
New and recontracting services only<br>
Offer ends 15/04/18<br>
$10 per extra 1GB</span></div>
<div class="more-data-info hide" data-information="included-data"><strong>Data Pool -</strong> Combine any of our latest My Plan Plus (including SIM Only) and My Mobile Broadband Plus plans on the one bill to pool and share the data.</div>
<div>more</div>
</div>
</div>
</div>
and my javascript
So when someone clicks on the a href with the class="more-data-link" I want to find the span with the class="amount" and get its text
$(".more-data-link").on("click", function(event) {
event.preventDefault();
var x = $(this).closest('plan-header').find('.price').find('.amount').text();
console.log(x);
});
Please use this fiddle
$(".more-data-link").on("click", function(event) {
event.preventDefault();
var x = $(this).closest('.plan.recommended').find('.plan-header .price .amount').text();
console.log(x);
});
<div class="plan recommended">
<div class="recommended-badge"><span>DOUBLE DATA</span></div>
<div data-equalizer-listener="plan-heading" class="plan-header">
<div class="prices">
<div class="col total">
<div class="price"><sup>$</sup>
<span class="amount">85</span>
<span class="caption">per month</span></div>
</div>
<p class="min-payment">Min. Total Cost is $2,040 over 24 months.</p>
</div>
</div>
<div class="features">
<div class="feature included_data PO_Included_Data standard first" data-equalizer-selector="PO_Included_Data" style="height: 247px;">
<div class="description"><span class="highlight-text">28GB TOTAL DATA</span><br>
<span class="legal">Includes 14GB + 14GB bonus data for 24 mths<br>New and recontracting services only<br>Offer ends 15/04/18<br>$10 per extra 1GB</span>
</div>
<div class="more-data-info hide" data-information="included-data">
<strong>Data Pool -</strong> Combine any of our latest My Plan Plus (including SIM Only) and My Mobile Broadband Plus plans on the one bill to pool and share the data.
</div>
<div>
more
</div>
</div>
</div>
</div>
You need to select parent (plan recommended) class and then find its child...
For those seeking a solution without jquery (the logic inside the click event is the same as described by Sarvan Kumar):
window.onload = function(){
for(var tL=document.querySelectorAll('.more-data-link'), i=0, j=tL.length; i<j; i++){
tL[i].onclick = function(){
var tE = function fA(e){return !e || (e.className && e.className.indexOf('plan') !== -1 && e.className.indexOf('recommended') !== -1) ? e && e.querySelector('.amount') : fA(e.parentNode)}(this);
console.log(tE ? tE.textContent : '404')
}
}
}
I check your script and find some error in it, use innerHtml in place of text() and closest('plan-header') should be closest('.plan-header'). but may be you not get the proper result because it will search in parents div not subling check link https://www.w3schools.com/jquery/traversing_closest.asp
you can use the simplest and best way to do same by creating the attribute of the more-data-link and save value of amount in it and use the following code.
$(".more-data-link").on("click", function(event) {
event.preventDefault();
var x = $(this).attr('amount');
console.log(x);
});
$(".more-data-link").on("click", function(event) {
event.preventDefault();
var x = $(this).closest('.plan-header').find('.amount').text();
console.log(x);
});
Fixed it. You don't need to use the second find and you missed a dot
I am working on project where I need to collect the price value form below div
<div>
<span class="price">
<span data-currency-iso="BDT">৳</span>
<span dir="ltr" data-price="21000">21,000.00</span>
</span>
</div>
I need help to find the solution.
Here is my suggestion to make it understandable what you are looking for
Plain JS
console.log(
document.querySelector("span.price span:last-child").getAttribute("data-price")
);
<div>
<span class="price">
<span data-currency-iso="BDT">৳</span>
<span dir="ltr" data-price="21000">21,000.00</span>
</span>
</div>
jQuery version
console.log(
$("span.price span:last").data("price")
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="price">
<span data-currency-iso="BDT">৳</span>
<span dir="ltr" data-price="21000">21,000.00</span>
</span>
</div>
or $("[data-currency-iso]").next().data('price');
or $(".price").find("[data-price]").data('price');
Use jQuery to do stuff like this easily.
Insert into your HTML in the <head></head>:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Then:
$('.price [data-price]').data('price');
It would be better though if you just added a class to your price div and did this:
$('.price-amount').data('price');
I guess you're looking for dataset
The HTMLElement.dataset property allows access, both in reading and
writing mode, to all the custom data attributes (data-*) set on the
element, either in HTML or in the DOM.
var elem = document.querySelector('[data-price]');
console.log(elem.dataset.price);
var elem = document.querySelector('[data-price]');
console.log(elem.dataset.price);
<div>
<span class="price">
<span data-currency-iso="BDT">৳</span>
<span dir="ltr" data-price="21000">21,000.00</span>
</span>
</div>