Jquery tranversing DOM to find consecutives values - javascript

Thanks for looking, all helpful answers are voted up.
This is my markup. I'm trying to find 2 consecutive divs cmk1 and cmk2 with the content RIGHT and HERE in consecutive order.
div id 1 shouldn't match because there's a right but not here.
div id 3 shouldn't match because there's a here but no right.
I'm trying to find something that looks like div id 2 where right is followed by here. Also the text has to be exact: <div>more than right</div> should not match even though it contains the word right
What's the most efficient way to do this?
Update: I just had a thought, I could find each class=cmk1. if it matches RIGHT, I could select its next (cmk2) and if it matches also, that's what I'm looking for. But how do I do this while loop in jquery? and most importantly how do I exit out of it?
<div class="sep" id="1">
<div class="cmk1">right</div>
<div class="cmk2">valc</div>
<div class="opp">vald</div>
<a class="go">Go</a>
</div>
<div class="clear">
<div class="sep" id="12">
<div class="cmk1">RIGHT</div>
<div class="cmk2">HERE</div>
<div class="opp">vala</div>
<a class="go">Go</a>
</div>
<div class="clear">
<div class="sep" id="59">
<div class="cmk1">vale</div>
<div class="cmk2">valf</div>
<div class="opp">here</div>
<a class="go">Go</a>
</div>
<div class="clear">

$('div.sep > div').each(function() {
if($(this).text() == 'RIGHT') {
if($(this).next('div').text() == 'HERE') {
alert('Values occur consecutively in div id: ' + $(this).parent().attr('id'));
return false;
}
}
});
I've basically looped over all the child divs of the each .sep div and tested for the first word. If it is matched, next can be used to determine if the next div contains the second word.

$(':contains(RIGHT) :contains(HERE)')

Try:
$(':contains(right), :contains(here)')
.filter( function() {
return ( $(this).text() == 'right' && $(this).next().is(':contains(here)') ) ||
( $(this).text() == 'here' && $(this).prev().is(':contains(right)') );
} );
The only drawback is this is case sensitive.

Related

How to show element only if other element contains something using jQuery?

My guess is what I want to achieve should be easy, but due to my lack of knowledge of front-end development, I cannot manage to solve issue. Have a page that works with AJAX-filters that users can select. Filters that are currently applied show up within <div> with id=current-filters.
HTML looks like this:
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<!-- here every single applied filter is displayed -->
</div>
</div>
</div>
Need to hide the the entire DIV current-filters-box in case no filter is applied.
The page uses a Javascript file, bundle.js which is massive, but contains the following line:
s=document.getElementById("current-filters")
Therefore tried the following if-statement to hide the DIV:
if(s.length<1)$('#current-filters-box').hide()
and
if(s=0)$('#current-filters-box').hide()
But this does not seem to have any effect. Can someone tell, what I did wrong?
Demo of page can be found here
EDIT: this is what the HTML looks like when filters are applied:
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<div class="badge-search-public">
<strong>Humanities & Languages</strong> <span class="x" data-property="disciplines" data-value="4" onclick="filter.removeFilter(this)">×</span>
</div>
<div class="badge-search-public">
<strong>January</strong> <span class="x" data-property="months" data-value="1" onclick="filter.removeFilter(this)">×</span>
</div>
</div>
</div>
Both of your conditions are incorrect or I would say they are not doing what you think they do.
s.length will always prints undefined so instead of s.length<1 you could use s.children.length
and the second one is not a condition rather it is an assignment
s==0 // condition
s=0 //assignment
the correct condition for your requirement would be
if(s.children.length<1){
I have assigned snippets for illustration.
Without filters
s = document.getElementById("current-filters")
console.log(s.children.length);
if (s.children.length < 1) {
$('#current-filters-box').hide(1000)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="current-filters-box">
filter box
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<!-- here every single applied filter is displayed -->
</div>
</div>
</div>
Without filters
s = document.getElementById("current-filters")
console.log(s.children.length);
if (s.children.length < 1) {
$('#current-filters-box').hide(1000)
}
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<div class="badge-search-public">
<strong>Humanities & Languages</strong> <span class="x" data-property="disciplines" data-value="4" onclick="filter.removeFilter(this)">×</span>
</div>
<div class="badge-search-public">
<strong>January</strong> <span class="x" data-property="months" data-value="1" onclick="filter.removeFilter(this)">×</span>
</div>
</div>
</div>
Try this .
if( $('#current-filters').is(':empty') ) {
$('#current-filters-box').hide()// or $('#current-filters-box').css("display","none")
}
You are performing an assignment, try..
if (s.children.length)
Using vanilla JavaScript, you can check if the current-filters div is empty or not and toggle the parent div current-filters-box like this:
s= document.getElementById("current-filters");
t= document.getElementById("current-filters-box");
if(s.children.length<1) {
t.style.display = 'none';
// t.style.visibility= 'hidden'; <<-- use this if you want the div to be hidden but maintain space
}
else {
t.style.display = 'block';
// t.style.visibility= 'visible'; <<-- use this if you used visibility in the if statement above
}
You can achieve this by adding your own variable which counts or maintains your applied filters, e.g.
var applied_filter_count = 0;
at every time filter is applied
applied_filter_count++;
if(applied_filter_count) {
$('#current-filters-box').show()
}
and at every time filter is removed
applied_filter_count--;
if(!applied_filter_count) {
$('#current-filters-box').hide()
}
and by default current-filters-box should be display:none

Only show parent if child contains certain string

I have a group of divs that appear on multiple pages, that have this pattern:
<div class=“entry”>
<div id=“post”>
<div class=“text”>
<div class=“service”></div>
<div class=“timeline”>
<div class=“entry-title”>
#hashtagOne
</div>
</div>
</div>
</div>
</div>
<div class=“entry”>
<div id=“post”>
<div class=“text”>
<div class=“service”></div>
<div class=“timeline”>
<div class=“entry-title”>
#hashtagTwo
</div>
</div>
</div>
</div>
</div>
<div class=“entry”>
<div id=“post”>
<div class=“text”>
<div class=“service”></div>
<div class=“timeline”>
<div class=“entry-title”>
#hashtagThree
</div>
</div>
</div>
</div>
</div>
This group appears on multiple pages.
My ideal javascript/jquery solution is something like this:
display:none on all div class="entry"
if child div class="entry-title" contains #something, change parent div class="entry" to display:block
so that on Page One I can insert this code to only show #hashtagOne, on Page Two only #hashtagTwo, etc. etc.
Try something like this:
$('.entry-title').each(function(i,v){
if ($(this).text().trim().charAt(0) =="#") {
$(this).closest('.entry').show();
}
});
https://jsfiddle.net/0ybstx9o/
This simply works fine :
$(document).ready(function(){
$(".entry").each(function(){
if($(this).find(".entry-title:contains('#something')").length > 0){
$(this).css("display","block");
}
});
});
Its pretty simple, just use :contains() and .closest() together either on page load or whatever event you want this display:block behavior to run.
As you want to show based on differnt pages, I suggest to use page title and set it to title="Page One" and title="Page Two" etc and then compare it in document ready state and show accordingly the desired div
jQuery(document).ready(function(){
jQuery('div.entry').hide();
if(jQuery(document).find("title").text() == 'Page One')
{
jQuery( "div.entry-title:contains('#something')" ).closest('.entry').show();
}
else if(jQuery(document).find("title").text() == 'Page Two')
{
jQuery( "div.entry-title:contains('#something Else')" ).closest('.entry').show();
}
});
$(".entry").find(".entry-title").text(function(key, text) {
if (text.indexOf("#")>=0) {
$(this).parents(".entry").hide()
}
})
Here is the working Plunker

Hide parent div if child div is missing

Is it possible at all to hide a parent div if there is a child div missing?
In the example below I would like to hide the parent div of "#live-sessions" if some of the divs are missing such as .views-content and .views-row.
This is what it looks like when the divs are there:
<div id="live-sessions">
<div class="container">
<div class="row">
<div class="col-sm-3">
<h3 class="session-title">Sessions Live Now</h3>
<div class="col-sm-9">
<div class-"view-display-id-live_sessions">
<div class="views-content">
<div class="views-row">
</div>
<div class="views-row">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
This is what it looks like when the divs are missing:
<div id="live-sessions">
<div class="container">
<div class="row">
<div class="col-sm-3">
<h3 class="session-title">Sessions Live Now</h3>
<div class="col-sm-9">
<div class-"view-display-id-live_sessions">
</div>
</div>
</div>
</div>
</div>
I tried using the :empty selector with the parent method, but my child div contains some blank lines so it doesn't think it's empty. Also I would like to hide the parent of the parent of the empty div.
$(".view-display-id-live_sessions:empty").parent().hide();
You have a typo in your html:
class-"view-display-id-live_sessions"
should be
class="view-display-id-live_sessions"
you can try the following jQuery code:
if ($(".view-display-id-live_sessions").html().trim() == '') {
$(".view-display-id-live_sessions").parent().parent().hide();
}
jqVersion demo
Use jQuery has() in a negative if test - http://api.jquery.com/has/
if(!$('#parent').has('.child')){
$('#parent').hide();
}
There isn't a one-line-query for this. Following code would do the trick:
$('#live-sessions .row').each(function(idx, row) {
if ($(row).find('.views-content').length == 0) {
$(row).hide();
}
});
If you want to keep using jQuery, you could instead do:
if ( ! $(".view-display-id-live_sessions").children().length ) { /* your logic */ }
Note that there's a syntax error in your code:
<div class-"view-display-id-live_sessions">
Should be
<div class="view-display-id-live_sessions">
If you understand your question:
First you need to check the number of .views-row divs. If the length is zero hide the parent div.
Ex:
if ($('.views-row').length < 1)
$('#live-sessions').hide();
Good Luck.
You need to trim the blank spaces, correct a typo and test for the text within the div -
class="view-display-id-live_sessions" // note the equals sign after class
The code to do the hiding (EDIT re-read problem again):
var liveSessionsText = $.trim( $('.view-display-id-live_sessions').text() );
if(0 == liveSessionsText.length) {
$('.view-display-id-live_sessions').closest('.row').hide();
}
The div with class="row" is the parent of the parent of view-display-id-live_sessions.

Is it possible to re-assign a div's childs class in consecutive order with Jquery

I have the following situation where my divs childs id's need to be renamed in consecutive order starting from 1.
eg.
<div id="parent">
<div id="child-108"></div>
<div id="child-99"></div>
<div id="child-9"></div>
<div id="child-18"></div>
<div id="child-64"></div>
</div>
converted via JQuery or regular Javascript into:
<div id="parent">
<div id="child-1"></div>
<div id="child-2"></div>
<div id="child-3"></div>
<div id="child-4"></div>
<div id="child-5"></div>
</div>
Any help would be great!
Sure, you can do that with the each function:
$('#parent > div').each(function(index) {
this.id = 'child-' + (index + 1);
});
The function you pass into each is called with this pointing at the DOM element and the index argument giving the index (starting with 0) within the selected elements.

Counting div elements based on id

I have a page similar to:
<div id="content">
<div id="boxes">
<div id="box:content:1:text" />
<div id="box:content:2:text" />
<div id="another_id" />
<div id="box:content:5:text" />
</div>
</div>
I want to know the number of div with id that matches the expression box:content:X:text (where X is a number). I can use pure javascript or jquery for doing that.
But inside boxes i can have several types of divs that i don't want to count ("another_id") and i can have gaps from the X of an element and the next element, they are not in sequence.
I was searching a way to gets the elements based on a regexp but i haven't found any interesting way. Is it a possibile approach ?
Thanks
jQuery:
$("div[id]").filter(function() {
return !(/^box:content:\d+:text$/.test(this.id));
}).size();
Pure JavaScript:
var elems = document.getElementsByTagName("div"),
count = 0;
for (var i=0, n=elems.length; i<n; ++i) {
if (typeof elems[i].id == "string" && /^box:content:\d+:text$/.test(this.id)) {
++count;
}
}
To expand on Boldewyn's comment, you can provide multiple classes delimited by spaces, and then work with those classes separately or in combination.
This probably removes the need for the ids, but I've left them in just in case:
<div id="content">
<div id="boxes">
<div id="box:content:1:text" class="box content 1 text" />
<div id="box:content:2:text" class="box content 2 text" />
<div id="another_id" />
<div id="box:content:5:text" class="box content 5 text" />
</div>
</div>
And then with jQuery you can count just the desired items with:
$j('#content>#boxes>.box.content.text').length
(or perhaps just use '#boxes>.box.text' or whatever works for what you're trying to match)

Categories

Resources