I want to hide a div based on the text inside. In the example below I want to hide the ones with "Handtekening" and the one with "Thuis". I prefer to do that with CSS. Is that possible?
The class names of the divs have to be the same...
<div class="test">
Pakket
</div>
<div class="test">
Handtekening
</div>
<div class="test">
Thuis
</div>
If not possible with CSS, how can it be done with JavaScript?
Here's an easy vanilla Javascript solution:
const divs = document.getElementsByClassName('test');
for (let x = 0; x < divs.length; x++) {
const div = divs[x];
const content = div.textContent.trim();
if (content == 'Handtekening' || content == 'Thuis') {
div.style.display = 'none';
}
}
Working JSFiddle here
Remember to include the script at the end of your HTML page (right before the </body> tag).
If you have control over the HTML output and have no problems with the text document getting twice as big, you can duplicate the content of each of those divs. Otherwise JavaScript is the way to go. Here is the CSS solution:
<div class="test" content="Pakket">
Pakket
</div>
<div class="test" content="Handtekening">
Handtekening
</div>
<div class="test" content="Thuis">
Thuis
</div>
Then use the selector for an attribute containing a string:
div[content~=Thuis] { display:none; }
The one above will match when "Thuis" is contained in the text as a separate word. If you want to match any occurrence of the string, you should use:
div[content*=and] { display:none; }
No, it won't be possible with pure CSS. You need to use JavaScript to do it.
This is code you can use for that:
var divs = document.querySelectorAll(".test");
Array.from(divs).forEach(function(div) {
if (div.textContent.indexOf("Handtekening") >= 0 || div.textContent.indexOf("Thuis") >= 0) {
div.style.display = "none";
}
});
var divs = document.querySelectorAll(".test");
Array.from(divs).forEach(function(div) {
if (div.textContent.indexOf("Handtekening") >= 0 || div.textContent.indexOf("Thuis") >= 0) {
div.style.display = "none";
}
});
<div class="test">
Pakket
</div>
<div class="test">
Handtekening
</div>
<div class="test">
Thuis
</div>
Here's one more solution:
Array.from( document.querySelectorAll('div.test') )
.filter( node => /\b(Handtekening|Thuis)\b/i.test(node.textContent) )
.forEach( node => node.style.display = 'none' );
<div class="test">
Pakket
</div>
<div class="test">
HANDTEKENING
</div>
<div class="test">
Test thuis blah blah
</div>
The main difference from chsdk's solution is that I'm using a single regexp test instead of multiple .indexOf() calls. IMO this is cleaner, more flexible and possibly more efficient as well.
The \b anchors in the regexp match word boundaries, so that e.g. "Thuis test" is matched but "Thuistest" is not. I suspect this is what the OP wants, but if not, the \b anchors can easily be removed and/or replaced with something else. For example, the regexp:
/^\s*(Handtekening|Thuis)\b/i
would match only if the words "Handtekening" or "Thuis" occur at the beginning of the content (possibly after some whitespace). Replacing the second \b with \s*$ would also require there to be nothing (except possibly whitespace) after the matched word.
The i flag at the end of the regexp literal makes the matching case-insensitive. If not desired, the i can simply be removed. I wanted to include it for illustrative purposes, though.
Ps. Some older browsers (such as, notably, Internet Explorer) may not support the ES6 arrow functions and the Array.from() method used in the code above. If compatibility with such old browsers is desired, here's an alternative implementation free from any such newfangled stuff:
var nodes = document.querySelectorAll('div.test');
for (var i = 0; i < nodes.length; i++) {
if ( /\b(Handtekening|Thuis)\b/i.test(nodes[i].textContent) ) {
nodes[i].style.display = 'none';
}
}
<div class="test">
Pakket
</div>
<div class="test">
HANDTEKENING
</div>
<div class="test">
Test thuis blah blah
</div>
AFAICT, this should be compatible with IE down to version 9, and of course with all modern browsers as well.
You could do the easy thing of hiding the elements with a second class.
So let's say we'll add the class="hidden".
See the example below:
.test {
color: blue;
}
.hidden {
display: none;
/* or visibility: hidden; */
}
<div class="test">
Pakket
</div>
<div class="test hidden">
Handtekening
</div>
<div class="test hidden">
Thuis
</div>
By adding the second class we're able to make a selection of which <div> element you'd like to show and which not.
To select elements based on text you can use js and check if text is equal to ones you want to hide. If it is you can set display property to none to hide that element.
[...document.querySelectorAll('.test')].forEach(function(e) {
if (['Handtekening', 'Thuis'].includes(e.textContent.trim())) {
e.style.display = 'none'
}
})
<div class="test">
Pakket
</div>
<div class="test">
Handtekening
</div>
<div class="test">
Thuis
</div>
You can do it just like this,
let filteredOut = ['Handtekening', 'Thuis'];
Array.from(document.querySelectorAll(".test")).forEach((elm) => {
if(filteredOut.includes(elm.textContent.trim())) elm.style.display = "none";
});
DEMO
Collect the values that are needs to be filtered out in a separate array.
Iterate over all the elements and check its value presents in the filter array.
If it exists, just hide it.
Side Note: You can use a class to add to the caught elements instead of inserting inline styles.
With CSS 3: no
With JavaScript: yes
With XPath: yes (something like //div[contains(text(),'Handtekening')]/.)
You can test your XPath here.
You can do it with JavaScript:
var elements = document.getElementsByClassName('test');
for(var i = 0; i<elements.length; i++){
if(elements[i].innerText==='Handtekening' || elements[i].innerText==='Thuis'){
elements[i].style.display = 'none';
}
}
<div class="test">
Pakket
</div>
<div class="test">
Handtekening
</div>
<div class="test">
Thuis
</div>
Here's pure JavaScript solution:
// Define your variables
var objectsToCheck = document.getElementsByClassName("test");
var hideText = "Pakket";
// Loop through your div objects
[].forEach.call(objectsToCheck, function (o) {
// Check if text appears in div under class "test"
if(o.innerText.toLowerCase() == hideText.toLowerCase()){
o.style.display = "none";
}
});
You can use querySelector to fetch elements and use element.classList.toggle to add/remove a class that will hide the value.
document.querySelector('#btn').addEventListener('click', function(){
var text = document.querySelector('#txt').value.trim();
var list = document.querySelectorAll('.test');
for(var i = 0; i< list.length; i++) {
list[i].classList.toggle('hide', list[i].textContent.trim() === text);
}
})
.hide {
display: none;
}
<div class="test">
Pakket
</div>
<div class="test">
Handtekening
</div>
<div class="test">
Thuis
</div>
<input type='text' id='txt' />
<button id='btn'>Hide Div</button>
You also have jQuery that makes this easy if you already use this
library: contains(text).
text: A string of text to look for. It's case sensitive.
The matching text can appear directly within the selected element, in any of that element's descendants, or a combination thereof. As with attribute value selectors, text inside the parentheses of :contains() can be written as a bare word or surrounded by quotation marks. The text must have matching case to be selected.
$( ".test:contains('Thuis'),.test:contains('Handtekening')" ).css( "display", "none" );
https://codepen.io/gc-nomade/pen/zEMbLz
I have two div's and what I am trying to do is loop through all the divs to check if the div has a class jsn-bootstrap3, I'm also trying to check to see if the div has any other classes, if it doesn't then I'd like to remove the jsn-bootstrap3 div so that the child content is whats left.
<div class="jsn-bootstrap3">
<div class="wrapper">
Div one
</div>
</div>
<div class="jsn-bootstrap3 block">
<div class="wrapper">
Div two
</div>
</div>
$('div').each(function() {
if ($(this).hasClass()) {
console.log($(this));
var class_name = $(this).attr('jsn-bootstrap3');
console.log(class_name);
}
});
jsFiddle
You can try something like
$('div.jsn-bootstrap3').removeClass('jsn-bootstrap3').filter(function () {
return $.trim(this.className.replace('jsn-bootstrap3', '')) == ''
}).contents().unwrap();
Demo: Fiddle
use the class selector to find div's with class jsn-bootstrap3 because we are not goint to do anything with others
use filter() to filter out div's with any other class
use unwrap() with contents() to remove the wrapping div
I want to check if there is only one div with an error class. And if so, I want to .select() the content of the input (that's in the in corresponding input class div).
How would I do such thing?
My attempt which does not work:
if($("div.addition").hasClass(".error").length === 0) {
(this).parent().find('input').select();
}
HTML
<form>
<div class="input">
<input type="text">
<div>
<div class="addition">Message message.</div>
</div>
</div>
<div class="input">
<input type="text">
<div>
<div class="addition">Message.</div>
</div>
<div class="input">
<!-- So in this case this input's content will be selected -->
<input type="text">
<div>
<div class="addition error">Error message.</div>
</div>
</div>
</form>
Here's a jsFiddle that should do it - I mentioned as a comment to your post that you're missing a </div> tag, that is fixed in the fiddle - without it, the jquery selector matches two inputs. Outline of the js:
if ($('div.error').length === 1) {
errorContent = $('div.error').parents('div.input').find('input').val();
alert(errorContent);
}
Here's a plain JavaScript implementation. No need to use jQuery unless you're already using it.
var errors = document.getElementsByClassName('error');
if(errors.length === 1){
//If there is one class with error
var content = errors[0].innerHTML;
} else{
//there is more than one error class.
}
I want to check if there is only one div with an error class.
if ($("div.error").length === 1) {
// Exactly one div with the class "error"
}
else {
// Zero or more than one
}
By using jQuery it can be done like:
$(document).ready(function(){
var div = $('.error');
if(div.length){
var val = div.parents('.input:first').find('input').val();
//val is the value of input
}
});
I am trying to hide all the divs inside of the container div section exempt the first one.
Here is my html:
<div id="main">
<div id="first">
First div
</div>
<div id="second">
Second div
</div>
<div id="third">
Third div
</div>
</div>
And here is my JavaScript:
function hide(){
var target = document.getElementById("main"),
childList = target.childNodes,
i = 1;
for( ; i < childList.length; i++){
if(childList[i].nodeName !== "#text"){
childList[i].style.display = 'none';
};
};
}
It seems that this should work and hide all divs exempt the first oneā¦ But it doesn't. It hides all of the elements. There are no errors in the console.
How can I fix this?
Thank you.
You are using childNodes instead of children. In this case you should be using children.
childList = target.children
Have a look to this answer: What is the difference between children and childNodes in JavaScript?
I use jQuery to append the content into each contentx class like.
<div id="sidebar">
<div class="contentx"></div>
<div class="contentx"></div>
</div>
<script>
$("#sidebar .contentx").each(function()
{
//Append here
}
</script>
After Append I have, for example :
<div id="sidebar">
<div class="contentx">
something 1 is inserted here.
</div>
<div class="contentx">
something 2 is inserted here.
</div>
</div>
but I want to remove class="contentx" whenever the content is appended. This mean I have only :
<div id="sidebar">
something 1 is inserted here.
something 2 is inserted here.
</div>
How
Option 1
If you just want to remove the class "contentX" from the div after the content has been added, you can try the following:
$('#sidebar .contextX').each(function () {
// Append here.
}).removeClass('contextX');
EDIT: Seems I misread the question a little (based on your indicated desired output).
Option 2
If you want to remove the entire element and replace it with the content of your choice? For that, you can try:
$('#sidebar .contextX').each(function () {
$(this).replaceWith('<new content here.>');
});
jQuery replaceWith
Besides the append, call removeClass
$("#sidebar .contentx").each(function()
{
//Append here
$(this).removeClass('contentx');
}
Try this
var tmp = $(".contentx").html();
$('.contentx').append(tmp);
var tmp2 = $(".contentx").html();
$('.contentx').remove();
$('#sidebar').append(tmp2);