jquery unable to select element using next/closest - javascript

I have the following HTML on my page;
<div id="c2">
<input type="checkbox" class="expandCollapseSection" id="my_chk">
<span>Header</span>
<div style="" class="contentDiv">
<div class="oj-inputtext oj-form-control oj-component">some things</div>
</div>
</div>
I have the following JS code;
$(".expandCollapseSection").click(function (event) {
if ($(this).prop("checked")) {
$(this).next('.contentDiv').slideDown('slow');
} else {
$(this).next('.contentDiv').slideUp('slow');
}
});
Now my question is $(this).next('.contentDiv') does not select the contentDiv
I even tried using $(this).closest('.contentDiv')
But still does not select.
Just to add $(".contentDiv") does get the div though.
Am I doing something wrong here?

use siblings( ".selected" )
$(".expandCollapseSection").click(function (event) {
if ($(this).prop("checked")) {
$(this).siblings('.contentDiv').slideDown('slow');
} else {
$(this).siblings('.contentDiv').slideUp('slow');
}
});
Demo

You can try:
$(this).closest('div').find('.contentDiv');
$(".expandCollapseSection").click(function (event) {
if ($(this).prop("checked")) {
$(this).closest('div').find('.contentDiv').css({'color':'red'});
} else {
$(this).closest('div').find('.contentDiv').css({'color':'green'});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="c2">
<input type="checkbox" class="expandCollapseSection" id="my_chk">
<span>Header</span>
<div style="" class="contentDiv">
<div class="oj-inputtext oj-form-control oj-component">some things</div>
</div>
</div>
<div id="c3">
<input type="checkbox" class="expandCollapseSection" id="my_chk">
<span>Header</span>
<div style="" class="contentDiv">
<div class="oj-inputtext oj-form-control oj-component">some things</div>
</div>
</div>

kapantzak's answer is correct.
However you could simply use
$(this).parent().find('.contentDiv');
Slightly more efficient, as you don't have to find closest div.

Try This Code,
$(".expandCollapseSection").click(function (event) {
if ($(this).prop("checked")) {
$(this).closest('#c2').find('.contentDiv').slideDown('slow');
} else {
$(this).closest('#c2').find('.contentDiv').slideUp('slow');
}
});

You may also use nextAll and shorten your code too, like below.
$(".expandCollapseSection").change(function (event) {
var div = $(this).nextAll('.contentDiv');
var func = this.checked ? 'slideDown' : 'slideUp';
div[func]("slow");
});
Demo#Fiddle

Related

Displaying elements based on search

I would like the .box elements to show/hide based on the words the user searches for, so for example if a user types in 'Title2 Title1' because those words exists inside box one and two they will remain visible with the renaming .box elements hiding. All the text within the .box elements needs to be searchable not just that in the .title element.
Below is how far I've got. It's almost there but it's not quite working as hoped.
Any help would be great.
Many thanks.
<input placeholder="Search" id="search" type="text" />
<div class="box">
<div class="title">Box Title1</div>
<div class="content">
Box title one content
</div>
</div>
<div class="box">
<div class="title">Box Title2</div>
<div class="content">
Box title two content
</div>
</div>
<div class="box">
<div class="title">Box Title3</div>
<div class="content">
Box title three content
</div>
</div>
<script>
$("#search").on("input", function () {
var search = $(this).val();
if (search !== "") {
var searchArray = search.split(" ");
searchArray.forEach(function(searchWord) {
$(".box").each(function () {
if($(this).is(':contains('+ searchWord +')')) {
$(this).show();
} else {
$(this).hide();
}
});
});
} else {
$(".box").show();
}
});
</script>
You need to use a different search method. :contains does not work as you expect. Consider the following example.
$(function() {
function filter(e) {
var term = $(e.target).val();
if (term.length < 3) {
$(".box").show();
return;
}
$(".box").each(function(i, el) {
if ($(".content", el).text().indexOf(term) >= 0) {
$(el).show();
} else {
$(el).hide();
}
});
}
$("#search").keyup(filter);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input placeholder="Search" id="search" type="text" />
<div class="box">
<div class="title">Box Title1</div>
<div class="content">Box title one content</div>
</div>
<div class="box">
<div class="title">Box Title2</div>
<div class="content">Box title two content</div>
</div>
<div class="box">
<div class="title">Box Title3</div>
<div class="content">Box title three content</div>
</div>
So for example if on is entered, no filtering is performed. If one is entered, the script will look inside the content class of each box and if one is found in the text, it will be shown otherwise, it is hidden. If the User clears their search out, all items are shown.
Hide all box before iterate, then only show when match any words:
$("#search").on("input", function () {
var search = $(this).val();
if (search !== "") {
var searchArray = search.split(" ");
// Hide all .box
$(".box").each(function () {
$(this).hide();
})
searchArray.forEach(function(searchWord) {
$(".box").each(function () {
if($(this).is(':contains('+ searchWord +')') ) {
$(this).show();
}
});
});
} else {
$(".box").show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input placeholder="Search" id="search" type="text" />
<div class="box">
<div class="title">Box Title1</div>
<div class="content">
Box title one content
</div>
</div>
<div class="box">
<div class="title">Box Title2</div>
<div class="content">
Box title two content
</div>
</div>
<div class="box">
<div class="title">Box Title3</div>
<div class="content">
Box title three content
</div>
</div>
Loop through all .boxs and using regex pattern matching, check either the title or content matches the search query. Show all matched boxes and hide all others
I have also fiddled it here
$("#search").on("input", function () {
var searchables=$('.box');
console.log(searchables)
var query=$(this).val();
searchables.each(function(i,item){
var title=$(item).find('.title').text();
var content=$(item).find('.content').text();
var rgx=new RegExp(query,'gi');
if(rgx.test(title) || rgx.test(content))
{
$(item).show();
}
else
{
$(item).hide();
}
})
})

Toggle multiple divs one at a time with 1 button using Jquery

I have four divs which i want to toggle one at a time with a single button. I want to toggle them one after the other and not randomly. I have tried something like below.
$(document).ready(function() {
$('#toggle').click(function() {
$('#1').hide();
});
$('#toggle').click(function() {
$('#2').hide();
});
$('#toggle').click(function() {
$('#3').hide();
});
$('#toggle').click(function() {
$('#4').hide();
});
});
.divs {
border: 1px solid;
height: 30px;
}
<div id='1' class='divs'></div>
<div id='2' class='divs'></div>
<div id='3' class='divs'></div>
<div id='4' class='divs'></div>
<button id='toggle'>
toggle
</button>
Save the state on each click.
$(document).ready(function() {
var state = 1;
$('#toggle').click(function() {
if(state==1){
$('#1').hide();
state=2;
}
else if(state==2){
$('#2').hide();
state=3;
}
else if(state==3){
$('#3').hide();
state=4;
}
else if(state==4){
$('#4').hide();
state=1; //back to state
}
});
$(document).ready(function() {
$('#toggle').click(function() {
$('.divs:visible:first').hide();
});
});
Try this one
var count = 1;
$(document).ready(function () {
$('#toggle').click(function(){
$('.divs').show();
if(count == 4)
count = 1;
$('#' + count).hide();
count++;
});
});
First of all, keeping numeric ids is not good, so considering you will change them after wards, I am writing both the answers with numeric ids and without numeric ids.
With Numeric Ids, it is easy to do.
Suppose you have button to toggle the other four divs then it would look like this:
var state = 1;
$("#toggleButton").click(function(){
$("#"+state++).slideToggle();
if(state===5){state=1;}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div id='1' >1</div>
<div id='2' >2</div>
<div id='3' >3</div>
<div id='4' >4</div>
<button id="toggleButton">
toggle
</button>
Now coming to the non numeric ids.
var state = 1;
$("#toggleButton").click(function(){
$("#div"+state++).slideToggle();
if(state===5){state=1;}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div id='div1' >1</div>
<div id='div2' >2</div>
<div id='div3' >3</div>
<div id='div4' >4</div>
<button id="toggleButton">
toggle
</button>
FYI:In my opinion you should not use numeric ids.
Further adding more in to the code.
If you don't know how many div would be there but you are having a clear cut rule that the div's follow the sequence whether or not they are having numeric/non numeric ids then you can change the code slightly to incorporate that as well like this.
var state = 1;//first button id to be toggled
var total = 4;//this will be the total number of divs to be handled by the button
$("#toggleButton").click(function(){
$("#"+state++).slideToggle();
if(state===(total+1)){state=1;}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div id='1' >1</div>
<div id='2' >2</div>
<div id='3' >3</div>
<div id='4' >4</div>
<button id="toggleButton">
toggle
</button>
Happy coding.
Use class instead of Id for using many times
var i = 1;
$('#toggle').click(function(){
$('.divs').show();
$('#' + i).hide();
i++;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='1' class='divs'>dsgsdg</div>
<div id='2' class='divs'>64636</div>
<div id='3' class='divs'>46y</div>
<div id='4' class='divs'>4373477</div>
<button id='toggle'>
toggle
</button>
loop through each element and use toggle. This gives the effect that you desire.
$('button').click(function(){
$('.divs').filter(function(index,item){
$(item).toggle('slow')
})
})
Have a look at this demo -
https://jsfiddle.net/ukw5wcmt/
var i = 1;
$('#toggle').click(function(){
$('.divs').show();
$('#' + i).hide();
if(i==4)
{
i=1;
}else{
i++;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='1' class='divs'>dsgsdg</div>
<div id='2' class='divs'>64636</div>
<div id='3' class='divs'>46y</div>
<div id='4' class='divs'>4373477</div>
<button id='toggle'>
toggle
</button>
Try this
.hide{ display: none; }
$(document).ready(function(){
$(".click-btn").click(function(){
var fid = $(".hide:first").prop("id");
$("#"+fid).removeClass("hide");
});
$(".remove-tag").click(function(){
$(this).parent().addClass("hide");
});
});
<div id="cart-1" class="hide">
<div class="remove-tag">x</div>
<h5>1</h5>
</div>
<div id="cart-2" class="hide">
<div class="remove-tag">x</div>
<h5>2</h5>
</div>
<div id="cart-3" class="hide">
<div class="remove-tag">x</div>
<h5>3</h5>
</div>
<div id="cart-4" class="hide">
<div class="remove-tag">x</div>
<h5>4</h5>
</div>
<div id="cart-5" class="hide">
<div class="remove-tag">x</div>
<h5>5</h5>
</div>
<button class="click-btn">click</button>

How can I make jquery script shorter?

I have got following code (i shorted it to make it more readable)
And I would like to ask if it is possible to do not write almost the same code for every button? How can I do it the easiest way? I have got 6 buttons and code would be quite long.
<script>
$(document).ready(function(){
$("#option1").click(function(){
if($(".option1").is(":visible")){
$(".option1").hide("slow",function(){});
}
else{
$(".option2, .option3").hide("slow",function(){});
$(".option1").show("slow",function(){});
}
});
$("#option2").click(function(){
if($(".option2").is(":visible")){
$(".option2").hide("slow",function(){});
}
else{
$(".option1, .option3").hide("slow",function(){});
$(".option2").show("slow",function(){});
}
});
$("#option3").click(function(){
if($(".option3").is(":visible")){
$(".option3").hide("slow",function(){});
}
else{
$(".option1, .option2").hide("slow",function(){});
$(".option3").show("slow",function(){});
}
});
});
</script>
<body>
<div class="containter">
<div class="row">
<div class="col-md-4">
<button type="button" id="option1" class="btn btn-primary">Button1 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option2" class="btn btn-primary">Button2 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option3" class="btn btn-primary">Button3 >></button>
</div>
</div>
</div>
</body>
Without the need to change much of your html, add a common class option to all your option1, option2, ... :
<div class ="option option1">a</div>
<div class ="option option2">b</div>
<div class ="option option3">c</div>
and then you can use this below:
Array.from(document.getElementsByTagName('button')).forEach(function(btn){
btn.addEventListener('click', function(e){
if($("." + e.target.id).is(":visible")){
$("." + e.target.id).hide("slow",function(){});
}
else{
$(".option").hide("slow",function(){});
$("." + e.target.id).show("slow",function(){});
}
});
});
DEMO
You can reduce the code to just one click listener. Try this:
<script>
$(document).ready(function() {
$(".btn-primary").click(function() {
var option = $(this).data("option");
if ($(".option." + option).is(":visible")) {
$(".option." + option).hide("slow", function() {});
} else {
$(".option").not("." + option).hide("slow", function() {});
$(".option." + option).show("slow", function() {});
}
});
});
</script>
<body>
<div class="containter">
<div class="row">
<div class="col-md-4">
<button type="button" id="option1" data-option="option1" class="btn btn-primary">Button1 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option2" data-option="option2" class="btn btn-primary">Button2 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option3" data-option="option3" class="btn btn-primary">Button3 >></button>
</div>
</div>
</div>
<!-- common class option added -->
<div class="options">
<div class="option option1"></div>
<div class="option option2"></div>
<div class="option option3"></div>
</div>
</body>
I added a common class to all the options, and a data-option attribute to your buttons.
You don't need to check to see whether the current button is visible. It's visible because it was just clicked on.
All you need to do is show the other buttons that weren't clicked on and hide the one that was. To do this, assign the same class to all 3 buttons. In the example below, I added the class "myBtn" to all 3 buttons.
$(".myBtn").click(function () {
var id = $(this).attr('id');
$(".myBtn:not(#"+id+")").show("slow", function () {});
$(this).hide();
});
JSFiddle demo.

Generate a random class and read with regex in jQuery

So I make this little kind of game. There are 7 switches that trigger other buttons on click to toggleClass 'on' which is defined in jQuery.
The Goal is to get all buttons to the state 'on'.
The problem is, you can easily right-click, choose Inspect Element, add the class 'on' and win the game.
So I need to make the classes for these switches random. E.g. 'on-214124712', 'on-307153821369' or 'on-6471649031264'. But they have to share the same prefix which is 'on-'.
How can I generate them differently with every click? And how can I still toggleClass and check hasClass them using regex?
HTML:
<h2>You clicked <span id="output">0</span> times</h2>
<div class="switches">
<div id="switch1" class="switch"></div>
<div id="switch2" class="switch on"></div>
<div id="switch3" class="switch on"></div>
<div id="switch4" class="switch"></div>
<div id="switch5" class="switch on"></div>
<div id="switch6" class="switch on"></div>
<div id="switch7" class="switch"></div>
</div>
Javascript:
var count = 0;
$('.switch').click(function () {
$('#output').html(function (i, val) {
return val * 1 + 1
});
});
$("#switch1").bind("click", function () {
$(this).toggleClass("on");
$('#switch3').toggleClass("on");
$('#switch5').toggleClass("on");
$('#switch6').toggleClass("on");
count++;
});
$("#switch2").bind("click", function () {
$(this).toggleClass("on");
$('#switch1').toggleClass("on");
$('#switch3').toggleClass("on");
$('#switch7').toggleClass("on");
count++;
});
$("#switch3").bind("click", function () {
$(this).toggleClass("on");
$('#switch2').toggleClass("on");
$('#switch5').toggleClass("on");
count++;
});
$("#switch4").bind("click", function () {
$(this).toggleClass("on");
//$('#switch1').toggleClass("on");
$('#switch2').toggleClass("on");
$('#switch5').toggleClass("on");
count++;
});
$("#switch5").bind("click", function () {
$(this).toggleClass("on");
$('#switch1').toggleClass("on");
$('#switch4').toggleClass("on");
count++;
});
$("#switch6").bind("click", function () {
$(this).toggleClass("on");
$('#switch3').toggleClass("on");
$('#switch5').toggleClass("on");
$('#switch7').toggleClass("on");
count++;
});
$("#switch7").bind("click", function () {
$(this).toggleClass("on");
$('#switch3').toggleClass("on");
$('#switch4').toggleClass("on");
count++;
});
$('.switches').click(function () {
if ($("#switch1").hasClass("on") && $("#switch2").hasClass("on") && $("#switch3").hasClass("on") && $("#switch4").hasClass("on") && $("#switch5").hasClass("on") && $("#switch6").hasClass("on") && $("#switch7").hasClass("on")) {
alert('Success!');
}
});
Thanks!
UPDATE
You can use this selector that checks if the element has a class that contains the desired string (check the updated demo):
$('.switch[class*=on-]').addClass('red');
Each div that has a class that contains on will get red
$('.switch[class*=on-]').addClass('red');
.red { color:red }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="switches">
<div id="switch1" class="switch">test</div>
<div id="switch2" class="switch on-9876597856978">test</div>
<div id="switch3" class="switch on-jhg675">test</div>
<div id="switch4" class="switch">test</div>
<div id="switch5" class="switch on-876uyg">test</div>
<div id="switch6" class="switch on-kjhg76gt9">test</div>
<div id="switch7" class="switch">test</div>
</div>

how can I check which p was clicked and what innerhtml he contains with javascript

hellow I have a problem,
I want my page to check which p was clicked and what is his innerhtml and acoording to that to change img size.
you can see it here:
http://jsfiddle.net/YgL5Z/
or
my html:
<div class="one_of_4_colum"><p class="mysizeNum" onclick="mySize()">4</p></div>
<div class="one_of_4_colum"><p class="mysizeNum" onclick="mySize()">3</p></div>
<div class="one_of_4_colum"><p class="mysizeNum" onclick="mySize()">2</p></div>
<div class="one_of_4_colum"><p class="mysizeNum" onclick="mySize()">1</p></div>
<img class="myPreviewElmo">
my js
function mySize()
{
if ((this.innerHTML) == "4") {
$('.myPreviewElmo').css('height', '200px');
}
if (this.innerHTML == "3") {
$('.myPreviewElmo').css('height', '150px');
}
if (this.innerHTML == "2") {
$('.myPreviewElmo').css('height', '100px');
}
if (this.innerHTML == "1") {
$('.myPreviewElmo').css('height', '50px');
}
}
thank you
Try something like this:
$(".mysizeNum").click(function() {
var innerText = parseInt($(this).text());
var height = innerText * 50;
$('.myPreviewElmo').css('height', height + "px");
})
Firslty, don't use on* event attributes. They are outdated and not good for separation of concerns. Attach events in jQuery instead. Also, you can use data-* attributes to simplify your code:
<div class="one_of_4_colum">
<p class="mysizeNum" data-height="200px">4</p>
</div>
<div class="one_of_4_colum">
<p class="mysizeNum" data-height="150px">3</p>
</div>
<div class="one_of_4_colum">
<p class="mysizeNum" data-height="100px">2</p>
</div>
<div class="one_of_4_colum">
<p class="mysizeNum" data-height="50px">1</p>
</div>
<div class="myPreviewElmo">
$('.mysizeNum').click(function () {
$('.myPreviewElmo').css('height', $(this).data('height'));
});
Example fiddle
Your HTML should be like this -
<div class="one_of_4_colum"><p class="mysizeNum">4</p></div>
<div class="one_of_4_colum"><p class="mysizeNum">3</p></div>
<div class="one_of_4_colum"><p class="mysizeNum">2</p></div>
<div class="one_of_4_colum"><p class="mysizeNum">1</p></div>
<div class="myPreviewElmo"></div>
And your javascript -
$(document).ready(function() {
$('.mysizeNum').click(function() {
$('.myPreviewElmo').height(parseInt($(this).text())*50);
});
});
In addition, make sure in the fiddle you select jQuery library as enabled.
<div class="one_of_4_colum">
<p class="mysizeNum" data-size="4">4</p>
</div>
<div class="one_of_4_colum">
<p class="mysizeNum" data-size="3">3</p>
</div>
<div class="one_of_4_colum">
<p class="mysizeNum" data-size="2">2</p>
</div>
<div class="one_of_4_colum">
<p class="mysizeNum" data-size="1">1</p>
</div>
<div class="myPreviewElmo">
then
jQuery(function () {
var heights = {
'size-1': '50px',
'size-2': '100px',
'size-3': '150px',
'size-4': '200px'
}
$('.mysizeNum').click(function () {
$('.myPreviewElmo').css('height', heights['size-' + $(this).data('size')]);
})
})
Demo: Fiddle
There were so many things wrong with your code, so I just rewrote most of it with this jsfiddle - http://jsfiddle.net/YgL5Z/7/ There's probably still room for improvement, but this gets the job done quite neatly.
$(function () {
$(".mysizeNum").click(function() {
var newheight=(parseInt($(this).text())*50);
$('.myPreviewElmo').height(newheight);
});
});

Categories