Generic way to only slideToggle() child div - javascript

New to jquery. I want to do a slideToggle to accordion collaps and expand a section.
When clicking the header, I want to expand/collapse everything in "#section".
<h3 id="assignments">Assignments</h3>
<div id="section">
Assignment Count <input type="number" name="assignment_count">
</div>
I have the code that works below. But I want to make it generic so that if I have any header I click, it will only collapse the section below it and not all div's with an id of "#section"
$(document).ready(function(){
$("h3").click(function(){
$("#section").slideToggle();
});
});

You can use DOM traversal to achieve this. In the click handler for the h3, the next() function can be used to retrieve the following element. Try this:
$('h3').click(function() {
$(this).next('div').slideToggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Assignments</h3>
<div>
Assignment Count
<input type="number" name="assignment_count">
</div>
<h3>Foo</h3>
<div>
Foo Count
<input type="number" name="foo_count">
</div>
<h3>Bar</h3>
<div id="section">
Bar Count
<input type="number" name="bar_count">
</div>

You can use .next() which gets the immediately following sibling.
$(document).ready(function(){
$("h3").click(function(){
$(this).next("#section").slideToggle();
});
});
Also, since you want to make it generic do not use IDs. Use classes instead. Something like this
<h3 class="assignments">Assignments</h3>
<div class="section">
Assignment Count <input type="number" name="assignment_count">
</div>
$("h3").click(function(){
$(this).next(".section").slideToggle();
});
$("h3").click(function() {
$(this).next(".section").slideToggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3 class="assignments">Assignments 1</h3>
<div class="section">
Assignment Count
<input type="number" name="assignment_count" />
</div>
<h3 class="assignments">Assignments 2</h3>
<div class="section">
Assignment Count
<input type="number" name="assignment_count" />
</div>
<h3 class="assignments">Assignments 3</h3>
<div class="section">
Assignment Count
<input type="number" name="assignment_count" />
</div>
<h3 class="assignments">Assignments 4</h3>
<div class="section">
Assignment Count
<input type="number" name="assignment_count" />
</div>

using :header you can trigger "on" click event on any header say h1,h2,h3,h4,h5,h6..
$(document).ready(function(){
$(":header").on('click',function(){
$(this).nextUntil(":header").slideToggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 id="assignments1">Assignment1</h1>
<div id="section">
Assignment Count <input type="number" name="assignment_count">
</div>
<h2 id="assignments2">Assignments2</h2>
<div id="section">
Assignment Count <input type="number" name="assignment_count">
</div>
<h3 id="assignments3">Assignments3</h3>
<div id="section">
Assignment Count <input type="number" name="assignment_count">
</div>

Related

How to get the nearest class of separate div in jquery?

On clicking the button I want to get the closest <input name="something/> value.
I tried $(this).closest(".input").val() but didn't work.
$(document).on("click", ".button", function() {
div = `<div class="second-div"><input name="something/></div>
<div class="third-div"></div>`
// get nearest <input name="something/> value
// get nearest <input class="a-input" /> value
$(".main-div").append(div);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-div">
<div class="second-div">
<input name="something" class="input" />
</div>
<div class="third-div">
<input name="another input" class="a-input" />
</div>
<div class="fourth-div">
<button type="button" class="button">Click Me</button>
</div>
</div>
I would traverse up to the containing div first, then back down to the desired control.
$(this).closest(".main-div").find(".input");
EDIT
I just read your comment saying you want to get the last instance of a class.
$(this).closest(".main-div").find(".input").last();
EXAMPLE
$(document).on("click", ".button", function() {
div = `<div class="second-div"><input name="something" class="input"/></div>
<div class="third-div"></div>`
$(".input").removeClass("highlight");
$(this).closest(".main-div").find(".input").last().addClass("highlight");
// get nearest <input name="something/> value
// get nearest <input class="a-input" /> value
$(".main-div").append(div);
});
.highlight{
background:#b00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-div">
<div class="second-div">
<input name="something" class="input" />
</div>
<div class="third-div">
<input name="another input" class="a-input" />
</div>
<div class="fourth-div">
<button type="button" class="button">Click Me</button>
</div>
</div>

how to get child of div element

<div class="div" id="div">
<div class="row">
<div class="col1">
<input type="text">
<!--I need to get a value of these inputs-->
</div>
<div class="col2">
<input type="text">
<!--I need to get a value of these inputs-->
</div>
</div>
<div class="row">
<div class="col1">
<input type="text">
<!--I need to get a value of these inputs-->
</div>
<div class="col2">
<input type="text">
<!--I need to get a value of these inputs-->
</div>
</div>
</div>
How to get values of all of inputs in div and how to check in which div input in(col1 or col2);
in my case div with class "row" will be added via firebase database.
const inputs = document.querySelectorAll(".div > .col");
alert(inputs.value);
Using JavaScript, try looping with forEach
var inputElem = document.querySelectorAll(".row input");
inputElem.forEach(function(obj){
console.log(obj.value)
})
Snippet:
var inputElem = document.querySelectorAll(".row input");
inputElem.forEach(function(obj){
console.log(obj.value)
})
<div class="div" id="div">
<div class="row">
<div class="col1">
<input type="text" value="one">
<!--I need to get a value of these inputs-->
</div>
<div class="col2">
<input type="text" value="two">
<!--I need to get a value of these inputs-->
</div>
</div>
<div class="row">
<div class="col1">
<input type="text" value="three">
<!--I need to get a value of these inputs-->
</div>
<div class="col2">
<input type="text" value="four">
<!--I need to get a value of these inputs-->
</div>
</div>
</div>
I think this could work:
$("div input").each(function(){
// Get the value:
console.log($(this).val());
// check in which div input in(col1 or col2)
console.log($(this).closest("div").attr("class"));
});
Try this:
const inputs = document.getElementById('div').getElementsByTagName('input');
console.log(inputs[0].value, inputs[1].value);
See an example here: https://jsfiddle.net/xbdd6q13/

jQuery val() doesn't update value in .html()

I have an HTML page generated with some default values for input fields. Here is the HTML and JavaScript:
$('#trigger').click(function () {
var content = $(this).parent().find('.content');
content.find('#name').val("Young man");
content.find('#age').val("25");
alert(content.find('#name').val());
alert(content.html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<a id="trigger" href="#">Know!</a>
<div class="content">
<div>
<label>Name:</label>
<input type="text" id="name" value="dummy">
</div>
<div>
<label>Age:</label>
<input type="text" id="age" value="dummy">
</div>
</div>
</div>
I am trying to get the div assigned to a variable, then change the values of name and age through this handle. The first alert method confirms that they are changed. But why is content.html() still outputs the original html? How can I make html() output the updated data?
jQuery .val() method never updates the value attribute. You can change it with .attr() method.
$('#trigger').click(function() {
var content = $(this).parent().find('.content');
content.find('#name').attr("value", "Young man");
content.find('#age').attr("value", "25");
alert(content.find('#name').val());
alert(content.html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<a id="trigger" href="#">Know!</a>
<div class="content">
<div>
<label>Name:</label>
<input type="text" id="name" value="dummy">
</div>
<div>
<label>Age:</label>
<input type="text" id="age" value="dummy">
</div>
</div>
</div>
Assign the new value using attr().
$('#trigger').click(function () {
var content = $(this).parent().find('.content');
content.find('#name').attr("value", "Young man");
content.find('#age').attr("value", "25");
console.log(content.find('#name').val());
console.log(content.html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<a id="trigger" href="#">Know!</a>
<div class="content">
<div>
<label>Name:</label>
<input type="text" id="name" value="dummy">
</div>
<div>
<label>Age:</label>
<input type="text" id="age" value="dummy">
</div>
</div>
</div>

Wrap a div into wrapper div

I have a div with some elements inside it. What I want is to create a wrapper div around that div using j query.
<div id="foo">
<input type="text">
<input type="button">
</div>
I need to make the above code look like the following
<div class="wrapper">
<div id="foo">
<input type="text">
<input type="button">
</div>
</div>
Just use Wrap method.
$( "#foo" ).wrap( "<div class='wrapper'></div>" );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
<input type="text">
<input type="button">
</div>

Loop inside a element with a specific class

I have the below HTML. Can someone please tell me how I can loop through all the divs with the class "tab-pane" and see if any element inside the div has a class
"input-validation-error" and then just change the background color of that div.
In this example the first div and the third div with "tab pane" class should have their background property change. I know how to loop through each but not sure how to look for specific properties inside child elements.
<ul id="sellerAppTabs">
<li title="General Information">Section I</li>
<li title="Affiliate Information">Section II</li>
<li title="Affiliate Information">Section II</li>
</ul>
<div class="tab-pane" id="tab">
<div class="test1">
<h1>Some Data</h1>
<input type="text" class="input-validation-error">
<input type="text" class="input-validation-error">
</div>
</div>
<div class="tab-pane" id="tab1">
<div class="test2">
<h1>Some Data</h1>
<input type="text">
<input type="text">
</div>
</div>
<div class="tab-pane" id="tab2">
<div class="test1">
<h1>Some Data</h1>
<input type="text" class="input-validation-error">
<input type="text" class="input-validation-error">
</div>
</div>
So I have to loop through the a tags in the sellerAppTabs ul section which have their ids matched to the divs and then if the div has any "input-validation-error" class then I have to change the background color of the li above the a tag.
Use .has() or :has()
$('.tab-pane').has('.input-validation-error').css({background: '#C55'})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tab-pane">
<div class="test1">
<h1>Some Data</h1>
<input type="text" class="input-validation-error">
<input type="text" class="input-validation-error">
</div>
</div>
<div class="tab-pane">
<div class="test2">
<h1>Some Data</h1>
<input type="text">
<input type="text">
</div>
</div>
<div class="tab-pane">
<div class="test1">
<h1>Some Data</h1>
<input type="text" class="input-validation-error">
<input type="text" class="input-validation-error">
</div>
</div>
this worked for me:
<script type="text/javascript">
var els = document.getElementsByClassName('input-validation-error');
for(var x=0; x<els.length; x++){
if( els[x].value == '' ){
els[x].parentNode.parentNode.style.backgroundColor = '#f00';
}
}
</script>
No need to loop. Just use a :has() selector
$('.tab-pane:has(.input-validation-error)').css('background', 'red');
$('.tab-pane:has(.input-validation-error)').css('background', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class="tab-pane">
<div class="test1">
<h1>Some Data</h1>
<input type="text" class="input-validation-error">
</input>
<input type="text" class="input-validation-error">
</input>
</div>
</div>
<div class="tab-pane">
<div class="test2">
<h1>Some Data</h1>
<input type="text">
</input>
<input type="text">
</input>
</div>
</div>
<div class="tab-pane">
<div class="test1">
<h1>Some Data</h1>
<input type="text" class="input-validation-error">
</input>
<input type="text" class="input-validation-error">
</input>
</div>
</div>
Since you are using jQuery, a simple .each() function would suffice. Followed by .find() for the input validation class
$('.tab-pane').each(function(){
$(this).find('.input-validation-error').each(function() {
//change the color
});
});
You can do this with each and find:
$(".tab-pane").each(function() {
if ($(this).find(".input-validation.error")) {
// $(this) points to the div.tab-pane!
$(this).css("background-color", "red")
}
});
You could use JQuery filter functionality:
$('.tab-pane')
.filter(':has(.input-validation-error)');
.css('background', 'red');
Get the elements with querySelectorAll
Filter the desired elements with filter
Iterate with forEach
[].filter.call(
document.querySelectorAll('.tab-pane'),
function(elem) { return elem.querySelector('.input-validation-error'); }
).forEach(function(elem) { elem.style.backgroundColor = color; });
[].filter.call(
document.querySelectorAll('.tab-pane'),
function(elem) { return elem.querySelector('.input-validation-error'); }
).forEach(function(elem) { elem.style.backgroundColor = '#C55'; });
<div class="tab-pane">
<div class="test1">
<h1>Some Data</h1>
<input type="text" class="input-validation-error"/>
<input type="text" class="input-validation-error"/>
</div>
</div>
<div class="tab-pane">
<div class="test2">
<h1>Some Data</h1>
<input type="text"/>
<input type="text"/>
</div>
</div>
<div class="tab-pane">
<div class="test1">
<h1>Some Data</h1>
<input type="text" class="input-validation-error"/>
<input type="text" class="input-validation-error"/>
</div>
</div>
Try and stick with Vanilla JS by using getElementsByClassName().
getElementsByClassName() returns a list of elements of which you can iterate through for your operations.

Categories