Select span of sibling div jquery - javascript

I am using jQuery selectors, and I need to be able to find each span individually that contains a dollar amount. For example, I'd like to find & change the first span to $15 and the third span to $40. I have put in class names in my example, but in my problem I do not know the class names, and I do not know which span the 2nd dollar amount is in. There also could be more or less div's and spans.
This happens to be in a form, and I find the first dollar amount like this:
$("form[action='/cart'] span:contains('$'):first).replaceWith("$15");
I have the following HTML.
<div class="daddy">
<div class="kid1">
<span>$10</span>
</div>
<div class="kid2">
<span>Nothing to see here</span>
</div>
<div class="kid3">
<span>$20</span>
</div>
</div>
Thanks

You can iterate over each span element and check if it's innerHTML contains $ symbol. If so, return all these spans and their position (index).
Once you have their index position, you can modify them as you like.
Note: No jQuery needed in this solution.
Example: You can push every index of each matched span to an array. In this particular case, it would look like var matchedIndexes = [0, 2]. Then basically, if you want to change e.g. the first element - simply use matchedIndexes[0].
var elems = document.getElementsByTagName('span'),
matchedIndexes = [];
Array.from(elems).forEach(function(v,i){
if (/\$/.test(v.innerHTML)){
matchedIndexes.push(i);
}
});
//change html of the first element
elems[matchedIndexes[0]].innerHTML = '$15';
//or change the last matched element
elems[matchedIndexes[matchedIndexes.length-1]].innerHTML = '$99';
<div class="daddy">
<div class="kid1">
<span>$10</span>
</div>
<div class="kid2">
<span>Nothing to see here</span>
</div>
<div class="kid3">
<span>$20</span>
</div>
</div>

why not having an array with values to be updated and query the span which contains '$' and update accordingly?
var ratesToUpdate = [15, 40, 70];
var spans = $("form[action='/cart'] span:contains('$')");
spans.each(function(index, span){
$(span).text('$'+ratesToUpdate[index]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form action="/cart">
<div class="daddy">
<div class="kid1">
<span>$10</span>
</div>
<div class="kid2">
<span>Nothing to see here</span>
</div>
<div class="kid3">
<span>$20</span>
</div>
<div class="kid4">
<span>nothing</span>
</div>
<div class="kid5">
<span>nothing</span>
</div>
<div class="kid5">
<span>$50</span>
</div>
</div>
</form>

I like the answer Kind user gave - but here is my stab at it. I couldn't make it more dynamic as the addition values are not similar (first one is added by 5, third is doubled...)
JSFiddle Here: https://jsfiddle.net/rL36jv8m/
Your HTML
<div class="daddy">
<div class="kid1">
<span>$10</span>
</div>
<div class="kid2">
<span>Nothing to see here</span>
</div>
<div class="kid3">
<span>$20</span>
</div>
</div>
Array of addition values to corresponding divs.
var addValues = [
5,
'',
20
]
Iteration:
$('.daddy').children().each(function(i, o) {
var elem = $(o).find('span');
if (elem.html().indexOf('$') === 0) {
elem.html('$' + (parseInt(elem.html().replace('$', '')) + addValues[i]))
}
})
Hope this helps.

Would this solve your problem?
var values = [15, 40];
$("form[action='/cart'] span:contains('$')").each(
function(index, element)
{
element.value = '$'+ values[index];
});

Related

Downshift remaining IDs after function remove()

I'm using Javascript and I'm having problems trying to remove several elements.
Each div has a specific ID, like this:
<div id='1'></div>
<div id='2'></div>
<div id='3'></div>
<div id='4'></div>
Each div has a button that fires the remove() function
document.getElementById(count).remove()
Count is a variable that is increased whenever I create a new div
The remove() function works, but it creates a gap. IF i remove the div with id=2, then:
<div id='1'></div>
<div id='3'></div>
<div id='4'></div>
But I would like that the remaining IDs could downshift like this:
<div id='1'></div>
<div id='2'></div>
<div id='3'></div>
I guess I need a for loop but I can't understand how to make it
Use a class on each element, like this:
<div class="a" id='1'></div>
<div class="a" id='2'></div>
<div class="a" id='3'></div>
<div class="a" id='4'></div>
And call the following function after each removal:
function resetId(){
const list = document.getElementsByClassName("a")
for(let i = 0; i < list.length; i++){
list[i].id = i + 1
}
}
However, it might be better to just not use IDs in this case. By applying the same class to all your elements, there's no need to readjust the numbering, and you can select (or remove) the nth element using:
document.getElementsByClassName("a")[n]
This would probably be best achieved using jquery.
Here is the working code below:
$("div").each(function(i) {
$(this).attr('id', ++i);
});
$("#remove").click(function() {
$("#2").remove();
$("div").each(function(i) {
$(this).attr('id', ++i);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
remove
How it works
First $(this).attr('id', ++i); this line here is used to add a number to div id. Ive repeated it in the remove function [("#remove").click(function()] This is because once a div has been removed the will be a number change.
This in affect is a loop. Without all the lines of code. Which is why i like jquery :)
The div id name is found here after they have been written $("#2").remove(); #2 refers to the <div id="2"> As you would in css.
If you notice, with an inspection the numbers down shift as 1 is removes as per your request.
In order to use jquery you have to link the library. <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
A Pure Javascript Version
function resetId(){
var div=document.getElementsByClassName("div")
for(i in div){
div[i].id=i++
}
}
function clicked() {
var elem = document.getElementById("1");
elem.parentNode.removeChild(elem);
resetId();
}
<div class="div" id="0">div</div>
<div class="div" id="1">div</div>
<div class="div" id="2">div</div>
<div class="div" id="3">div</div>
Remove
How it Works
This section here is your loop:
for(i in div){
div[i].id=i++
}
This section quite simply rewrites the numbers 0 - 4 after one has been removed.
The reason it starts from 0, is because in programming we start counting from 0. Hay 0 is a number too guys :).
The i++ Is a basically a mini int [ish] that is increased as the loop counts through how many divs there are.
This var elem = document.getElementById("1"); & this elem.parentNode.removeChild(elem); Is why I find jquery more acceptable in this situation. Its a bit less faf.
Finally resetId(); We have to call the function otherwise it doesn't that anything has changed, because computers are silly and need to be told.
Furter Reading
https://api.jquery.com/
http://www.lucemorker.com/blog/javascript-vs-jquery-quick-overview-and-comparison
Sounds like you should be using classes and referencing elements by index instead. IDs should remain persistent for clarity.
document.getElementsByClassName('my-class')[2].remove();
<div class="my-class" id="thing1">One</div>
<div class="my-class" id="thing2">Two</div>
<div class="my-class" id="thing3">Three</div>
<div class="my-class" id="thing4">Four</div>

how to to put values into array if class is present

i have a list of values inside a div having class="price" iam intrested to push
values into array if class is present otherwise/ 'not present'.
the div pattern is .mainDiv>span, .price sometime pattern will be .mainDiv > span
sometime .mainDiv > .price
so how to push price value into array if class="price" is present.
DOM tree is below.
<div class="mainDiv">
<span>abcdsnndsjdjnd</span>
<div class="price">$2000</div>
</div>
<div class="mainDiv">
<span>abcdsnndsjdjnd</span>
<div class="price">$300</div>
</div>
<div class="mainDiv">
<span>abcdsnndsjdjnd</span> <!-- observe here price is not there -->
</div>
I am using code like this
var arr = [];
$('.mainDiv').each(function(i){
if ($(this).hasClass('price')){
arr.splice(i, 0, $(this).text());
} else {
arr.splice(i, 0, 'no price');
}
});
Please help me thanks in advance
Firstly you're using hasClass() on the .mainDiv itself, when the .price element is a child. You could use has() or find().length to get the element.
You could also make this simpler by using map() to create your array. Try this:
var arr = $('.mainDiv').map(function() {
return $(this).has('.price') ? $(this).text() : 'no price';
}).get();
There are various issues in your code
$(this).hasClass('price') - here working of hasClass() method is not as you expected like has() method. It's check the class for the selected element not for it's descentant. So use $(this).has('.price').length instead
$(this).text() - retrives all the div text since you just need the price use $('.price', this).text() instead.
Use map() method in jQuery for make it optimized.
// iterate aver all div
var arr = $('.mainDiv').map(function(i) {
// cache the `.price` element
var $price = $('.price', this);
// check `.price` element present or not
// and based on that generate the element
return $price.length ? $price.text() : 'no price';
// get the array from the generated jQuery object
}).get();
console.log(arr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mainDiv">
<span>abcdsnndsjdjnd</span>
<div class="price">$2000</div>
</div>
<div class="mainDiv">
<span>abcdsnndsjdjnd</span>
<div class="price">$300</div>
</div>
<div class="mainDiv">
<span>abcdsnndsjdjnd</span>
<!-- observe here price is not there -->
</div>

AppendChild a element above a cerain element

So i have a div element which will be filled dynamically with others divs using the appendChild Method, this should display a list. The User is now able to sort that list with the JqueryUI Sortable option.I also added some sortable option attribues like follows:
Options:
$("#NameContainer").sortable("option", "axis", "y");
$("#NameContainer").sortable( "option", "containment", "parent" );
LIST
<div id="NameContainer" class="ui-widget">
<div id="Name_1">John</div>
<div id="Name_2">Jack</div>
<div id="Name_3">Charlie</div>
<div id="Name_4">Sawyer</div>
<div id="Name_5">Yin</div>
<div id="Name_6">Ben</div>
</div>
Now comes my problem. The appendChild always inserts the new div at the bottom of the container but i want to to add some space at the bottom of to the Container Div with a "br" or something like that. I want to add that space to make sure that when the user sorts the last item of that list it will get sorted correctly because the "containment" bounds sometimes wont allow to sort under the last item.
<div id="NameContainer" class="ui-widget">
<div id="Name_1">John</div>
<div id="Name_2">Jack</div>
<div id="Name_3">Charlie</div>
<div id="Name_4">Sawyer</div>
<div id="Name_5">Yin</div>
<div id="Name_6">Ben</div>
<br><!--SPACEHOLDER-->
</div>
So here comes my Question is there away to appendChild above a certain element? Like a "br" "div" or "p"?
Try this instead of appendChild:
Please note I have used random value to add in div as I don't have your dynamic value.
check fiddle: https://jsfiddle.net/dqx9nbcy/
<div id="NameContainer" class="ui-widget">
<div id="divspacer"></div>
</div>
<button id="btn">ADD Element</button>
$(document).ready(function(){
$("#btn").click(function(){
var parentnode = document.getElementById("NameContainer");
var existnode = document.getElementById("divspacer");
var rand = Math.floor((Math.random() * 10) + 1);
var newName = document.createElement("div");
newName.setAttribute("id", rand);
newName.setAttribute("value", rand);
newName.setAttribute("class","ui-widget-content");
newName.innerHTML = rand;
parentnode.insertBefore(newName,existnode);
});
});
refer http://api.jquery.com/appendto/ but you need to make sure that your are targeting right tag.
You can try with this code snippet.
HTML Snippet
<div id="NameContainer" class="ui-widget">
<div id="Name1">Name1</div>
<div id="Name2">Name2</div>
<div id="Name3">Name3</div>
<div id="Name4">Name4</div>
<br>
<br>
</div>
Javascript Snippet
$(document).ready(function(){
$("#btn").click(function(){
var containerDiv= $("#NameContainer");
var childList = containerDiv.children("div");
var newElementid = childList.length;
var newName = document.createElement("div");
newName.setAttribute("id", "Name"+(newElementid+1));
newName.setAttribute("value", "Name"+(newElementid+1));
newName.setAttribute("class","ui-widget-content");
newName.innerHTML = "Name"+(newElementid+1);
$(childList[childList.length-1]).after(newName);
});
});
This is specific to a situation where there are some elements in the initial list. The same can be modified for dynamic list of implementation by validating that childList.length is != 0 before using the same.

Having issue with DOM selection in jquery

<div class="wrapper">
<p class="text"></p>
</div>
<div class="wrapper">
<p class="text"></p>
<img></img>
</div>
<div class="wrapper">
<p class="text"></p>
<div class="vid"></div>
</div>
Assume above is a list of users' post, and I want to identify type of post of them. To select the image or video type is easy, for example the video, just select like $('.wrapper .vid').
But there is a problem when I want to select plaintext type of post, because the class text also appear in vid and image type of post.
Looks like you want wrapper elements which does not hae vid or img then
$('.wrapper').not(':has(img, .vid)')
If you want the text elements within them
$('.wrapper').not(':has(img, .vid)').find('.text')
You can use filter to get the three different types of posts. Something like this:
var $textPosts = $('.wrapper').filter(function() {
return $(this).find('img, .vid').length == 0;
});
var $imgPosts = $('.wrapper').filter(function() {
return $(this).find('img').length > 0;
});
var $vidPosts = $('.wrapper').filter(function() {
return $(this).find('.vid').length > 0;
});
Also note that the img HTML tag is self closing, eg:
<img src="foo.jpg" title="Foo" />
If i get this right that you want to get all the test in <p> with the class text, then you can do something like this
$('.wrapper > .text').html()
The above code will give you the content of only those element with class "text" that are direct under class "wrapper"
You can use .filter() to filter out the element with class text whose has no sibling:
var text = $('.text').filter(function() {
return $(this).siblings('*').length == 0
}).text();
Fiddle Demo
You can use
$('.wrapper p.text').text()
fiddle demo

Add class with a particular div

I have this div
<div class="newDiv">
It is generating in loop, something like
<div class="newDiv">
<div class = "innerDiv">
SomeCode
</div>
</div>
<div class="newDiv">
<div class = "innerDiv">
SomeCode
</div>
</div>
<div class="newDiv">
<div class = "innerDiv">
SomeCode
</div>
</div>
Now I want to add another class "BrightDiv" with the div that generated at odd places like
with first and third div.
what should I do to add Class "BrightDiv" along with "newDiv" with every div at odd place?
Try this : You can use :odd or :even to select odd / even elements, but it is depend on the index position and not natural number count. So In your case, you want first and third position div i.e. with index= 0 and 2 which is even by index position and hence use :even.
$('div.newDiv:even').addClass('BrightDiv');
DEMO
You can use filter to select only the odd indexed divs
$(".newDiv").filter(function() {
return $(this).index() % 2 == 1;
}).addClass("BrightDiv");
this will give you a solution $("div:even").addClass("BrightDiv");
Ways to achieve this:
CSS:
.newDiv:nth-child(odd) { /*CSS*/ }
or
.newDiv:nth-child(2n-1) { /*CSS*/ }
jQuery:
$('.newDiv:odd').addClass('BrightDiv');

Categories

Resources