Best way to assign value from radio button selection - javascript

I have created this little jsbin, with the framework for my use case: http://emberjs.jsbin.com/kufijixicu/1/edit?html,js,output
What I have tried to achieve in various ways, is to be able to assign the color value based on the selection in the list of radio buttons. I believe there to be a simple solution to this.
The solution must also provide a way where a potential existing value is already selected in the list. So if color is already selected, the selected one should be checked in the list.
Current solution
My current solution may be irrelevant, but I'll post it here for context.
As mentioned, I've tried various solutions. The one I have in my application at this moment works as described, it's buggy and messy which is why I'm looking for a better solution:
The ColorController has an action, which is attached to what would be the <li> in above jsbin:
selectColor: function(color) {
this.send('setColor', color);
this.forEach(function(item) {
item.set('isChecked', item.get('model') == color);
});
}
The IndexController has the setColor action:
setColor: function(color) {
this.set('color', color);
}
And the initial selection is set through this observer on the ColorController:
colorsChanged: function() {
if (this.filterBy('isChecked', true).get('length') == 0) {
var selectedColorId = this.parentController.get('model.color_id')+'',
selectedColor = this.filterBy('id', selectedColorId);
if (selectedColor.get('length') == 0) return;
selectedColor.objectAt(0).set('isChecked', true);
}
}.observes('this.[]')
This seems way too messy, but it also doesn't work 100%. For instance, a click on the radio button itself will actually un-check the radio button again.

In Ember, things like radio buttons and checkboxes are best wrapped up in components. Unfortunately, a few edge cases have prevented Ember from shipping a radio button component as part of core.
The first thing I'd do is see if someone else has already implemented this. Are you using Ember CLI? If not, you should be. Browsing Ember Addons I find two radio button components.
I'd give ember-radio-button a shot.

Related

How to find radio group checked property

Here, I've three radio group in a single page. But in the entire page I want to select only one radio option. Like if I'm selecting Monday then Tuesday selection should be unchecked automatically. How can I proceed with the logic, below logic is not working as expected.
sample JSON :
{
report:[
{
day:'Monday',
slot:[
'9-10am',
'10-11am',
'11-12am'
]
},{
day:'Tuesday',
slot:[
'9-10am',
'10-11am',
'11-12am'
]
},{
day:'Wednesday',
slot:[
'9-10am',
'10-11am',
'11-12am'
]
}
]}
JS code
for(var I=0; I<reports.length; I++){
var radios = document.getElementsByTagName('input')
if(radios[I].type === 'radio' && radios[I].checked){
document.getElementById(radios[I].id).checked = false
}
If you're able to create radio buttons in SurveyJS, you should be able to give the button group a name, so there would be no need for any additional JavaScript. Check out their documentation for an example.
Looks like the sort of nested structure you have for the buttons could be achieved with something like a dynamic panel or cascading conditions in SurveyJS. You should be able to render the available time slots dynamically with "visibleIf" based on the selected day.
I would definitely dig around the documentation of SurveyJS to find a solution there rather than hacking your way around it. But solely as an exercise, the problem in your current code could be that you're selecting a button by ID, which will not work correctly if you have tried to give the same ID to multiple buttons. After all, you already have the target button as radios[I], so you could just use radios[I].checked = false. Or the issue could be that you're unchecking the selected button AFTER the new selection has been made, which might actually uncheck the button you just clicked. Hard to say without additional information, but in any case, looping your inputs based on a value that might be something else than the actual number of inputs (you're using reports.length) is probably not the best idea, since that value might be different from the number of inputs in your form, which would mean that not all of them are included in the loop. Here are a couple of examples of what you could do instead:
// Get all radio buttons
const radioButtons = document.querySelectorAll('input[type="radio"]')
// If you need to uncheck the previously selected one (don't do this if you can avoid it!)
radioButtons.forEach(radioButton => {
// Use a mousedown event instead of click
// This gives you time to uncheck the previous one before the new one gets checked
radioButton.addEventListener('mousedown', () => {
// Get the currently selected button and uncheck it
const currentlySelected = document.querySelector('input[type="radio"]:checked')
if (currentlySelected) currentlySelected.checked = false
})
})
// You can add further options to the querySelector, such as [name]
// This gets the currently selected button in the specified group
const checkedRadioButton = document.querySelector('input[type="radio"][name="group-name"]:checked')
Here's a fiddle demonstrating this sort of "fake" radio button functionality (without a "name" attribute).
You can give all these radio buttons the same name, then one radio only will be checked.

Radio button validation in javascript for multiple screens

I am looking for some help on how to validate radio buttons generically across multiple screens and make the script reusable. I have manage to get it working by using a single class $('.radio_validate'). However, if I want to reuse the script for any other pages I would have to duplicate the script which is not ideal.(I'm not super familiar with JS so appreciate any support on this.)
Here's the code specifically on the radio button validation. Basically adding the error class if not checked and remove the error class if checked. Ideally, I would like to make $('.radio_validate') into something that is reusable if possible.
if( $('.radio_validate').is(':visible') && !$('.radio_validate').is(':checked') ){
$('.radio_validate')
.closest('.form__item')
.addClass('error');
shakeCurrentCard( $('.radio_validate').closest('.step') );
//return false;
}
else {
$('.radio_validate')
.closest('.form__item')
.removeClass('error');
}
If you plan on having every single radio button validated no matter the page, then use:
$("input[type='radio']")
However, if you don't want all of the radio buttons to be validated, then adding a class or data-attribute, to the radios you want validated is the best option.
loops through the radio instead of doing them all at once:
$("input[type='radio']").each(function() {
if ($(this).is(':visible') && !$(this).is(':checked')) {
$(this)
.closest('.form__item')
.addClass('error');
shakeCurrentCard($(this).closest('.step'));
//return false;
} else {
$(this)
.closest('.form__item')
.removeClass('error');
}
});

Item is moving on mouse click in bootstrap-duallistbox

I have taken the customized plugin which gives the feature for optgroup which is given over here Add scroll position return on select1. Add optgroup capability
Customized bootstrap-duallistbox (with optgroup feature)
I have created a sample example in plunker which shows a running example. The option group is working fine but the issue is that even through when I put move-on-select="false" still Item is moving on mouse click.
Can anyone please tell me why this is behaving like that
Working Plunker
<select ng-model="modal.selectedItems"
ng-options="item.name group by item.app for item in modal.allItems"
multiple
bs-duallistbox
move-on-select=false
></select>
Honestly, the easiest solution is just to change the implementation of selectGroup. I think it should be this:
function selectGroup(e) {
if(e.data.dlb.settings.moveOnSelect) {
move(e.data.dlb);
}
e.preventDefault();
}
You'll probably want to make a similar change to unselectGroup. The current implementation has strange behavior, where it moves things that aren't selected since it never unselects anything properly.
Edit:
The way that selections are made is faulty. I have no idea of the author's intent, but I suspect this implementation is closer to what a user would expect:
function selectGroup(e) {
if (e.target.tagName != 'OPTGROUP') return;
$(this).find('option').each(function (index, item) {
var $item = $(item);
if (!$item.data('filtered1')) {
if (!$item.prop('selected')) {
$item.prop('selected', true);
} else {
$item.removeAttr('selected');
}
}
});
if(e.data.dlb.settings.moveOnSelect) {
move(e.data.dlb);
}
e.preventDefault();
}
Again, make a similar change to unselectGroup. In the original code, the problem was that when you click on an individual option, the click would bubble up to the optgroup, hence the if guard. Also, the selection state should not be changed directly. That is already handled in the move function. It's much nicer to change the selected attribute, which the the move function later digests. In this way, it's also visually clear what is actually being selected. Thus, when you click an optgroup, it should toggle selected on each the item properties. You may want to modify how the removal of selected attribute is done.
Go with
http://www.virtuosoft.eu/code/bootstrap-duallistbox/
as #prakash Said in Commments.

Need either Mutually Exclusive Checkboxes or Deselectable Radio Buttons

I need either:
Radio buttons that can be deselected OR
Mutually exclusive checkboxes
Background info:
I have a repeater.
For each row in the repeater there is an associated document that can be either "Generated" or "Reprinted".
The user should be able to select up to one checkbox in any given row. After this, one button click will handle all of their selections in one pass.
When I search for "Mutually exclusive checkboxes", the common response is, "This is what radio buttons are for."
When I search for "Deselectable radio buttons", the common response is, "This is what check boxes are for."
Others have suggested custom JavaScript/ jQuery solutions but none in which the number of CheckBoxes/RadioButtons and their IDs are variable.
I find it hard to believe that this functionality isn't supported by ASP.NET controls. Has anyone faced this problem? Is there another control I could use or does this require a custom solution?
NOTE: The only third party software I have access to is Telerik's UI for ASP.NET AJAX, which doesn't contain an obvious solution.
Sample "Mutually exclusive checkboxes" in a repeater using Javascript:
window.onload = function(){
var repeater = document.getElementById('repeater');
var chks = repeater.querySelectorAll('[type=checkbox]');
for(var i = 0,chk;chk = chks[i];++i){
chk.onclick = function(){
if(this.checked){
for(var j=0,ch;ch=chks[j;++j]){
if(ch !== this)
ch.checked = false;
}//for
}//if(this...
}//chk.onclick
}//for(var i
}//window.onload
use a checkboxlist and handle the SelectedIndexChanged
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (checkedListBox1.CheckedItems.Count > 0)
{
foreach (int i in checkedListBox1.CheckedIndices)
{
checkedListBox1.SetItemCheckState(i, CheckState.Unchecked);
}
}
}
I'm more of a StackOverflow guy, but I eventually found this on GitHub.
https://gist.github.com/kikegarcia/6104607
And here's what I ended up with, along with some documentation. Basically the same thing, but using .prop instead of .attr since reading Tim Down's explanation of the difference between the two here: .prop() vs .attr()
// mutually exclusive checkboxes within the scope of a repeater row
function cbOnClick(sender) {
if (sender.checked)
$(sender).siblings(":checkbox").prop("checked", false);
// 1 2 3 4 5 6
}
Get the event-initiating checkbox as a jQuery object.
Get the sibling elements of our checkbox...
... with type = "checkbox".
Access their properties...
... of type "checked"...
... and set them to false. => Automatic unchecking of sibling checkboxes.

Keeping jQuery addClass when going back in browser

I'm having some trouble understanding how to turn my addClass into a cookie. I have a multi-select box that currently filters a list of products by adding an active class and then only showing products with the specified tags. If you make a selection and then click one of the products to view the product and then go back you have to reselect the previously selected options again. Below is the code used to make the selection.
tabsBlock.children('.tab').click(function() {
var tabContentClass = $(this).attr('id') + '-content';
tabsBlock.children('.active').removeClass('active');
tabsContentBlock.children('.active').removeClass('active').hide();
$(this).addClass('active');
if (tabContentClass.length) {
tabsContentBlock.children('#' + tabContentClass).addClass('active').show();
}
getTags();
});
All help is appreciated!
For a case like you describe I would would use hidden inputs. See this example:
Put checkbox values into hidden input with jQuery
Reason being, it sounds like you only need to store the values for this particular case. Storing in a cookie will require you to manage when the cookie expires which can be messy and cause undesired behaviors.
I don't know much about localStorage (as mentioned in the comment) -- that may be a viable option as well.
Thanks everyone for the help. I ended up using Astaroth's suggestion of using local storage.
$(".tag-group-label").click(function(){
localStorage.setItem('tagGroupLabelState', 'open');
});
$(document).ready(function(){
if(localStorage.getItem('tagGroupLabelState') == 'open') {
$('.tag-group-label').addClass('open').next('.tag-container').slideToggle(400, function(){
reCalcStickyElement();
});
}
});

Categories

Resources