Expand/Collapse one at time - javascript

How to expand one element at a time and the others to be closed?
When click open one at a time...
Thanks!
jQuery(document).ready(function($) {
$(".se-q").click( function () {
var container = $(this).parents(".se-c");
var answer = container.find(".se-a");
var trigger = container.find(".se-t");
answer.slideToggle(200);
if (trigger.hasClass("se-o")) {
trigger.removeClass("se-o");
}
else {
trigger.addClass("se-o");
}
})
});

You can use .not() , removeClass() , toggleClass();
jQuery(document).ready(function($) {
$(".se-q").click( function () {
var container = $(this).parents(".se-c");
var answer = container.find(".se-a");
var trigger = container.find(".se-t");
answer.slideToggle(200);
$('.se-t').not(trigger).removeClass('se-o'); // remove the class from all .se-t element but not this one(container.find(".se-t"))
trigger.toggleClass("se-o"); // toggle class for this(container.find(".se-t"))
})
});
Note: you can catch the point from my code .. but actually you need to provide your html code .. what I got from your code its
question/answer script .. so you may need to toggle answer as
well
For answer you can use the next line before answer.slideToggle(200);
$('.se-a').not(answer).slideUp(200);

Related

Add class to next and remove form closest

I have a function that worked in jQuery, but i need to rewrite the solution without using jQuery.
// Working in jQuery
var menu = jQuery('.menu');
menu.find('a').focus(function() {
jQuery(this).closest('ul').find('.visible').removeClass('visible');
jQuery(this).next('ul').addClass('visible');
});
But I can not deal with a clean javascript
const menu = document.querySelectorAll('.menu a');
menu.forEach(function(menu) {
menu.addEventListener('focus', function() {
// I tired replace this jquery into vanilla javascript
jQuery(this).closest('ul').find('.visible').removeClass('visible');
// Works
const next = mainMenuLink.nextElementSibling;
if (next) {
next .classList.add('visible');
}
});
});
You can use the function .querySelectorAll(...) in order to select the whole set of ul elements with class visible.
Array.from(this.closest('ul').querySelectorAll('.visible')).forEach((ul) => {
ul.classList.remove('visible');
});

How can I observe changes to my DOM and react to them with jQuery?

I have this function where I toggle a class on click, but also append HTML to an element, still based on that click.
The problem is that now, I'm not listening to any DOM changes at all, so, once I do my first click, yup, my content will be added, but if I click once again - the content gets added again, because as far as this instance of jQuery is aware, the element is not there.
Here's my code:
(function($) {
"use strict";
var closePluginsList = $('#go-back-to-setup-all');
var wrapper = $('.dynamic-container');
$('#install-selected-plugins, #go-back-to-setup-all').on('click', function(event) {
$('.setup-theme-container').toggleClass('plugins-list-enabled');
if ( !wrapper.has('.plugins-container') ){
var markup = generate_plugins_list_markup();
wrapper.append(markup);
} else {
$('.plugins-container').hide();
}
});
//Below here, there's a lot of code that gets put into the markup variable. It's just generating the HTML I'm adding.
})(jQuery);
Someone suggested using data attributes, but I've no idea how to make them work in this situation.
Any ideas?
You could just do something like adding a flag and check for it before adding your markup.
var flag = 0;
$('#install-selected-plugins, #go-back-to-setup-all').on('click', function(event) {
$('.setup-theme-container').toggleClass('plugins-list-enabled');
if ( !wrapper.has('.plugins-container') ){
var markup = generate_plugins_list_markup();
if(flag == 0){
wrapper.append(markup);
flag = 1;
}
} else {
$('.plugins-container').hide();
}
});
If you want to add element once only on click then you should make use of .one() and put logic you want to execute once only in that handler.
Example :
$(document).ready(function(){
$("p").one("click", function(){
//this will get execute once only
$(this).animate({fontSize: "+=6px"});
});
$("p").on("click", function(){
//this get execute multiple times
alert('test');
});
});
html
<p>Click any p element to increase its text size. The event will only trigger once for each p element.</p>

How to test jquery .slideDown() and slideUp() by code?

I use the jQuery to hide and show a div.
function bindIconClick() {
$('span.scroIcon').click(function(event) {
var eventIcon = $(event.target);
var contentPanel = eventIcon.parents('.panelTitle').next();
if (contentPanel.is(':hidden')) {
contentPanel.slideDown('slow');
} else {
contentPanel.slideUp('slow');
}
});
}
I want to test the function, I can use the trigger() to simulate the click event, but I don't know how to test the slideDown() and slideUp() effect.
I want to test the function bindIconClick ,means if I use the trigger() function simulate the click event, I want know does the contentPanel hide or show.
I want to test the full function bindIconClick , not the part of it. I want to test the full function is correct!
In fact , I want to test the effetc that when the span be clicked, will contentPanel hide or show ?
Use slideToggle function instead of if and else
function bindIconClick() {
$('span.scroIcon').click(function(event) {
var eventIcon = $(event.target);
var contentPanel = eventIcon.parents('.panelTitle').next();
contentPanel.slideToggle('slow');
});
}

How to call a function with jQuery blur UNLESS clicking on a link?

I have a small jQuery script:
$('.field').blur(function() {
$(this).next().children().hide();
});
The children that is hidden contains some links. This makes it impossible to click the links (because they get hidden). What is an appropriate solution to this?
This is as close as I have got:
$('.field').blur(function() {
$('*').not('.adress').click(function(e) {
foo = $(this).data('events').click;
if(foo.length <= 1) {
// $(this).next('.spacer').children().removeClass("visible");
}
$(this).unbind(e);
});
});
The uncommented line is suppose to refer to the field that is blurred, but it doesn't seem to work. Any suggestions?
You can give it a slight delay, like this:
$('.field').blur(function() {
var kids = $(this).next().children();
setTimeout(function() { kids.hide(); }, 10);
});
This gives you time to click before those child links go away.
This is how I ended up doing it:
var curFocus;
$(document).delegate('*','mousedown', function(){
if ((this != curFocus) && // don't bother if this was the previous active element
($(curFocus).is('.field')) && // if it was a .field that was blurred
!($(this).is('.adress'))
) {
$('.' + $(curFocus).attr("id")).removeClass("visible"); // take action based on the blurred element
}
curFocus = this; // log the newly focussed element for the next event
});
I believe you can use .not('a') in this situation:
$('.field').not('a').blur(function() {
$(this).next().children().hide();
});
This isn't tested, so I am not sure if this will work or not.

Toggle State Incorrect in jQuery

I am using jQuery to show / hide lists, but it takes two clicks on a link instead of just one to show the list. Any help?
jQuery.showList = function(object) {
object.toggle(function(){
object.html("▾");
object.siblings("ul.utlist").show("fast");
}, function(){
object.html("▸");
object.siblings("ul.utlist").hide("fast");
});
}
$(document).ready(function() {
$("#page").click(function (e){
e.preventDefault();
var target = $(e.target);
var class = target.attr("class");
if(class == "list")
$.showList(target);
});
});
It's probably because toggle thinks the object is already visible, and executes the 'hide' clause.
edit:
Eh.. quite circular logic; how else would a user be able to click on it :-)
PS. You changed the logic from is-object-visible? to is-list-visible? in your own reply.
Not sure if this will fix everything but stop using reserved keywords.
Change variable class to something like c. And Change object variable to at least obj.
Doing the following worked well
jQuery.showList = function(obj) {
var list = obj.siblings("ul.utlist");
if(list.is(":visible")){
obj.html("▸");
list.hide("fast");
} else {
obj.html("▾");
list.show("fast");
}
}

Categories