In the below shown html i have this main div as cxfeeditem feeditem and there are many divs with the same class names and structure.My question is for all the divs starting with the class name cxfeeditem feeditem ,how to get values for the children,
1.with class name cxfeeditem feeditem
2.class=feeditemtimestamp
3.cxcomments feeditemcomments
4.cxfeeditem feeditem
<div class="cxfeeditem feeditem">
<span class="feeditemtext cxfeeditemtext">
This is my blog
</span>
<a class="feeditemtimestamp">Yesterday 2:13PM</a>
<div class="cxcomments feeditemcomments">
These are my comments
</div>
<div class="cxfeeditem1 feeditem1">
My comments for the comment
</div>
</div>
EDIT: Output i want to alert the values like:
This is my blog
Yesterday 2:13PM
These are my comments
My comments for the comment
I tried the following but it returns null:
$("div.cxfeeditem.feeditem").each(function() {
alert($(this).children('span.feeditemtext.cxfeeditemtext').html());
alert($(this).children('a.feeditemtimestamp').html());
alert($(this).children('div.cxcomments.feeditemcomments').html());
alert($(this).children('div.cxfeeditem.feeditem').html());
break;
});
The easiest way I could see is:
$('.cxfeeditem.feeditem').filter(
function(){
return !$(this)
.parents('.cxfeeditem.feeditem')
.length;
}).children().each(
function(){
console.log($(this).text().trim());
});
JS Fiddle demo.
The filter() is used to ensure we're not accessing the elements of the same .cxfeeditem and .feeditem classes that are children of the outer-most element of those classes. This feels a little messy, but given your desired output it seemed the best way.
After that we're simply logging the white-space trim()-ed text() of each of the (direct) child elements that haven't been filtered-out.
Edited in response to question from the OP in comments, below:
What if I want to add a children class name and I do not want to consider all tags; for example if I wanted the value of only a.feeditemtimestamp and span.feeditemtext.cxfeeditemtext
In that case you can either use a second call to filter():
$('.cxfeeditem.feeditem').filter(
function() {
return !$(this).parents('.cxfeeditem.feeditem').length;
}).children().filter(
function() {
var that = $(this);
return that.is('span.feeditemtext.cxfeeditemtext, a.feeditemtimestamp');
}).each(
function() {
console.log($(this).text().trim());
});
JS Fiddle demo.
Or you can use find() (and omit children()):
$('.cxfeeditem.feeditem').filter(
function() {
return !$(this).parents('.cxfeeditem.feeditem').length;
}).find('> span.feeditemtext.cxfeeditemtext, > a.feeditemtimestamp').each(
function() {
console.log($(this).text().trim());
});
JS Fiddle demo.
References:
jQuery:
children().
each().
filter().
find().
parents().
text().
'Plain' JavaScript:
length.
trim().
According to your function
alert($(this).children('span.feeditemtext.cxfeeditemtext').html());
this is giving the text value of span inside the first div whose class is cxfeeditem feeditem
for second div the span is not present so null.
Related
I have the following HTML structure in my document HTML STRUCTURE
[![enter image description here][1]][1]
I need to grab the info__meta-dates text so only the date using an onClick event in jQuery, this is the code that I have so far:
$("input[type=checkbox]").click(function (e) {
$(this)
.parent()
.parent()
.parent()
.find(".info__meta--dates")
.text()
);
});
But I also get the date text that is within the nested span.
You can clone that span tag and using .remove() remove mdc-typography--caption from the cloned element so that final result will be only the text which you needed
Demo code :
$("input[type=checkbox]").click(function(e) {
var texts = $(this).closest(".ev-info_meta").find(".info__meta--dates").clone(); //clone that span tag
texts.find('span.mdc-typography--caption').remove(); //remove elemnt with class mdc-typography--caption
console.log(texts.text().trim()); //show
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="ev-info_meta">
<span class="info__meta--dates"><span class="mdc-typography--caption">dates</span> fffff</span>
<div>
<input type="checkbox">
</div>
</div>
As there is no direct element to get the date, you can try the above method explained by Swati and if you are not willing to remove the element from the DOM then try the string manipulation method.
The below method only works for this scenario.
$("input[type=checkbox]").click(function (e) {
let dateString = $(this).parent()
.parent()
.parent()
.find(".info__meta--dates")
.text()
);
//removing the "date" string from the entire string
let date = dateString.substring(4,dateString.length).trim();
console.log(date);
});
I need a JavaScript or jQuery way of extracting the Class name of DIV element by the text it contains.
Let's illustrate. If I had let's say following code:
<div class="_className">UniqueText</div>
I need to to know how to programmatically do something like this:
getClassNameWhereText("UniqueText");
In this case output should be:
_className
Is there a way to do this?
JQuery :contains selector select element has specific text but it isn't exact. For example
$("div:contains(UniqueText)")
Select both of bottom divs
<div class="_className">UniqueText</div>
<div class="_className2">UniqueText2</div>
You can use .filter() to filter selected element by text.
var className = $("*").filter(function(){
return $(this).text() == "UniqueText";
}).attr("class");
var className = $("*").filter(function(){
return $(this).text() == "UniqueText";
}).attr("class");
console.log(className);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="_className">UniqueText</div>
<div class="_className2">UniqueText2</div>
By getting all the div with each function you can search through all the divs and place a condition in which you the value of the div is equal to the particular text that you want to find. Then get the class name by using .attr('class').
$( "div" ).each(function(){
if($(this).text() == "UniqueText"){
var output = $(this).attr('class');
$(".output").html(output);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="_classname">UniqueText</div>
<div class="output"></div>
It might be a bit long for a code but it gets the work done nicely. :)
You can use :contains(word)
var className = $( "div:contains('John')" ).attr("class");
console.log(className)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="foo">John Resig</div>
<div class="bar">George Martin</div>
<div class="foo">Malcom John Sinclair</div>
<div class="baz">J. Ohn</div>
You can keep an id for your div, as per your information your text will be unique.
<div id="UniqueText" class="_className">UniqueText</div>
and the js code will be
function getClassNameWhereText(text){
var className = $('#'+text).attr('class');
console.log(className);
}
UPDATE : if you want to using contains
then you can do this,
function getClassNameWhereText(text){
var val = document.getElementById(text).value;
if(text.indexOf(val)>=0){
var className = $('#'+text).attr('class');
console.log(className);
}
}
This should be faster than using jQuery (but a bit more to type):
var xpath = "//div[text()='UniqueText']";
var result = document.evaluate(xpath,
document, null, XPathResult.FIRST_ORDERED_NODE_TYPE);
var node = result.singleNodeValue;
if (node) {
console.log(node.className);
} else {
console.error("Not found!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="_className">UniqueText</div>
The reason is, browser's CSS selectors don't support :contains selector, and jQuery needs to emulate it by checking every node matching the rest of the selector. Ditto for using .filter. But XPath is done natively by the browser.
You also cannot specify exact match using the jQuery :contains, like here. If substring matching was indeed needed, you can change the XPath:
var xpath = "//div[contains(text(),'UniqueText')]";
XPath is very powerful, but a bit finicky and largely unknown, so I find it is very under-utilised, even when its use would be a perfect fit.
Is there a way to assign nested div attribute with variable? Like
<div>
<div>
123456
</div>
</div>
Become
<div>
<div sectionid="123">
123456
</div>
</div>
BTW above component will be created by JavaScript.
I've tried something like this, but it didn't work.
var a = $('<div><div>123456</div></div>');
a.eq(":nth-child(2)").attr("sectionid", "123");
Try this snippet.
//FOR DOM HTML
console.log("FOR DOM HTML");
//1st way
$('#input > div').find('div').attr("sectionid","123");
console.log($('#input').html());
//2nd way
$('#input > div > div').attr("sectionid","321");
console.log($('#input').html());
//JS HTML
console.log("FOR JS OBJECT");
var input = $('<div><div>123456</div></div>');
//1st way
input.eq(0).children().attr('sectionid', '456');
console.log(input[0].outerHTML);
var input = $('<div><div>123456</div></div>');
//2nd way
$(input[0]).children().attr('sectionid', '789');
console.log(input[0].outerHTML);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="input">
<div>
<div>
123456
</div>
</div>
</div>
nth-child(2) maches elements that are the second child element of their parent. This is not the case for your div, it is the first element of the parent div.
.eq finds an element at a specific index. It is not the place to pass a selector.
The child selector, >, will find a child element, i.e. div>div will find a div that is an immediate child of a div.
Note that the code you've provided, $('<div></div>123456<div></div>');, doesn't create a DOM tree like the one you've pasted.
Update, now that the code is edited, the value of a is a div with a child div. Since a.find will perform a search within a, you don't have to use a child selector, but can find the div immediately:
a.find('div')
Just apply attribute to children. No complicated 'find', eq(), etc.
var a = $('<div><div>123456</div></div>');
a.children().attr('sectionid', '123');
$('body').append(a);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Why don't you add it in the first place? Not clear if you add it later!
$(document).ready(function() {
var sectionid = "123";
var a = $('<div><div sectionid="' + sectionid + '">123456</div></div>');
$('body').append(a);
});
div[sectionid]{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Try this - I have added comments to the code to explain what is happening.
Inspect the element to see that the attribute is added
var a = $('<div><div>123456</div></div>'); // change this to match the structure you want
a.children() // .children gets the direct descendant (which should be the nested div
.eq(0) // gets the first in the array that is returned (if there are multiple direct descendents) - it is a 0 based index selector
.attr('sectionid', '123');
$('body').append(a)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
More information about .children()
More information about .eq()
try it :
$(document).ready(function(){
$("div").eq(1).attr("sectionid","123");
})
I want to be able to remove HTML elements if they contain no content.
Let's say we have some markup and are targeting all 'collapse' classes:
<div class='collapse'>[CONTENT?]</div>
If there is some content then don't do anything.
But if there is no content - no string characters or whitespace - then remove the div element completely.
This is easy to implement in the simple cases but with nested content it's slightly more more tricky.
Here is a demo, if you try removing the [CONTENTX?] strings and then seeing what the HTML structure is you'll notice that it doesn't work completely.
If a div only has other divs with no content then that should be treated as no characters or whitespace.
If we remove all [CONTENTX?] strings then we should see no HTML structure.
What ways are there to handle this?
jsFiddle: http://jsfiddle.net/97udq/
HTML:
<div id='container'>
<div class='collapse'>
[CONTENT1?]
</div>
<div class='collapse'>
[CONTENT2?]
<div class='collapse'>
[CONTENT3?]
<div class='collapse'>[CONTENT4?]</div>
<div class='collapse'>[CONTENT5?]</div>
</div>
</div>
</div>
Javascript:
$(function(){
// function
collapse();
// Show HTML structure
alert($('#container').html());
});
function collapse(){
// Loop thru all collapse elements
$('.collapse').each(function(){
// Check for pure whitespace
if($(this).html().replace(/\s+/g, '').length==0){
// Nothing to see, so remove.
$(this).remove();
}
});
}
CSS:
.collapse{
height:20px;
border:1px solid red;
}
I think this does the job;
It just uses text() instead of html();
Here's the documentation.
This one adds the trim(), but I thik that's not what you want.
function collapse(){
$('.collapse').each(function(){
if($(this).text().length==0){
$(this).remove();
}
});
}
Here's another way of accomplishing what you want. It recurses down the DOM pruning nodes from the bottom up. Hope this helps.
function prune(root) {
$.each($(root).children(), function(){
prune($(this));
});
if($(root).html().replace(/\s+/g, '').length==0 && $(root).hasClass("collapse")){
$(root).detach();
}
}
Code integrated into your JSFiddle
You need to recreate the .each() loop, but reversed. Just like that :
function collapse(){
var el = $('.collapse');
for(var i = el.length - 1; i >= 0; i--){
if(el[i].innerHTML.replace(/\s+/g, '').length==0){
$(el[i]).remove();
}
}
}
It will remove the childrens first, then check for parent.
Here a fiddle : http://jsfiddle.net/97udq/5/
EDIT :
I missunderstood your question, here's the right solution :
function collapse(){
$('.collapse').each(function(){
var $this = $(this)
var clone = $this.clone();
clone.children().remove();
if(clone.html().replace(/\s+/g, '').length==0){
$this.children().appendTo($this.parent());
$this.remove()
}
})
}
Basicly, you clone the current div, remove its children and then check if there is some text. If there's none, you append his children to his parent
Fiddle : http://jsfiddle.net/97udq/9/
I have some markup where a lot of id's have an id attribute, as well as innerText. I want to select each of these elements, performing a function on the id.
How do I do that?
Something like this?
$('[id]:not(:empty)').each(function(i, el) {
// do stuff
});
Give them a common class:
HTML
<div id="first" class="all"></div>
<div id="second" class="all"></div>
<div id="third" class="all"></div>
jQuery
$('div.all').each(function(index){
processid(this.id);
});
If you are talking about selecting elements whose id (or some permutation of it) is included in its text then
$('[id]').filter(function(){
return $(this).text().indexOf( this.id ) >= 0; // the this.id should be altered to match the permutation you seek ..
}).css('color','red'); // turn those to red
After you comment to #lonesomeday (at the question comments) here is what to do ..
$('[id]').each(function(){
processid(this.id);
});
First select by a regular ID selector and then loop over that selection by filtering .text() non-empty.
$("[id]").each(function() {
if ($(this).text() != "") {
// do stuff
}
});