Select neighbor of element selected by class and attribute - javascript

I have almost completed this but am stuck on an advanced selector. I am trying to select a label next to a radio button, but its a little more complex than that.
I have a select box. Only radio buttons (and their sibling labels) in which the value of the select matches the name (well part of) of the radio button.
I have a JS fiddle set up, what I am looking to do, is on selection of January, everything except Jan should be hidden, and when i select February, it should change. I'm trying to do this with just the name and no additional classes but if it comes down to it, I can add them.
http://jsfiddle.net/alpha1beta/G9Sz2/2/
Below is my working selector to get the radio button, and now am looking at how to get their + label next to it
$('.radio([name="insights[interview_questions[' + curr_sel + ']]"])').css('display','inline');
Thanks in advance!

Try
var $radios = $('.radio'), $all = $radios.add($radios.nextUntil('.radio'));
$("#interview_month").change(function () {
var $mon = $radios.filter('.radio[name="insights[interview_questions[' + this.value + ']]"]');
var $cur = $mon.add($mon.nextUntil('.radio')).show();
$all.not($cur).hide()
}).change();
Demo: Fiddle

You may want to check the next() function, it returns the next sibling

Try this:
$("#interview_month").change(function () {
$('.radio , label').hide();
var sel = '.radio[name*="' + $("#interview_month").val() + '"]';
$(sel).add(sel+'+label').css('display', 'inline');
});

Related

For through html elements and appending only appends to last element

I have a text input and on focusout, I have couple of select elements which I want to fill with the text field's value.
And I have bunch of select tags with 'NameSelect' class
$('.textField').focusout(function() {
var name = $(this).val();
var NameOption = $('<option>', { value: name, text: name, attrid: '1'});
var selects = $('#mainForm').find('.NameSelect');
$(selects).each(function(i, obj) {
console.log($(obj)); // it seems to get the right select
$(obj).append(NameOption);
})
}
However, when I do that, even though the selects get all the right elements and for loop for the right count, it only appends the option input to the latest object, not all of them.
What am I missing here?
The issue is because NameOption holds a reference to the option, hence if you append() it multiple times it will move between each parent element.
To fix this you can either clone() the element when you append it:
selects.append(NameOption.clone());
Or you could just provide append() with a string to create a new element each time it's called:
$('.textField').focusout(function() {
var name = $(this).val();
$('#mainForm').find('.NameSelect').append('<option value="' + name + '" attrid="1">' + name + '</option>');
})
});
Note that in both cases the each() is not required.

Jquery checkbox affect one item not all items

I was wondering if someone can help me please, I have a series of checkboxes that when clicked change the div background, activate 2 inputs and add a tick icon. My issue is that when one check box is checked the class .TickIco shows for all and so does the .disableToggle
How can i get it so that this only affects one .checkBG at a time and not all of them?
Hopefully this JSFiddle will help explain what I mean.
https://jsfiddle.net/jayjay89/xfg96we5/
thanks
$(".checkBG").click(function () {
var checked = $(this).is(':checked');
var location = $(this).parent().parent().parent();
if (checked) {
$(this).parent().parent().parent().addClass("activeformBlock");
$(".tickIco").show();
$(".disabletoggle").removeAttr("disabled");
} else {
$(this).parent().parent().parent().removeClass("activeformBlock");
$(".tickIco").hide();
$(".disabletoggle").attr('disabled', 'disabled');
}
});
thanks
you can use the context in which the selector will be looked.
You already have the location variable which is the parent context for one of your row
$(".checkBG").click(function () {
var checked = $(this).is(':checked');
var location = $(this).parent().parent().parent();
if (checked) {
$(this,location).parent().parent().parent().addClass("activeformBlock");
$(".tickIco",location).show();
$(".disabletoggle",location).removeAttr("disabled");
} else {
$(this,location).parent().parent().parent().removeClass("activeformBlock");
$(".tickIco",location).hide();
$(".disabletoggle",location).attr('disabled', 'disabled');
}
});
Your issue lies in the way you are selecting the .tickIco and .disabletoggle elements:
$(".tickIco").show();
$(".disabletoggle").removeAttr("disabled");
These jquery calls use selectors that match all classes of .tickIco and .disabletoggle.
Dirty solution (finds elements of the parent with matching classes using .find()):
$(this).parent().parent().parent().find(".tickIco").show();
$(this).parent().parent().parent().find('.disabletoggle').removeAttr("disabled")
Better solution:
jQuery selecter takes the context of your selection as a second argument so you can:
var context = $(this).parent().parent().parent();
$(".tickIco", context).show();
$('.disabletoggle', context).removeAttr("disabled")

Reverse changes when value is no longer selected (specified IDs)

I have a function that changes the color of a text of one of 12 DIVs on my website.
$('.position_select').change(function(){
var selected = $(this).val();
var shelf = $("#mockup_shelf_" + selected)
$(shelf).css({ color: "#FF6633" });
}).change();
It's a mock-up for a user to show on which position they've chosen to display their buttons. It's based on which of the numbers (from 1 to 12) are selected in select tag:
f.select :position, (1..12), {prompt: 'Select Position'}, {required: 'true', class: "position_select" }
I want to change this DIV's text back to black (or all unselected DIVs) if the user unselects this specific position and chooses another. How can I do it?
Colors get back to what they should be on page reload, but that's not the point.
Easiest way is to just update all elements to the default color, and then change the color of the element that corresponds to the selected item like this:
$('.position_select').change(function(){
//reset all elements color
$("[id^=mockup_shelf_]").css({ color: "#000000" });
//now find and set the color of the selected item
var selected = $(this).val();
var shelf = $("#mockup_shelf_" + selected)
$(shelf).css({ color: "#FF6633" });
}).change();
I'm using the starts with attribute selector since the beginning of every ID is the same.
http://www.w3schools.com/cssref/sel_attr_begin.asp
The [attribute^=value] selector matches every element whose attribute
value begins with a specified value.
Alternately, you could assign the same class to all mockup_shelf elements and then use this class selector to target them all: $(".mockup_shelf").css({ color: "#000000" });
And since good things come in threes, you could also completely eliminate any styling information from the script and create 2 css classes in your stylesheet (allowing you to do more complex styling easier). For example:
.mockup_shelf {
color: #000000;
}
.mockup_shelf.selected {
color: #FF6633;
}
All of your mockup_shelf elements would have the mockup_shelf class, and then in script you could add or remove the selected class like so:
$('.position_select').change(function(){
//reset selected element's color
$(".mockup_shelf.selected").removeClass("selected");
//now find and set the color of the selected item
var selected = $(this).val();
var shelf = $("#mockup_shelf_" + selected)
$(shelf).addClass("selected");
}).change();
EDIT
Since you clarified that you have a multi-select box, I've gone ahead and created a sample fiddle showing how to accomplish this with multiple selections:
https://jsfiddle.net/ofhw085r/
$('.position_select').change(function() {
//remove class from all shelves to reset them
$(".mockup_shelf.selected").removeClass("selected");
var $position_select = $(this); //explicitly labeling this to avoid confusion in the next part
$position_select.find("option:selected").each(function() {
var $option = $(this); //'this' now has a new context, so label it to avoid confusing it with 'this' in the outer context
var shelf = $("#mockup_shelf_" + $option.val());
shelf.addClass("selected");
});
}).change();
Essentially, every time the change event fires on your select, you'll reset the styles on all mockup_shelf elements and then loop through every selected option (using jquery's built-in :selected selector), and then add the selected class to the associated shelf.

.val with invalid value on select

I have a <select>, and on button click users can select the next option:
$(".someButton").on('click', function () {
var $opt = $("select :selected");
$("select").val($opt.next().val());
});
The problem is that on the last option, $opt.next().val() returns some unselectable value, and apparently jQuery selects the first option by default. What I would like is for it to stay on the last option.
Is there any way to do this (preferably without checking the position of $opt or the length of $opt.next())?
Here's a more efficient way to do it:
$(".someButton").on('click', function () {
var el = $("select")[0];
el.selectedIndex = Math.min(el.selectedIndex + 1, el.length - 1);
});
If you want to stick to jQuery, set the option to selected:
$opt.next().prop('selected', true);
If $opt is the last one, .next() will return an empty set, so nothing will change.
I would just handle the case to be honest. It would be simple to add the following:
if(!$opt.is(':last-child')) {
$("select").val($opt.next().val());
}

How to toggle checkbox selection rather than only selecting?

I currently am using this JavaScript code snippet to select 3 checkboxes at a time
$(document).ready(function() {
var $cbs = $('input:checkbox[name="select[]"]'),
$links = $('a[name="check"]');
$links.click(function() {
var start = $links.index(this) * 3,
end = start + 3;
$cbs.slice(start,end).prop("checked",true);
});
});
Currently this code only selects the checkboxes, however I was wondering if anyone knew how to modify it so that it toggles the checkbox selection on and off?
Here's an example of my current code: "jsfiddle" - click the 1-3, 4-6 links etc to check the checkboxes.
Make the second argument to the prop("checked", ...) call depend on the "checked" status of the first (or other) checkbox in the slice:
// ...
$cbs.slice(start,end).prop("checked", !$cbs.slice(start).prop("checked"));
Here's an updated jsFiddle.
[Edit] Or to update each checkbox in the slice individually:
// ...
$cbs.slice(start,end).each(function() {
var $this = $(this);
$this.prop("checked", !$this.prop("checked"));
});
http://jsfiddle.net/ShZNF/3/
$cbs.slice(start,end).each(function() {
if ($(this).is(":checked")) {
$(this).removeProp("checked");
} else {
$(this).prop("checked",true);
}
});
http://jsfiddle.net/ShZNF/1/
Edit: Maeric's solution is better. I wasn't aware removeProp had this gotcha:
Note: Do not use this method to remove native properties such as
checked, disabled, or selected. This will remove the property
completely and, once removed, cannot be added again to element. Use
.prop() to set these properties to false instead.

Categories