wrap only text within a selection in jquery - javascript

I have the following markup repeating several times on a page:
<div class="RebalanceCellBroadACName">
<img src="someimage.png" />
Accounts
</div>
Where I wish to use jquery to wrap only the word "accounts" in a span with the class .orange-category.
I have found that the following:
$(".RebalanceCellBroadACName").wrapInner("<span class='orange-category' />");
wraps both the image and the text.
This when typed in the console returns all of the instances of the text concatenated together:
$(".RebalanceCellBroadACName").text();
However the following returns an error "undefined is not a function", and I assume this is because I am selecting a string rather than a jQuery object.
$(".RebalanceCellBroadACName").text().wrapAll("<span class='orange-category' />");
So any help would be appreciated as to how to best achieve the folowing result via jquery:
<div class="RebalanceCellBroadACName">
<img src="someimage.png" />
<span class='orange-category' />Accounts</span>
</div>
For every instance of .RebalanceCellBroadACName on the page. Thank you for your help in advance.

A solution :
$(".RebalanceCellBroadACName").each(function(){
var img = $('img', this).detach();
$(this).wrapInner("<span class='orange-category' />").prepend(img);
})

While you don't have access to the text node, you do have access to the children that are DOM elements.
So basically you can clone the parent, remove the children, wrap the text and finally replace it in the original.
$(".RebalanceCellBroadACName").each(function(){
var $this = $(this);
var all_text = $this.html();
var clean_text = $this.clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.text().trim();
var new_text = "<span class='orange-category'>"+clean_text+"</span>"
$this.html(all_text.replace(clean_text, new_text));
})
http://jsfiddle.net/p2he9h2k/

Related

How to modify HTML attributes inside a variable that contains HTML?

I have a variable that contains some HTML elements & content:
var data = '<h1>This is a demo element. <span>This is a span.</span></h1><div id="div-element" data-id="1">This is a div.</div>';
What I'd like to do is modify the data-id within the #div-element.
What I've tried so far:
console.log($(data).find('#div-element').attr('data-id'));
This returns undefinied.
data = $.parseHTML(data);
console.log($(data).find('#div-element').attr('data-id'));
Tried to parse the HTML also, but it returns undefinied as well.
What am I missing here?
I'm using jQuery but a Javascript solution is just as good.
The issue is because you're using find() yet there is no root element in the HTML string you're specifying; all the elements are siblings. In this case you can use filter():
var data = '<h1>This is a demo element. <span>This is a span.</span></h1><div id="div-element" data-id="1">This is a div.</div>';
var id = $(data).filter('#div-element').data('id');
console.log(id);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Also note the use of data('id') over attr('data-id').
Create a dummy element div and set data as its innerHTML
var html = `<h1>This is a demo element. <span>This is a span.</span></h1><div id="div-element" data-id="1">This is a div.</div>`;
var div = document.createElement( "div" );
div.innerHTML = html; //set the html string
//change the attribute of the id-Element
div.querySelector( "[id='div-element']" ).setAttribute( "data-id", "2" );
console.log( div.innerHTML );
In this case following will work.
$("<div>" + data + "</div>").find('#div-element').attr('data-id')

Is it possible to remove dom node from detached dom tree using jquery?

What I'm trying to do:
$domTree = $('<div class="container"><div class="first">first</div><div class="second">second</div></div>')
$domTree.remove('.first')
$dom.html() // Should contain second div only
What I get: both first and second divs are present.
What I'm doing wrong? What's the right approach?
Yes you can , use find to get the element and remove to remove it, end is used to return back the container
$domTree = $('<div class="container"><div class="first">first</div><div class="second">second</div></div>').find('.first').remove().end();
$domTree.html();
$domTree = $('<div class="container"><div class="first">first</div><div class="second">second</div></div>').find('.first').remove().end();
console.log($domTree[0]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

javascript - how to get img tags from any element?

I want to get img tags attribute values from any element, img tags could be more than 1, and also can be randomized.
like,
<div> hellow <img src='icons/smile.png' title=':)'> how are u <img src='icons/smile2.png' title=':D'></div>
I want to grab their title attribute values and then want to store in some var currentHTML; with all existing div data.
and then insert into any element just like $('#div').html(currentHTML);
and output should be like this,
hellow :) how are u :D
How can I do this?
Thanks in advance.
Try this:
$("img").each(function()
{
$(this).replaceWith($(this).prop("title"));
});
Fiddle. Its just looping through each image and replacing it (with replaceWith()) with its own title attribute.
UPDATE:
Things got more complex. Check this snippet:
// The text result you want
var currentHTML = "";
// Instead of search for each image, we can search of elements that
// contains images and you want to get their text
$(".images").each(function()
{
// Check note #1
var cloned = $(this).clone().css("display", "none").appendTo($("body"));
// Here we select all images from the cloned element to what
// we did before: replace them with their own titles
cloned.find("img").each(function()
{
$(this).replaceWith($(this).prop("title"));
});
// Add the result to the global result text
currentHTML+= cloned.html();
});
// After all, just set the result to the desired element's html
$("#div").html(currentHTML);
Note #1: Here is what is happening in that line:
var cloned = here we create a var which will receive a cloned element;
the cloned element will the current element $(this).clone();
this element must be hidden .css("display", "none");
and then appended to the document's body .appendTo($("body"));.
Note that in your initial html, the div containing the images received the class images:
<div class="images"> hellow <img src='icons/smile.png' title=':)' /> how are u <img src='icons/smile2.png' title=':D' /></div>
So you can do that on more than one element. I hope this helps.
Here's a neat little function you can reuse.
$(function(){
function getImageReplace($el) {
var $copy = $el.clone();
$copy.find('img').each(function(){
$(this).replaceWith($(this).attr('title'));
});
return $copy.text();
}
//now you can use this on any div element you like
$('#go').click(function() {
alert(getImageReplace($('div')));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div> hellow <img src='icons/smile.png' title=':)'> how are u <img src='icons/smile2.png' title=':D'></div>
<button id='go'>Convert images</button>

count of dynamically created DIVs returning zero

Following is my code and relevant HTML , what i wanna do is that i wanna count the number of search-img-box within search-img-ctrl but i get 0 as output, just to tell here that
following div search-img-box is dynamically created.
jQuery(document).ready(function() {
var numberOfDivs = jQuery('#search-img-ctrl').filter('.search-img-box').length;
alert(numberOfDivs);
});
following is my HTML
<div id="search-img-ctrl" class="search-img-ctrl">
<div id="search-img-box" class="search-img-box" name="search-img-box">
<img width="335" height="206" src="" alt="">
<ul>
</div>
<div id="search-img-box" class="search-img-box" name="search-img-box">
</div> </div>
Here's a fiddle: http://jsfiddle.net/t5jcT/
I changed filter to find and got rid of the duplicate ids in the html.
jQuery(document).ready(function() {
var numberOfDivs = jQuery('#search-img-ctrl').find('.search-img-box').length;
alert(numberOfDivs);
});
or you can use selectors instead of the find as others have pointed out:
jQuery(document).ready(function() {
var numberOfDivs = jQuery('#search-img-ctrl .search-img-box').length;
alert(numberOfDivs);
});
use .find instead of .filter:
var numberOfDivs = jQuery('#search-img-ctrl').find('.search-img-box').length;
alert(numberOfDivs);
If you want to only find the number of direct children with that class you can use .children
var numberOfDivs = jQuery('#search-img-ctrl').children('.search-img-box').length;
Also make sure you edit your html so that your html elements don't have duplicate IDs

jquery, how to use nextAll() with css scope

HTML:
<div class="my_1"></div>
<div class="my_big">
<div class="small" id="id_1"></div>
<div class="small" id="id_2"></div>
<div class="small" id="id_3"></div>
<div class="small" id="id_4"></div>
</div>
javascript:
var css_scope=$(".my_big");
var next_div=$(".my_1").nextAll('.small',css_scope).first();
console.log(" \n next div = "+ next_div.attr('id'));
console shows undefined. But if I exclude the my_big div from html and define var next_div in javascript as follows:
var next_div=$(".my_1").nextAll('.small').first();,
expected output is obtained.
How to make nextAll() work with the mentioned css scoping ?
.nextAll is used to find all the next siblings, you should find the .small from the result of nextAll.
var next_div=$(".my_1").nextAll('.my_big').find('.small').first();
You cannot get to .small from my_1 using nextAll() since they are not siblings. You can get to it using the following selector.
// Get the first element matching ".small" inside an element matching ".my_big"
// that comes immediately after an element matching ".my_1"
var next_div = $('.my_1 + .my_big > .small:first')​;
Check this demo: http://jsfiddle.net/q6XKR/
If you want to access the first element in my_big div, there's no need to bring my_1 into the scene.
var next_div = $('.my_big').find('.small').first();
console.log(" \n next div = "+ next_div.attr('id'));
Hope it clarifies you somewhat about traversing elements in jQuery.

Categories