Append HTML inside nested classes - javascript

I'm trying to use jQuery to loop through classes and append some text to an HTML element. I'm working with the following HTML (example case):
<div class="question">
<div class="title">
<strong>Here's the question title.</strong>
</div>
<div class="choice">Here's choice1.</div>
<div class="choice">Here's choice2.</div>
</div>
<div class="question">
<div class="title">
<strong>Here's the question title.</strong>
</div>
<div class="choice">Here's choice1.</div>
<div class="choice">Here's choice2.</div>
</div>
So what I'm trying to do is loop through each question on the page, see if the title matches some string, then append some text based on that statement. I have the following:
$('.question').each(function() {
var title = $(this).find('.title').innerHTML;
$('.choice').each(function() {
var span = document.createElement("span");
if (title == "someString")
{
span.className = "someClass";
}
else
{
span.className = "someOtherClass";
}
var text = document.createTextNode("text");
span.appendChild(text);
$(this).appendChild(span);
});
// put this in to see if outer loop was working
document.body.style.backgroundColor = "orange";
});
The text will change color based on what the title is, hence the different CSS classes. But it doesn't seem to be doing anything, not even appending the text to each choice. The background color does change to orange, and Chrome isn't throwing any errors from the script in the developer tools, so I'm totally lost. Can anyone help?

You can get the title like this:
var title = $(this).find('.title strong').text();
Here you're confusing jquery with native javascript, $(this) is a jquery object so you cannot use appendChild() here's how you change that:
$(this).get(0).appendChild(span);
Or you can use jQuery directly:
$(this).append(span);

Using Arun P Johny's fiddle, I've updated a few things;
FIDDLE
The following are the important changes;
var title = $.trim($(this).find('.title').text());
$(this).find('.choice').each(function () {...
Changing $('.choice') to $(this).find('.choice') because you only want to change the elements within that question, not every choice element on the page.
and find('.title').innerHTML; to find('.title').text()); because you only want to match the text within that div, not the html as well.

Something like this?:
Jsfiddle
jQuery ( Comment free code in the jsfiddle ):
// On document ready...
$(function () {
// Geat each title element...
$('.title').each(function () {
// Points to each title element as defined above
var title = $(this),
// Get all siblings of title element(s)
choices = title.siblings(),
// Ternary if statement. Equivalent to if ( X ) {} else {}
myClass = title.text().trim() === "Here's the question title." ? "someClass" : "someOtherClass";
// Make a span element...
$('<span />', {
class: myClass, // Give it a class
text: " Appended text" // Give it some text
}).appendTo(choices); // Append the span to each .choice element
});
});
Html:
<div class="question">
<div class="title"><strong>Here's the question title.</strong></div>
<div class="choice">Here's choice1.</div>
<div class="choice">Here's choice2.</div>
</div>
<div class="question">
<div class="title"><strong>Here's the question title.</strong></div>
<div class="choice">Here's choice1.</div>
<div class="choice">Here's choice2.</div>
</div>
<div class="question">
<div class="title"><strong>Here's title.</strong></div>
<div class="choice">Here's choice1.</div>
<div class="choice">Here's choice2.</div>
</div>
Css:
.someClass {
color: red;
}
.someOtherClass {
color: green;
}
.question { margin: 10px 0px; }

Related

Use variable as selector in function

On click, I want to get the name of the closest div and then look for all div's, that have this name attribute and add a class to them.
Here is my code:
HTML:
<div class="wrapper">
<div class="container" name="button1">
<div class="button">this is p #1</div>
</div>
</div>
<div name="button1">
somewhere else
</div>
JS:
$('.wrapper').on("click", '.button', function() {
var attrname = $(this).closest('.container').attr('name');
$("div[name=attrname]").each(function() {
$(this).addClass("classtobeadded");
});
});
But it is not working. So, how can I use the variable in here:
$("div[name=attrname]").each(function()
Here is the fiddle:
There's a few issues with your logic. Firstly the .container element does not have the name attribute, the .button does, so you don't need to use closest(). Secondly, you need to concatenate the actual name value in to the selector. Lastly div elements do not have a name attribute so the HTML is invalid. If you want to store custom meta-data on an element use a data attribute instead.
Also note that you don't need the each() loop, you can just call addClass() on the collection selected with the data-name attribute. Try this:
$('.wrapper').on("click", '.button', function() {
var attrname = $(this).data('name');
$('div[data-name="' + attrname + '"]').addClass("classtobeadded");
});
.classtobeadded {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="container">
<div class="button" data-name="button1">this is p #1</div>
</div>
</div>
<div data-name="button1">
somewhere else
</div>
You have to concatenate it properly,
$(`div[name=${attrname}]`).each(function() {
And by the way, when looking at your code there is no attribute available in the closest div with a class .container. Check that as well.
$("div[name=" + attrname + "]").each(function() {})
or
$(`div[name=${attrname}]`).each(function() {})

Is there any inbuild function in javascript to select last element with using class selector or element selector?

similar type of question is already asked link.but my question is bit diffrent.
in my program frequently occur new element with using dom. here my question is
is there any built in function in javascript that i can select last element frequently?
here is an example
var para = document.createElement("div");
var node = document.createTextNode("This is new.");
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
given program append div element frequently and also i want to select div element frequently. similar with a class
thankyou in advance
Use querySelectorAll and pass the class selector. Then target the last element and do whatever
let getAllElem = document.querySelectorAll('.test');
getAllElem[getAllElem.length - 1].classList.add('green')
.green {
color: green
}
<div class="test">1</div>
<div class="test">2</div>
<div class="test">3</div>
<div class="test">4</div>
<div class="test">5</div>
<div class="test">6</div>
no there is not any built in function in java script but u should try below logic and use it with jquery like $(last_selector(".lastclass")).click(); for select last class and $(last_selector("div")).click(); for elect last element
function last_selector(select){
if(select[0]=="."){
var allSelect = document.getElementsByClassName(select.slice(1));
}
else{
var allSelect = document.getElementsByTagName(select);
}
return allSelect[allSelect.length-1];
}
console.log(last_selector("div"))
console.log(last_selector(".last"))
<div>hello</div>
<div>hello</div>
<div class="last">last class</div>
<div>last element</div>
It will give last span text inside every Div using $(elementName).children("span:last").text()
$(document).ready(function(){
console.log($('div').children("span:last").text())
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="time">2016</span><br>
<span class="time">2017</span><br>
<span class="time">2018</span><br>
<span class="time">2019</span><br>
<span class="time">2020</span><br>
<span class="time">2021</span><br>
<span class="time">2022</span><br>
<span class="time">2023</span><br>
<span class="time">2024</span> <br>
</div>

Hide div that contains specific text

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

How to get DIV ID on click

I am new to javascript and couldnt find answer online (I feel like its out there since this seems pretty simple thing, I might not be using the right search terms though)
I am working with the code in this jfiddle:
http://jsfiddle.net/ApoG/f7qqq6k2/4/
$('.item').click(function(){
if( document.getElementById("one").style.display != "none") {
document.getElementById("one").style.display = "none";
} else {
document.getElementById("one").style.display = "block";}
var $this = $(this),
tileStyle = $this.hasClass('big') ? { width: 50, height: 50} : { width: 170, height: 110};
$this.toggleClass('big');
$this.find('.item-content').stop().animate( tileStyle );
$container.isotope( 'reLayout' )
});
When you click a div, it takes the 'item' class and changes its properties.
My goal is to have image or one type of text in a widget when its small and another text or image when its expanded on click. I am going to achieve that by changing div custom properties when its clicked using an if statement in my javascript. (right now testing with changes to display)
My questions is...since 'item' class is selected on click, how can I get the DIV ID on click? (right now I hard coded div id)
Thank you.
With JQuery:
$('div').click(function(){
alert(this.id);
});
JSFiddle Demo, with your full code
With Pure JS:
var div = document.getElementsByTagName("div");
for(var i=0; i<div.length; i++){
div[i].onclick = function(){
alert(this.id);
}
}
JSFiddle Demo
Thank you for the toggle tip. I used that to make my code work and show different things in the box depending on the click of the div.
Here is what I ended up doing:
https://jsfiddle.net/ApoG/z3x6hqLe/
<script>
function toggleText1() {
$('#one_one').toggle();
$('#one_two').toggle();
}
function toggleText2() {
$('#two_one').toggle();
$('#two_two').toggle();
}
</script>
<div id="container">
<div class="item">
<div id=one style=display:"none" class="item-content" onclick="toggleText1()">
<div id=one_one class="text" >Show More</div>
<div id=one_two class="text" style="display:none">Show Less</div>
</div>
</div>
<div class="item">
<div id=two style=display:"none" class="item-content" onclick="toggleText2()">
<div id=two_one class="text" >Show More</div>
<div id=two_two class="text" style="display:none">Show Less</div>
</div>
</div>
<div class="item">
<div id=three style=display:"none" class="item-content"></div>
</div>
</div>
I am definitely sure there is a more optimal way to define all the toggle but as I mentioned earlier I am a complete newb so hopefully with more tinkering I will figure that one out.

Javascript onmouseover and onmouseout

You can see in the headline what it is. I've four "div", and therein are each a p tag. When I go with the mouse on the first div, changes the "opacity" of the p tag of the first div. The problem is when I go on with the mouse on the second or third "div" only changes the tag "p" from the first "div". It should changes the their own "p" tags.
And it is important, that i cannot use CSS ":hover".
The problem is clear, it is that all have the same "id".
I need a javascript which does not individually enumerated all the different classes.
I' sorry for my english.
I hope you understand me.
My script:
<div onmouseout="normal();" onmouseover="hover();" >
<p id="something">LOLOL</p>
</div>
<div onmouseout="normal();" onmouseover="hover();" >
<p id="something">LOLOL</p>
</div>
<div onmouseout="normal();" onmouseover="hover();" >
<p id="something">LOLOL</p>
</div>
<div onmouseout="normal();" onmouseover="hover();" >
<p id="something">LOLOL</p>
</div>
Javascript:
function normal() {
var something = document.getElementById('something');
something.style.opacity = "0.5";
}
function hover() {
var something = document.getElementById('something');
something.style.opacity = "1";
CSS:
p {
opacity: 0.5;
color: red;
}
As Paul S. suggests, you need to pass this to the function so that it knows which element it has to work on.
<div onmouseout="normal(this);" onmouseover="hover(this);" >
<p>LOLOL</p>
</div>
<div onmouseout="normal(this);" onmouseover="hover(this);" >
<p>LOLOL</p>
</div>
<div onmouseout="normal(this);" onmouseover="hover(this);" >
<p>LOLOL</p>
</div>
<div onmouseout="normal(this);" onmouseover="hover(this);" >
<p>LOLOL</p>
</div>
And then select the child element <p> for the passed <div>. Here I select the first child p, i.e. the first element in the array of children of this element with tag p, that's why you see [0]. So if in each div you had two paragraph, then you could use e.g. getElementsByTagName("p")[1] to select the second <p>.
function normal(mydiv) {
mydiv.getElementsByTagName("p")[0].style.opacity="0.5";
}
function hover(mydiv) {
mydiv.getElementsByTagName("p")[0].style.opacity="1";
}
See the working example here: http://jsfiddle.net/mastazi/2REe5/
Your html should be something like this:
<div onmouseout="normal(1);" onmouseover="hover(1);">
<p id="something-1">LOLOL</p>
</div>
<div onmouseout="normal(2);" onmouseover="hover(2);">
<p id="something-2">LOLOL</p>
</div>
<div onmouseout="normal(3);" onmouseover="hover(3);">
<p id="something-3">LOLOL</p>
</div>
<div onmouseout="normal(4);" onmouseover="hover(4);">
<p id="something-4">LOLOL</p>
</div>
As you can see, we have different ids for your elements, and we pass the ids through the function that we trigger with onlouseover and onmouseout.
For your javascript, your code could be something like this:
function normal(id) {
var something = document.getElementById('something-'+id);
something.style.opacity = "0.5";
}
function hover(id) {
var something = document.getElementById('something-'+id);
something.style.opacity = "1";
}
For normal() and hover() we receive an id and change the style for the current element that have this id.
Please, check this JSFiddle that I've built for you.

Categories

Resources