Toggling same class names except for one (JavaScript) - javascript

I am trying to prevent a paragraph element with a class attribute of 'show' from toggling away on the click event on updateButton. I've tried if else statements but to no avail.
I'm essentially trying to create an editing state when I click update button and all the text on the bottom of these buttons need to show (the paragraph elements). Though there is one button with text underneath it already which I want to prevent from toggling the class .hide.
The other buttons already have the .hide class attribute on them already so when toggled from the click event, they appear.
TLDR: I want to prevent the one paragraph element with no .hide class attribute from toggling it on when I toggle all the other paragraph elements in the .risk-text container.
// select indicator div
const riskIndicator = document.getElementById("Risk__indicator");
// select update button
const updateButton = document.getElementById("Update_button");
// Indicator buttons
const indicatorButton = document.getElementsByClassName("Risk_indicator_button");
// Indicator 'check every..' text
const checkIndicatorText = document.querySelectorAll(".risk-text");
// select update button
updateChange: updateButton.addEventListener("click", function (event) {
riskIndicator.classList.toggle("active");
});
// If statement to check whether the Risk Indicator is active to apply background changes
editState: updateButton.addEventListener("click", function(el) {
[].map.call(document.querySelectorAll('.risk-text'), function(el) {
// loop through text indicator elements checking to see if it's got a hidden class attribute
el.classList.toggle('hide');
});
});

Depending on your use case:
If you want to exclude it only once, and then toggle this element with others, do something like:
editState: updateButton.addEventListener("click", function(el) {
[].map.call(document.querySelectorAll('.risk-text:not(.hide)'), function(el) {
// loop through text indicator elements checking to see if it's got a hidden class attribute
el.classList.toggle('hide');
});
});
If you want to leave the "ember" element alone, then
editState: updateButton.addEventListener("click", function(el) {
[].map.call(document.querySelectorAll('.risk-text:not(.low_risk_text__wrap--risk-middle-amber)'), function(el) {
// loop through text indicator elements checking to see if it's got a hidden class attribute
el.classList.toggle('hide');
});
});
You can also add new class, like "spareMe", and exclude it with .not()

Related

On click only apply class to element clicked, not all elements with the same class

I have a set of filters which are in accordions. When the user clicks on one of the filter headings, I just want to show that elements fitlers. My issue is that when I click on an element header to show the filters, all the other classes change too.
$('.filter-group__title').on('click', function () {
$(".glyphicon").toggleClass("glyphicon-minus glyphicon-plus");
});
You should be referring the parent with "this"
$('.filter-group__title').on('click', function () {
$(this).find(".glyphicon").toggleClass("glyphicon-minus glyphicon-plus");
});

Jquery on click hide the next added element

I have a button, which on every click gives the dropdown element.
Now i need to add the check box above the dropdown - which i have done, but this checkbox element should appear only for the first time.
The problem is , on every click, i get both dropdown associated with checkbox like below.
I need checkbox only for the 1st time button click- along with dropdown.
SO for the 2nd time button click, i tried to hide the checkbox, but the previous checkbox is getting hidden.
public function getPreferenceKeysAction() {
....
<div style="margin:2px 0px 15px 0px;">
<input id = "mydd" type="checkbox" name="vehicle1" value="RegisteredUsers"> Registered Users</input><br>
<input id = "mydd" type="checkbox" name="vehicle1" value="RegisteredUsers"> Opted Users</input><br>
}
in JS
$(add_button).click(function(e){ //on add input button click
if($("#mydd").length){
alert("The element you're testing is present.");
$("#mydd").hide();
}
else{
alert("NOt present.");
}
});
Why not add a class to the element or a data attribute.
With jQuery both are easy to achive.
If you want to use a class just change data method to hasClass and addClass
just do a
$btn = $(this);
// Check if the element has data attribute used
if ( $btn.data('used') != 'true' ) {
// Add data attribute used to element
$btn.data('used', 'true')
// Do whats needed for the first time it's clicked.
} else {
// The element has been used already
}
Change you id="mydd" to class="mydd", you should use id with a unique value, doing that you can hide the elements skipping 2 of them, like this.
$('.mydd').slice(2).hide();
If you want to hide the div wrapping your checkbox, add .parent()
$('.mydd').parent().slice(1).hide();

Conditional jQuery Toggle Function

I want to hide and show list items based on their attributed class.
The problem is that certain list items have multiple classes. So if I toggle one class then toggle another, any items with both selected classes will be removed.
I created a demo of my problem: http://jsfiddle.net/a4NkN/2/
Here's the JS CODE:
$('#easy').click(function(){
$(this).toggleClass( "checked" );
$('.easy').toggle();
});
$('#fun').click(function(){
$(this).toggleClass( "checked" );
$('.fun').toggle();
});
$('#silly').click(function(){
$(this).toggleClass( "checked" );
$('.silly').toggle();
});
If you select the "Easy" and "Fun" buttons, Boating will disappear.
How can I get Boating to stay?
This might be a good point to start from. Although you can do this cheaper and cleaner, that gives the idea:
Use an array to save the status of your selection buttons and one corresponding to hold the class names. Whenever your select buttons get clicked, you set all your elements invisible and reset those visible again, that are already selected by other buttons or the currently clicked, which is all saved in the switcher array.
//saves whether button is active
var switcher = [false, false, false];
//holds your classes selectable
var classes = ['easy', 'fun', 'silly'];
$('.toggler').click(function () {
// toogle the select button and save status
var x = $(this).hasClass('checked');
switcher[$(this).data('switch')] = !x;
$(this).toggleClass("checked", !x);
// iterate through your elements to set them active if needed
$('li').each(function () {
var cur = $(this);
cur.addClass('hidden');
$.each(switcher, function (index, data) {
if (data && cur.hasClass(classes[index])) {
cur.removeClass('hidden');
}
});
});
});
Whole solution in this fiddle: http://jsfiddle.net/BMT4x/
You cannot unconditionally toggle elements based on a click on one of the button filters if it is possible for an element to satisfy multiple filters at once. The correct approach is a little more involved.
Since your checked class means that only items corresponding to that button should be shown, do exactly this: toggle them based on the current status of the button. The items should be shown if and only if the corresponding button is checked as a result of clicking it.
$('#easy').click(function(){
$(this).toggleClass( "checked" );
$('.easy').toggle($(this).is(".checked"));
});
This code uses the last version of .toggle, the one accepting a boolean argument.
It can also be done more succintly:
$('.easy').toggle($(this).toggleClass( "checked" ).is(".checked"));

Internet Explorer won't trigger click function if display: none;

The problem is mostly summed up in the title.
I am using the custom radio/checkbox code from accessible_custom_designed_checkbox_radio_button_inputs_styled_css_jquery/
This is the jist of their code (I modified it to allow defining different style depending on the label's title)
$(this).each(function(i){
if($(this).is('[type=radio]')){
var input = $(this);
// get the associated label using the input's id
var label = $('label[for='+input.attr('id')+']');
var labelTitle = label.attr('title');
// wrap the input + label in a div that has class "custom-radio-LabelTitle"
$('<div class="custom-radio-' + labelTitle + '"></div>').insertBefore(input).append(input, label);
// find all inputs in this set using the shared name attribute
var allInputs = $('input[name='+input.attr('name')+']');
//bind custom event, trigger it, bind click,focus,blur events
input.bind('updateState', function(){
if (input.is(':checked')) {
if (input.is(':radio')) {
allInputs.each(function(){
$('label[for='+$(this).attr('id')+']').removeClass('checked');
});
};
label.addClass('checked');
}
else { label.removeClass('checked checkedHover checkedFocus'); }
})
.trigger('updateState')
.click(function(){
$(this).trigger('updateState');
})
}
});
From my understanding, their code basically finds all the radio inputs and then defines a special trigger called updateState. Then they trigger it inside the input's click function.
So every time the input radiobutton is clicked, updateState is trigger, which in turn sets a class for that radiobutton's label. The changing of the class changes the CSS of the label.
When the label is clicked, The input that the label is for is also clicked (JQuery's .click() function is ran).
What I did was set all my input radiobuttons to display:none. That way the user only clicks the label, and secretly they clicked a radio button.
The .click() function won't run for the input if the input is hidden.
I assume there are two ways pass this:
instead of have the radio's .click() function trigger the handlestate, have the label's .click() function handle it instead. This may not work right though, because then the radio button may not actually be clicked (which messes up my form)
when the label is clicked, trigger the radio's click function manually. However, this may cause it to be triggered twice in every browser but IE. I don't know how to reference the label's radio nor to stop it from triggering twice.
a) instead of have the radio's
.click() function trigger the
handlestate, have the label's .click()
function handle it instead. This may
not work right though, because then
the radio button may not actually be
clicked (which messes up my form)
This may work right, on you label's .click() trigger also force the radio button to be checked like this,
$('#radiobutton').attr('checked', 'checked');
I got what I wanted with:
$("label[title='Plan']").click(function() {
var id = $(this).attr('for')
$("input[id='"+id+"']").trigger("click");
$("input[id='"+id+"']").trigger("updateState");
PlanChange();
});
Then removed all the onClicks.

dynamic jquery question

I am doing the following to toggle the display of an element:
$("*[id^=" + id + "_]").toggle(); // id is the element to toggle
This then toggles everything of the form id_* where * is any string.
I now realized, that I don't want to simply toggle each element, but show or hide it based on the state of the clicked element. How can I conditionally show() or hide() all those elements of the form 'id_*' depending on some other boolean? My problem is that the selector automatically selects multple id's, so how I can I trigger a show() or hide() selectively on each id that is selected?
You can pass a bool to .toggle() to tell it whether to show and hide, so just look through, like this:
$("*[id^=" + id + "_]").each(function() {
var someBool = condition; //figure out each one here, depending on...whatever
$(this).toggle(someBool);
});

Categories

Resources