I am adding items dynamically with ajax_select (app with builtin js script to add items), it is adding items as
<div class="col-md-4 col-sm-6">
<div class="form-group ">
<label class="control-label" for="id_colours">Colours</label>
<input type="text" name="colours_text" id="id_colours_text" value="" autocomplete="off" class="form-control ui-autocomplete-input">
<input type="hidden" name="colours" id="id_colours" value="|1|7|2|" data-ajax-select="autocompleteselectmultiple" data-plugin-options="{"html": true, "source":
"/ajax_select/ajax_lookup/colours"}" data-changed="true">
<div id="id_colours_on_deck" class="results_on_deck">
<div id="id_colours_on_deck_1">
<span class="ui-icon ui-icon-trash" id="kill_1id_colours">X</span> White
</div>
<div id="id_colours_on_deck_7">
<span class="ui-icon ui-icon-trash" id="kill_7id_colours">X</span> Yellow
</div>
<div id="id_colours_on_deck_2">
<span class="ui-icon ui-icon-trash" id="kill_2id_colours">X</span> Black
</div>
</div>
</div>
Here I added White, Yellow and Black these are inside div of id = id_colours_on_deck, how can I get the list of all colours in id_colours_on_deck.
I am not friendly with jquery probably here I can get the answer.
You can iterate over the divs using each() and grab only the text using .contents()[1], like this:
("div[id^='id_colours_on_deck_']").each(function(){
$($(this).contents()[1]).text();
})
If I have understood your question correctly, you want to "extract" the colors you have mentioned inside the divs? (So White, Yellow, Black)
Using jQuery, you should be able to do something like this with jQuery: (however, this will also include the "X" that is inside the span, so that will need to be looked at)
$("#id_colours_on_deck").find("div[id^=id_colours_on_deck]").each(function() {
var value = $(this).text();
});
Because it's dynamically added you need to use $(document) or $('body') to find your elements as jQuery works with the DOM that's loaded on document load. Which is why newly added elements can't be targeted using conventional ways:
$(document).find('#my-dynamic-element'); //this is how you get the dynamically added element
then to get your data you'd use something like:
$(document).find('#id_colours_on_deck_7').text();
You can use an each function, something like this.
$('#id_colours_on_deck div').each(function) {
$('#id_colours_on_deck div').html();
}
This however will include the X from the span tag.
Fiddle
https://jsfiddle.net/shawnw/4yaem85k/12/
Another solution would be to use this technique
$("div[id^=id_colours_on_deck_]").clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.text();
You can use plain javascript, querySelectorAll and lastChild.
With querySelectorAll you get the selection of div with a color text, and with lastChild you avoid getting the span and can grab the text node holding the color.
Stack snippet
Array.from(document.querySelectorAll('#id_colours_on_deck div')).forEach(el => {
console.log( el.lastChild.textContent );
})
<div id="id_colours_on_deck" class="results_on_deck">
<div id="id_colours_on_deck_1">
<span class="ui-icon ui-icon-trash" id="kill_1id_colours">X</span> White
</div>
<div id="id_colours_on_deck_7">
<span class="ui-icon ui-icon-trash" id="kill_7id_colours">X</span> Yellow
</div>
<div id="id_colours_on_deck_2">
<span class="ui-icon ui-icon-trash" id="kill_2id_colours">X</span> Black
</div>
</div>
Updated based on a comment how to be compatible with older browsers.
Here is an option that will do that, far way back in time :)
var list = document.getElementById('id_colours_on_deck').children;
for (var i = 0; i < list.length; i++) {
var el = list[i].lastChild;
console.log( (el.textContent || el.innerText) );
}
<div id="id_colours_on_deck" class="results_on_deck">
<div id="id_colours_on_deck_1">
<span class="ui-icon ui-icon-trash" id="kill_1id_colours">X</span> White
</div>
<div id="id_colours_on_deck_7">
<span class="ui-icon ui-icon-trash" id="kill_7id_colours">X</span> Yellow
</div>
<div id="id_colours_on_deck_2">
<span class="ui-icon ui-icon-trash" id="kill_2id_colours">X</span> Black
</div>
</div>
I have made a very small change to your HTML by adding the color name to a span with class .color-name, and have generated the following answer:
var colorParentList = $("#id_colours_on_deck span.color-name");
colorParentList.each(function() {
alert($(this).text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="id_colours_on_deck" class="results_on_deck">
<div id="id_colours_on_deck_1">
<span class="ui-icon ui-icon-trash" id="kill_1id_colours">X</span> <span class="color-name">White</span>
</div>
<div id="id_colours_on_deck_7">
<span class="ui-icon ui-icon-trash" id="kill_7id_colours">X</span> <span class="color-name">Yellow</span>
</div>
<div id="id_colours_on_deck_2">
<span class="ui-icon ui-icon-trash" id="kill_2id_colours">X</span><span class="color-name"> Black</span>
</div>
</div>
I hope this was helpful.
Related
<div class="row data">
<div class="subdiv">
<div class="check"><input type="checkbox" name="buy" value="260" checked="" onclick="javascript:basket.checkItem();"> </div>
<div class="img"><img src="./img/basket1.jpg" width="60"></div>
<div class="pname">
<span>TX2</span>
</div>
</div>
<div class="subdiv">
<div class="num">
<div class="updown">
<input type="text" name="p_num1" id="p_num1" size="2" maxlength="4" class="p_num" value="2" onkeyup="javascript:basket.changePNum(1);">
<span onclick="javascript:basket.changePNum(1);"><i class="fas fa-arrow-alt-circle-up up"></i></span>
<span onclick="javascript:basket.changePNum(1);"><i class="fas fa-arrow-alt-circle-down down"></i></span>
</div>
</div>
</div>
<div class="subdiv">
<div class="basketcmd">삭제</div>
</div>
</div>
I saw the way using DOMParser().parseFromString, but this solution requires me to convert html code into one line string. Is there better way to convert or skills to make html code to string easily?
my final goal is to use appendChild() so that I can have many "row data" class div. which requires me to make html code to DOM.
As others have stated, going from strings to HTML in JavaScript is dangerous, as it can result in easy-to-exploit XSS (Cross-Site Scripting) vulnerabilities.
If you want to create an element safely, we can do so as follows.
let clicks = 0;
const container = document.createElement("div");
container.setAttribute("class", "container");
const heading = document.createElement("h1");
heading.textContent = "Created & Appended, Click Me!";
heading.addEventListener("click", (event) => {
heading.textContent = `Clicked ${++clicks} Times`;
});
container.append(heading);
document.body.append(container);
We can create elements with createElement, set any attribute with setAttribute, modify the classes with classList or setAttribute, and set the text node content with textContent. By doing this, we can prevent XSS.
We can even add events using addEventListener.
I have this HTML:
<p></p>
<div class="comment_like">
<span class="reaction_2 tooltipstered" id="like13seperator2" rel="unlike"><i
class="likeIconDefault"></i>Like</span>
</div>
Now I want to add this div: <div class="commentLikeCount"></div> before this comment_like class using jQuery.
I am trying with this code:
$("#like"+posts_id).parents(".comment_like").prepend('<div class="commentLikeCount"></div>');
but somehow not working :(
Updated for the new Questions:
Now I have that HTML:
<p></p>
<div class="commentLikeCount">
<br>
<span class="float-right"> 1</span>
<img src="assets/images/db_haha.png" alt="" class="float-right old">
<img src="assets/images/db_love.png" alt="" class="float-right">
</div>
<div class="comment_like">
<span class="unLike_2" id="like13seperator2" rel="unlike">
<i class="loveIconSmall likeTypeSmall"></i>Love
</span>
</div>
Now, I just want to remove the last Img from the coomentLikeCount class.
You can use insertBefore:
$('<div class="commentLikeCount" />')
.insertBefore($("#like"+posts_id).parents(".comment_like"))
Or before:
$("#like"+posts_id).parents(".comment_like")
.before('<div class="commentLikeCount" />')
If you're inserting commentLikeCount in every .comment_like, then just use $('.comment_like') instead of $("#like"+posts_id).parents(".comment_like")
Regarding your comment:
well if I already have this div then how can select this div?
You can prepend using insertBefore like:
$('.commentLikeComment').insertBefore($("#like"+posts_id).parents(".comment_like"));
To your updated question, you can remove last image like:
$('.commentLikeCount img').last().remove()
You can do with before().
$(".comment_like").before("<div class='commentLikeCount'></div>");
I want to remove an element using jQuery.
HTML:
<div class="listContainer" id="listContainer">
<div class="listItem">
<div class="name">
Item Name
</div>
<div class="amount">
<input type="text" class="amountInput" />
</div>
<div class="delete">
<div class="deleteBtn">
X
</div>
</div>
</div>
</div>
There are several listItemss on the page and each of the listItem will be created dynamically using jQuery. I want to delete amountInput of specific listItem by clicking the deleteBtn, so I tried doing:
$("#listContainer").on("click", ".deleteBtn", function() {
$(this).closest(".amountInput").remove();
});
This doesn't work. But on the other hand if I try to delete a listItem as a whole, the code works:
$("#listContainer").on("click", ".deleteBtn", function() {
$(this).closest(".listItem").remove();
});
Why is this happening?
Thanks.
Because .closest propagates to the top of the HTML. So it searches for the first parent that matches your selector. That is why it cannot find .amountInput. Because it isn't a parent of your button.
To get .amountInput you have to:
$("#listContainer").on("click", ".deleteBtn", function() {
$(this).closest(".listItem").find('.amountInput').remove();
});
This will get the wrapping .listItem element and then search it for the .amountInput element.
Your selector is not correct, use find instead of closest could be helpful in this case, also $(this) in your sample is related to deleteBtn class not to listContainer.
$("#listContainer").on("click", ".deleteBtn", function() {
console.log($(this)) // this here is .deleteBtn not listContainer
$(this).closest(".listItem").find(".amountInput").remove();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="listContainer" id="listContainer">
<div class="listItem">
<div class="name">
Item Name
</div>
<div class="amount">
<input type="text" class="amountInput" />
</div>
<div class="delete">
<div class="deleteBtn">
X
</div>
</div>
</div>
</div>
I have an output page (that I can't control) that has a really bad format. I'm using jQuery to loop through the elements and reorganize them to meet design specs.
I'm compiling strings using code similar to that below, but I'm wondering if there's a way to make it run faster? As you can see, the .html() I'm sniffing out is in children of the same parent element.
$('.parent').each(function(){
var address = $('.cellInnerWrapper .row-content .address a .addressNumber', this).html() +
$('.cellInnerWrapper .row-content .address a .addressDirection', this).html() +
$('.cellInnerWrapper .row-content .address a .addressName', this).html();
});
This just seems incredibly slow and repetitive to me, but I'm not the best at JavaScript and jQuery and don't know how to simplify it / speed it up.
Here's the original HTML structure:
<div class="parent">
<div class="cellInnerWrapper">
<div class="rowContent">
<div class="address">
<a href="URL">
<span class="addressNumber">17080 </span>
<span class="addressDirection"></span>
<span class="addressName">Iron Springs Road</span>
</a>
</div>
</div>
</div>
</div>
You can do something like this:
$(document).ready(function() {
$('.parent').each(function(){
var address;
var a = $('.cellInnerWrapper .rowContent .address a');
address = a.find('.addressNumber').html()+a.find('.addressDirection')+a.find('.addressName').html();
});
});
I adjusted to your html structure. Don't forget to use document.ready event to make sure the html structure was loaded before the script is executed.
Hope it helps!
Here is a working demo. You can store your common element in a new object and then access all the required elements that way you won't have to navigate the DOM every time.
$('.parent').each(function(){
var anchor = $('.cellInnerWrapper .rowContent .address a');
var address = anchor.find('.addressNumber').html() +
anchor.find('.addressDirection').html() +
anchor.find('.addressName').html();
console.log(address);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="cellInnerWrapper">
<div class="rowContent">
<div class="address">
<a href="URL">
<span class="addressNumber">17080 </span>
<span class="addressDirection"></span>
<span class="addressName">Iron Springs Road</span>
</a>
</div>
</div>
</div>
</div>
$('.parent').each(function(){
var a=$('.cellInnerWrapper').find('div.address').children('a').html();
$('div.newaddress').html(a);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="cellInnerWrapper">
<div class="rowContent">
<div class="address">
<a href="URL">
<span class="addressNumber">17080 </span>
<span class="addressDirection"></span>
<span class="addressName">Iron Springs Road</span>
</a>
</div>
<div class="newaddress"></div>
</div>
</div>
</div>
try this one.
I have the following code:
$(document).on( 'click', '.chevronright', function( event ) {
for (var i=0; i<2; i++){
var $next = $(this).siblings('.postlink').find('.post-title').eq(i+1).html();
$('.row').find('.post-title').eq(i).html($next);
}
I have three instances of row, and 3 instances of postlink inside each row, and there is also a chevron in each row. I want it so that when the chevron is clicked, the title from the middle one changes to the left one and the rightmost one changes to the middle one.
What happens is that when i click a chevron in row 2 or row 3, the first row is the one that the actions happen to. It gets the title of the chevron that is the next in line, in the row that I click on but it always happens to the first post-title in the page. How would I need to refer to the children of the chevrons parent row?
This is a bit "brute force" and sequence dependent but does that: (verbose for clarity)
//chevron is clicked,
$(document).on('click', '.chevronright', function(event) {
// get the elements with the class
var myPostlinks = $(this).parent('.row').find('.postlink');
//the title from the middle one changes to the left one and the rightmost one changes to the middle one.
// get reference to middle one
var middleoneNow = myPostlinks.eq(1).find('.post-title');
// get reference to left one
var leftoneNow = myPostlinks.eq(0).find('.post-title');
// Set right to middle (before we change middle)
myPostlinks.eq(2).find('.post-title').html(middleoneNow.html());
// Set middle to left now that right is set
middleoneNow.html(leftoneNow.html());
});
<style>.row{border:solid cyan 2px;}</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<span class="chevronright">chevron right</span>
<div class="postlink">
<span class="post-title">left title</span>
</div>
<div class="postlink">
<span class="post-title">middle title</span>
</div>
<div class="postlink">
<span class="post-title">right title</span>
</div>
</div>
<div class="row">
<span class="chevronright">chevron right</span>
<div class="postlink">
<span class="post-title">left title</span>
</div>
<div class="postlink">
<span class="post-title">middle title</span>
</div>
<div class="postlink">
<span class="post-title">right title</span>
</div>
</div>
<div class="row">
<span class="chevronright">chevron right</span>
<div class="postlink">
<span class="post-title">left title</span>
</div>
<div class="postlink">
<span class="post-title">middle title</span>
</div>
<div class="postlink">
<span class="post-title">right title</span>
</div>
</div>
<!-- begin snippet: js hide: false console: true babel: false -->
For clarity here is an assumption on the markup: (yes it is horrid but demonstrates as here: https://jsfiddle.net/MarkSchultheiss/vfu10c5k/
You can try
Whatever.find('.post-title:eq('+(i+1)+')').html()