input:radio click function isn't triggering in IE / Firefox - javascript

I have a form with multiple inputs / radio buttons.
I also have a series of Yes & No radio buttons. When the "Yes" radio button is checked, I have some data slide down beneath.
HTML:
<div class="item seperator first clearfix">
<label>test</label>
<div class="radioWrap">
<label class="yes">
<input class="homepageContent" name="homepageContent" type="radio" value="yes" />
</label>
<label class="no">
<input class="homepageContent" name="homepageContent" type="radio" value="no" checked />
</label>
</div>
</div>
<div class="extrasInner">
<div class="item clearfix">
<label for="theContent">Your Content:</label>
<textarea id="theContent" name="theContent"></textarea>
</div>
</div>
<div class="extrasOuter hide clearfix">
Make Changes
<span>Click "Make Changes" to update.</span>
</div>
The jQuery:
$("input:radio[name=homepageContent], input:radio[name=addSocialIcons], input:radio[name=addTracking]").click(function() {
var value = $(this).val();
if (value == 'yes') {
$(this).parent().parent().parent().next().slideDown();
$(this).parent().parent().parent().next().next().slideDown();
} else {
$(this).parent().parent().parent().next().slideUp();
$(this).parent().parent().parent().next().next().slideUp();
}
});
Question 1) This works absolutely fine in Google Chrome, but not in Firefox and IE. It doesn't seem to recognise the click function?
Solved: I had a function within one of my files that removes the value from input fields on focus and this was stripping the value of the radio buttons as well in IE / Firefox (but not chrome!).
Question 2) Is my DOM traversing for the slideUp / slideDown an acceptable way of achieving what I'm trying to do? Are there any disadvantages to how I'm doing it and can it be improved?

Answer to #1
As Anthony Grist pointed out, there doesn't seem to be an issue with the click function.
Answer to #2
Your DOM traversal seem a bit unnecessary. In fact, your DOM structure is in need of rearrangement.
Using a checkbox instead of radio buttons. A checkbox only accepts two values: true or false, or in your case, yes or no. It seems more suitable.
Encapsulate your extras inner and extras outer divs inside your item div instead of having it next to the checkbox. This way, you make it easier to traverse within the item.
Also, you should read up on the different types of traverse functions JQuery has:
.parent() / .parents()
.children()
.closest()
.next()
.prev()
.siblings()
.find()
and many more.
Knowing all of these traverse functions, you'll most likely never ever do parent().parent().parent()... again. :)
Here's a JSFiddle example | Code
HTML
<ul>
<li class='item'>
<label>
<input class="homepageContent" name="homepageContent" type="checkbox" value="yes" />
Item 1
</label>
<div class='extras'>
<div class='inner'>
<label>
Your Content:<textarea name="content"></textarea>
</label>
</div>
<div class='outer'>
Make Changes
<span>Click "Make Changes" to update.</span>
</div>
</div>
</li>
</ul>
Javascript
$("input:checkbox").click(function() {
var $this = $(this),
$item = $(this).closest(".item");
if($this.is(':checked')){
$(".extras", $item).slideDown();
}else{
$(".extras", $item).slideUp();
}
});
CSS
.extras{
display: none;
}

Value of the radio button will always be same, no matter it is checked or not. If you want to know the particular radio button is checked or not then use this code. Based on the status of the radio button do your stuff.
var value = $(this).attr('checked')

That is working for me in FF (jsfiddle), although the DOM looks a little convoluted (I'm guessing because it's missing a lot of your other CSS/resources).
I think you can simplify the jQuery selectors a lot. Generally, using simple ID or class selectors will make the your page much more performant (and simpler!)
$('.homepageContent').click(function() {
var value = $(this).val();
if (value == 'yes') {
$('.extrasInner').slideDown();
$('.extrasOuter').slideDown();
} else {
$('.extrasInner').slideUp();
$('.extrasOuter').slideUp();
}
});
Hopefully doing something like this makes it work cross browser better too.

try this way
$("input:radio[name=homepageContent], input:radio[name=addSocialIcons], input:radio[name=addTracking]").click(function() {
var value = $(this).val();
if (value == 'yes') {
$(this).parents('.seperator').next().slideDown();
$(this).parents('.seperator').next().next().slideDown();
} else {
$(this).parents('.seperator').next().slideUp();
$(this).parents('.seperator').next().next().slideUp();
}
});
EDIT
​
and also a point
wrap your code inside
$(document).ready(function(){});
like this
$(document).ready(function(){
$("input:radio[name=homepageContent], input:radio[name=addSocialIcons], input:radio[name=addTracking]").click(function() {
var value = $(this).val();
if (value == 'yes') {
$(this).parents('.seperator').next().slideDown();
$(this).parents('.seperator').next().next().slideDown();
} else {
$(this).parents('.seperator').next().slideUp();
$(this).parents('.seperator').next().next().slideUp();
}
});
});

Related

When click on button, show divs with checked checkbox using JQuery

I want to use JQuery on my Coldfusion application for showing/hiding div elements with checkbox checked/unchecked within the div.
Basically, in a view I show multiple divs elements, every div have also more divs inside, one of these internal divs contains an input type checkbox that could come checked or unchecked.
I also have three buttons in that view 'Active, Inactive, All'. When clicking on Active I want to show all div elements with checkbox checked, not showing the unchecked, and the other way around when clicking on Inactive.
<div class="btn-group ">
<button id="actives" type="button">Actives</button>
<button id="inactives" type="button">Inactives</button>
<button id="all" type="button">All</button>
</div>
<div id="apiDiv">
<cfloop array="#apis#" index="api">
<div class="card card-found">
<div class="card-header">
<cfif Len(api.iconClass)>
<i class="fa fa-fw #api.iconClass#"></i>
</cfif>
#structKeyExists( api, "name" ) ? api.name : api.id#
</div>
<div class="card-body">
<p>#api.description#</p>
</div>
<div class="card-button">
<input class="#inputClass# ace ace-switch ace-switch-3" name="#inputName#" id="#inputId#-#api.id#" type="checkbox" value="#HtmlEditFormat( api.id )#"<cfif ListFindNoCase( value, api.id )> checked="checked"</cfif> tabindex="#getNextTabIndex()#">
<span class="lbl"></span>
</div>
</div>
</cfloop>
</div>
I´m not an expert at all with JQuery. The only thing I have done is what follows and I do not know whether if is a good beggining or not:
$("#actives").click(function (e) {
$("#apiDiv .card").filter(function() {
<!--- code here --->
});
});
Someone please that can help me with it? Thanks a lot in advance!
After your CF code executes, it will generate a .card for each loop iteration of your apis array. So you jQuery code will need a click handler for the #actives button and that will loop through each() iteration of the checkboxes to determine the checked/unchecked state. At that point find the closest() ancestor .card and show()/hide() the .card depending upon the checkbox state.
$("#actives").click(function (e) {
$('input[type=checkbox]').each(function() {
if (this.checked) {
$(this).closest(".card").show();
} else {
$(this).closest(".card").hide();
}
});
});
If you want to do it with jQuery code:
$('#actives').click(function(){
$('#apiDiv').show();
});
Working Fiddle
The code you are probably looking for is in these event handlers for your buttons:
function activesHandler() {
jQuery(".card-button > input:checked").parents(".card.card-found").show();
jQuery(".card-button > input:not(:checked)").parents(".card.card-found").hide();
}
function inactivesHandler() {
jQuery(".card-button > input:checked").parents(".card.card-found").hide();
jQuery(".card-button > input:not(:checked)").parents(".card.card-found").show();
}
function allHandler() {
jQuery(".card.card-found").show();
}
jQuery("#actives").click(activesHandler);
jQuery("#inactives").click(inactivesHandler);
jQuery("#all").click(allHandler);
I reproduced some of your ColdFusion by replacing it with JavaScript and provided a demonstration of the above event handlers in this JSFiddle.
Call the checkbox by its id and when it's checked, write a function to display the divs you want to display:
<input type="checkbox" id="check">
$document.getElementById("check").onclick = function(){
$document.getElementById("div_name").style.display="block"; // block displays the div.
}

Jquery deep deep cloning not preserving events

I have a list of items which need to be re-categorised depending on what the user decides.
<li class="indent_padd" data-show-question="53" data-tech-id="1" data-step-id="1" data-show-answers="1">
<p>
<span class="sub_step_title">
Example question text
</span>
</p>
<div class="slidecontainer">
<div class="slide_checkcontainer">
<div class="bs_sliders elRes" id="54_slider"></div>
<script>
$(document).ready(function(){
var slider_54_slider = document.getElementById('54_slider');
noUiSlider.create(slider_54_slider,{"start":0,"range":{"min":0,"max":100},"steps":4,"connect":"lower","direction":"ltr","orientation":"horizontal","pips":{"mode":"steps","stepped":"true","density":4}});
// Set one handled slider
slider_54_slider.noUiSlider.set(0);
slider_54_slider.noUiSlider.on('update',function(values){
$('#result_54_slider').val(values[0]);
})
})
</script>
<input type="text" value="0" id="result_54_slider" class="rangeUpdate" data-toggle="popover" data-trigger="manual" data-content="The permitted value range is 0-100" />
</div>
<div class="radio_container hasSlider">
<input type="checkbox" name="steps[54_4]" value="4" id="id_54_4" class="elRes" />
</div>
</div>
</li>
I then later run the following JS:
$('li[data-type="'+core_row+'"]').each(function(){
var thisID = $(this).data('typeid');
var newList = $(this).find('ul');
$(newList).empty();
var bringIn = $('li[data-'+get_items+'-id="'+thisID+'"]');
$(bringIn).each(function(){
$(newList).append($(this).clone(true,true));
$(this).remove();
})
})
I am using a slider (alt HTML range) as the question and had previously tried Bootstrap-slider (Destroy and re-initialize a bootstrap-slider) believing it was an issue with the slider code. I have since amended the code to use https://refreshless.com/nouislider/).
So what isn't working?? Basically in both instances the sliders lose their attached events - typically these relate to mouse actions as its a drag required. So why, when I'm using deep, deep cloning (and jq 3.5.1) are these events not being copied across when cloned? I would have expected to literally be able to "move" the LI and its entire contents/objects/variables etc and it work. If cloning isnt the answer - what is the best way of doing it?
If it makes a difference - the UL is hidden when it is appended to.

this.$ or this.$$ to select all elements with same id or class name - Polymer

I have 3 paper-toggle-buttons that I would like to have disabled until I click an "edit" button (makes sense to do that).
I have cobbled this together in a long-winded form, however I wanted to know if there was a way in PolymerJS that you could use either the this.$.ID-NAME or the this.$$('CLASS-NAME') to select all of the paper-toggle-buttons, assuming that I gave them all the same ID and CLASS names (bad practise to duplicate ID's I know).
Any help is appreciated. I know that it's currently working, but I just want to know if there's an easier way.
I am currently working with the following (the toggle will occur when clicking a button with on-click event "editMode"):
HTML
<div class="detail info horizontal layout">
<div class="bodyHeaderText flex">Active User</div>
<paper-toggle-button class="toggle" id="toggle" checked$="{{isActive}}" disabled></paper-toggle-button>
</div>
<div class="detail info horizontal layout">
<div class="bodyHeaderText flex">Operator</div>
<paper-toggle-button class="toggle" id="toggle" checked$="{{isOperator}}" disabled></paper-toggle-button>
</div>
<div class="detail info horizontal layout">
<div class="bodyHeaderText flex">Manager</div>
<paper-toggle-button class="toggle" id="toggle" checked$="{{isManager}}" disabled></paper-toggle-button>
</div>
PolymerJS
editMode : function() {
toggle1 = this.$.toggle1;
toggle2 = this.$.toggle2;
toggle3 = this.$.toggle3;
if( EditDiv.style['display'] == 'none' )
{
toggle1.toggleAttribute('disabled');
toggle2.toggleAttribute('disabled');
toggle3.toggleAttribute('disabled');
}
else
{
toggle1.toggleAttribute('disabled');
toggle2.toggleAttribute('disabled');
toggle3.toggleAttribute('disabled');
}
}
You could take a look to Polymer DOM API, there're a lof of functions to interact with the DOM. I think you're looking for Polymer.dom(this.root).querySelectorAll('.toggle')
$$ returns the first node in the local DOM that matches selector.
you can do
Array
.from(Polymer.dom(this.root).querySelectorAll('.foo'))
.forEach($0 => /* do something */)
;
Then, just a note, your snippet doesn't make much sense because you are performing the same operation in if and else statements:
if(expression) {
toggle1.toggleAttribute('disabled')
} else {
toggle1.toggleAttribute('disabled')
}
// is equal to:
toggle1.toggleAttribute('disabled')
your code could definitely look like:
{
editMode() {
return [
this.$.toggle1,
this.$.toggle2,
this.$.toggle3
]
.forEach($0 => $0.toggleAttribute('disabled'))
}
}

Show/Hide (via Bootstrap's collapse function) divs based on radio button

I'm trying to use Bootstrap's collapse functionality to show/hide divs based on which radio button is checked. I was able to get things to work fine when I don't use Bootstrap's collapse function, however, in order to give a more consistent feel I'd like to take advantage of this function.
Here's a snippet of the HTML in question:
<div class="col-xs-12 form-group">
<label class="radio-inline">
<input type="radio" id="send-now-radio" name="when" value="send-now" checked> <strong>Send Now</strong>
</label>
<label class="radio-inline">
<input type="radio" id="pickup-radio" name="when" value="pickup"> <strong>Hold for pickup</strong>
</label>
<label class="radio-inline">
<input type="radio" id="fax-radio" name="when" value="fax"> <strong>Fax</strong>
</label>
<label class="radio-inline">
<input type="radio" id="email-radio" name="when" value="email"> <strong>Email</strong>
</label>
</div>
<div class="col-xs-12">
<div id="send">Send</div>
<div id="pickup">Pickup</div>
<div id="fax">Fax</div>
<div id="email">Email</div>
</div>
And here's my javascript code:
$(document).ready(function()
{
// Hide all but one method div (since all are shown in case the user has JS disabled)
$('#send').show();
$('#pickup').hide();
$('#fax').hide();
$('#email').hide();
// Attach to the radio buttons when they change
$('#send-now-radio, #pickup-radio, #fax-radio, #email-radio').on('change', function () {
// Make sure that this change is because a radio button has been checked
if (!this.checked) return
// Check which radio button has changed
if (this.id == 'send-now-radio') {
$('#send').collapse('show');
$('#pickup').collapse('hide');
$('#fax').collapse('hide');
$('#email').collapse('hide');
} else if (this.id == 'pickup-radio') {
$('#send').collapse('hide');
$('#pickup').collapse('show');
$('#fax').collapse('hide');
$('#email').collapse('hide');
} else if (this.id == 'fax-radio') {
$('#send').collapse('hide');
$('#pickup').collapse('hide');
$('#fax').collapse('show');
$('#email').collapse('hide');
} else // if (this.id == 'email-radio') {
$('#send').collapse('hide');
$('#pickup').collapse('hide');
$('#fax').collapse('hide');
$('#email').collapse('show');
}
});
};
Here's a link to a JS fiddle with all of this: http://jsfiddle.net/DTcHh/156/
Unfortunately I'm missing something, cause the behavior is weird and not what I would expect.
First of all, excellent question. You provided code, made it clear what you tried, etc. Love it.
I forked your JSFiddle, and came up with this:
http://jsfiddle.net/emptywalls/EgVF9/
Here's the Javascript:
$('input[type=radio]').on('change', function () {
if (!this.checked) return
$('.collapse').not($('div.' + $(this).attr('class'))).slideUp();
$('.collapse.' + $(this).attr('class')).slideDown();
});
I wouldn't recommend using the collapse functionality from Bootstrap, it relies on a very different DOM structure from what you need. My fiddle uses just jQuery to accomplish what you need. My approach was to pair the radio buttons and divs with classes, so you can DRY up your code.
As #emptywalls mentioned, the Bootstrap collapse function won't work. I tried it and it almost does, except that it is based on clicking the source element, not it's state. A radio button needs to pay attention to it's state.
But I wanted something that allowed me to mark up the element with data tags and have it inherit the functionality, as the bootstrap collapse does. So I came up with this:
<input data-target="#send" data-toggle="radio-collapse" id="send_now_radio" name="when" type="radio" value="send-now">
<div id="send" class="collapse">Send</div>
And then have this included once in your site and it will apply to all such buttons.
$('input[type=radio][data-toggle=radio-collapse]').each(function(index, item) {
var $item = $(item);
var $target = $($item.data('target'));
$('input[type=radio][name="' + item.name + '"]').on('change', function() {
if($item.is(':checked')) {
$target.collapse('show');
} else {
$target.collapse('hide');
}
});
});
This uses the collapse function of Bootstrap for the animation. You could just as easily use jQuery hide() and show().
Unless I'm mistaken, #jwadsack code won't work if you have another group of radio buttons with a different name attribute.
That's because the $item and $target variables are declared globally. The $item variable will be overidded by the last group and only this one will hide/show the collaspe.
Adding var before the variable definition seems to fix the problem.
The code is then
$('input[type=radio][data-toggle=radio-collapse]').each(function(index, item) {
var $item = $(item);
var $target = $($item.data('target'));
$('input[type=radio][name="' + item.name + '"]').on('change', function() {
if($item.is(':checked')) {
$target.collapse('show');
} else {
$target.collapse('hide');
}
});
});

How to grey out checkbox unless radio button is selected?

very new to javascript, but any help to get me started would be appreciated. I have a simple form:
<div><input type="radio" name="o1" id="burger" />Burger</div>
<div id="yesFries"><input type="checkbox" name="e1" id="fries" />Fries with that?</div>
<div><input type="radio" name="o1" id="pizza" />Pizza</div>
<div><input type="radio" name="o1" id="hotdog" />Hot Dog</div>
I want the "Fries" checkbox greyed out unless the "Burger" radio button is selected. I'm not sure if Javascript or CSS is the best way to do it. Thanks in advance!
what you want to do is set the elements disabled, until the state of the radio changes, that'd be done with javascript, and then you'd add/remove the disabled class in the onchange of the radio button.
What javascript libraries are you considering using? jQuery would make this fairly simple.
$('#burger').change( function () {
if ($('#burger').checked() ) {
$('#fries').removeClass('disabled');
} else {
$('#fries').addClass('disabled');
}
});
Actually with a bit CSS3 you can mock up a very simplistic solution.
Here we don't gray the button out, but you make it visible just if the checkbox is checked.
But, we could also gray it out with a bit more of CSS on top of this example.
You will always have to consider what kind of support you want to offer.
But if you are fine with it working on modern browsers, just give it a go.
Here's the HTML
<label>
<input type="checkbox" name="test" />
<span>I accept terms and cons</span><br><br>
<button>Great!</button>
</label>
Here's the CSS
button { display: none}
:checked ~ button {
font-style: italic;
color: green;
display: inherit;
}
And here's the DEMO http://jsfiddle.net/DyjmM/
I've noticed that you don't specify whether or not you can use jQuery. If that's an option, please see one of the other posts as I highly recommend it.
If you cannot use jquery then try the following:
<script>
function setFries(){
var el = document.getElementById("burger");
if(el.checked)
document.getElementById("fries").disabled = false;
else
document.getElementById("fries").disabled = true;
}
</script>
<div><input type="radio" name="o1" id="burger" onchange="setFries();"/>Burger</div>
<div id="yesFries"><input type="checkbox" name="e1" id="fries" disabled="disabled"/>Fries with that?</div>
<div><input type="radio" name="o1" id="pizza" onchange="setFries();"/>Pizza</div>
<div><input type="radio" name="o1" id="hotdog" onchange="setFries();"/>Hot Dog</div>​
Simple example on jsFiddle
If you're using jQuery, a really-easy-to-use Javascript library (that I would highly recommend for beginners), you can do this in two steps by adding some code to a script tag in your page containing:
$(function(){
$("#burger").change(function() {
if ($(this).is(':checked')) $("#fries").removeAttr("disabled");
else $("#fries").attr("disabled", true);
});
});
This code does three things:
Listens for change events on #burger.
When a change occurs, execute the provided function.
In that function, set the disabled attribute of #fries to the checked property of #burger.
use JQuery
$().ready(function() {
var toggleAskForFries = function() {
if($('#burger').is(':checked')) {
$('#yesFries').show()
else
$('#yesFries').hide()
}
return false
}
toggleAskForFries()
$('#burger').change(toggleAskForFries)
}
Using jQuery: http://jsfiddle.net/kboucher/cMcP5/ (Also added labels to your labels)
You nay try this without any function library
<input type="checkbox" name="e1" id="fries" disabled />
JS
window.onload=function(){
var radios=document.getElementsByName('o1');
for(i=0;i<radios.length;i++) radios[i].onclick=checkFire;
};
function checkFire(e)
{
var fires=document.getElementById('fries');
var evt=e||window.event;
var target=evt.target||evt.srcElement;
if(target.checked && target.id==='burger') fires.disabled=false;
else
{
fires.checked=false;
fires.disabled=true;
}
}
DEMO.

Categories

Resources