Yui 2.0 Enabling input via multiple radio buttons - javascript

I have an application that uses Yui 2.0 and some custom JS. I did not write it originally so I am not really familiar with the Yui JS tools. For this problem I will look at three radio buttons and one text input.
The behavior right now is that when you select radio button s3 you enable text input toEnable.
What I would like to see is that when you select radio button S2 or S3 toEnable is enabled. However using the following example what happens is that once you try and use the NCRS_bind_to_radio method on S2, S3 loses the ability to effect the toEnable input all together.
Anyone have any idea how I can get this input enabled/disabled with both radio buttons?
<ul>
<li><label><input value="MET" type="radio" name="selector" id="s1"> 1</label></li>
<li><label><input value="MET" type="radio" name="selector" id="s2"> 2</label></li>
<li><label><input value="MET" type="radio" name="selector" id="s3"> 3</label></li>
<ul>
<input id="change" type="text" name="toEnable">
//S2 is the new addition here, bind for s3 has been around and works by itself, not with s2
NCRS_bind_to_radio('toEnable', 's2', true, true)
NCRS_bind_to_radio('toEnable', 's3', true, true)
function NCRS_bind_to_checkbox(input, checkbox, required, autofocus){
// Bind an input to a checkbox.
// i.e., the input is disabled until the checkbox is checked
// If "required", then "validate-required" is added/removed as needed.
// If "autofocus", then when the checkbox is checked, this field
// automatically gets focus.
if (typeof checkbox == "string") {
checkbox=document.getElementById(checkbox);
}
if (typeof input == "string") {
input = document.getElementById(input);
}
YAHOO.util.Dom.removeClass(input, 'validate-required');
if (required) {
YAHOO.util.Event.addListener(input, "blur",
NCRS_forms_passive_check_text, input, true)
}
input.disabled = !checkbox.checked;
// Set initial state of "validate-required"
if (checkbox.checked && required) {
YAHOO.util.Dom.addClass(input, 'validate-required');
}
// Add a "click" listener to the checkbox/radio
YAHOO.util.Event.addListener(checkbox, "click", function() {
if (checkbox.checked) {
input.disabled = false;
if (autofocus) {
input.focus();
}
if (required) {
YAHOO.util.Dom.addClass(input, 'validate-required');
}
} else {
NCRS_forms_set_error(input, true)
YAHOO.util.Dom.removeClass(input, 'validate-required');
input.disabled = true;
}
});
// If parent is a "radio" input, also add listeners to sibling radios.
if (checkbox.type == 'radio') {
var item;
for (var i=0; i < checkbox.form[checkbox.name].length; i++) {
item = checkbox.form[checkbox.name][i]
if (item != checkbox) {
// Add a "click" listener to the checkbox/radio
YAHOO.util.Event.addListener(item, "click", function() {
if (!checkbox.checked) {
NCRS_forms_set_error(input, true)
YAHOO.util.Dom.removeClass(input, 'validate-required');
input.disabled = true;
}
})
}
}
}
// Add a "click" listener to the dependent input.
// This was intended to re-enabled a disabled input,
// but doesn't work?
YAHOO.util.Event.addListener(input, "click", function() {
if (!checkbox.checked) {
checkbox.click();
input.focus();
}
});
}
NCRS_bind_to_radio = NCRS_bind_to_checkbox

The problem is that when one radio button is selected the others are deselected. I believe that when you select S3 the input is enabled briefly, then S2's deselect disables the input.
I would modify the method to take an array of inputs, and change this bit of code:
if (!checkbox.checked)
{
NCRS_forms_set_error(input, true)
YAHOO.util.Dom.removeClass(input, 'validate-required');
input.disabled = true;
}
to something like:
var state = true;
for (radio in radioArray)
{
state = state && !radio.checked;
}
if (state)
{
NCRS_forms_set_error(input, true)
YAHOO.util.Dom.removeClass(input, 'validate-required');
input.disabled = true;
}
I've worked with YUI a bit and let me offer you a tip to simplify your code. Instead of doing this:
if (typeof checkbox == "string")
{
checkbox=document.getElementById(checkbox);
}
if (typeof input == "string")
{
input = document.getElementById(input);
}
you can take advantage of YUI's DOM utilities.
var Dom = YAHOO.util.Dom;
checkbox = Dom.get(checkbox);
input = Dom.get(input);
YUI will check whether it's a string or not under the hood and always give you a reference to the element, even if you pass an element into get().
Paul

Related

How to extract this function to not duplicate code

This code checks if the checkbox is enabled on site if it is disabled then it disable the textbox.
Function disableTextBox() is a onclick function and the $(function() is used to check the behavior of the checkbox after refreshing the page, I did not use the localstorage for that because sometimes different browsers are used.
How can I write this code better to do not duplicate it?
If the checkbox is checked then the textbox should be enabled, if the checkbox is not checked then the checkbox should be disabled for any input. It saves the checkbox after clicking save button (that is different functionality) not connected with this problem, and when the user back to the page it should check if the checkbox is checked or not and adjust the textfield.
Any ideas how to write it better or something?
$(function()
{
var checkboxField = document.querySelector('#checkbox');
var textBox = document.querySelector('#textBox');
if (checkboxField.checked == true)
{
textBox.disabled = false;
}
else if (checkboxField.checked == false)
{
textBox.disabled = true;
}
});
function disableTextBox()
{
var checkboxField = document.querySelector('#checkbox');
var textBox = document.querySelector('#textBox');
if (checkboxField.checked == false)
{
textBox.disabled = true;
}
else if (checkboxField.checked == true)
{
textBox.disabled = false;
}
}
Call your disableTextBox() function, and instead of the if/else you could use the evaluated boolean result of checkboxField.checked straight ahead:
function disableTextBox() {
var checkboxField = document.querySelector('#checkbox');
var textBox = document.querySelector('#textBox');
textBox.disabled = !checkboxField.checked;
}
jQuery(function( $ ) {
// Do it on DOM ready
disableTextBox();
// and on button click
$('#btnDisableTextBox').on('click', disableTextBox);
// Other DOM ready functions here
});
prefering this way ;)
in this story every thing is boolean
Don't do testing if a boolean is True to déclare a true value for a if...
const
checkboxField = document.querySelector('#checkbox'),
textBox = document.querySelector('#textBox');
checkboxField.onchange = function()
{
textBox.disabled = !checkboxField.checked;
}
<label> modify texy <input type="checkbox" id="checkbox" checked>
<textarea id="textBox"disable> blah blah bla</textarea>

Disable <a class button if input fields empty

I know it's easy to do using < button > or < input type="submit" but how would you keep this button disabled unless both input fields are filled?
<input id="one" type="text">
<input id="two" type="text">
OK
Tie an event to both inputs, and check that both have values. Then enable the link.
$('#one, #two').blur(function() {
if($('#one').val() !== "" && $('#two').val() !== "") {
$('.button').attr('href','#');
} else {
$('.button').removeAttr('href');
}
});
and change your html to:
<a class="button">OK</a>
so that the link is disabled on page load. Here's a JSFiddle demo.
$(document).ready(function() {
$inputs = $('#one,#tow');
$inputs.change(check);
$submit = $('#submit');
function check() {
var result = 1;
for (var i = 0; i < $inputs.length; i++) {
if (!$inputs[i].value) {
result = 0;
break;
}
}
if (result) {
$submit.removeAttr('disabled');
} else {
$submit.attr('disabled', 'disabled');
}
}
check();
});
suggest use angular form
$(document).ready(function(){
//$(".button").attr('disabled', "disabled");
$(".button").click(function(){
one = $("#one").val();
two = $("#two").val();
if(one && two){
///both fields filled.
return true;
}
//one or both of them is empty
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="one" type="text">
<input id="two" type="text">
OK
This is my implementation if facing this kind of situation.
First, am add disabled class onto anchor tag on page load by using this style :
.disabled {
color : gray // gray out button color
cursor : default; // make cursor to arrow
// you can do whatever styling you want
// even disabled behaviour
}
We add those class using jquery on document ready together with keyup event like so :
$(function () {
// add disabled class onto button class(anchor tag)
$(".button").addClass('disabled');
// register keyup handler on one and two element
$("#one, #two").keyup(function () {
var one = $("#one").val(),
two = $("#two").val();
// checking if both not empty, then remove class disabled
if (one && two) $(".button").removeClass('disabled');
// if not then add back disabled class
else $(".button").addClass('disabled');
});
// when we pressing those button
$('.button').click(function (e) {
// we check if those button has disabled class yet
// just return false
if ($(this).hasClass('disabled')) return false;
});
});
DEMO

How to test if users has made any changes to a form if they haven't saved it

Basically the same functionality as stackoverflow when posting a question, if you start writing a post then try to reload the page. You get a javascript alert box warning message.
I understand how to check if the form has been changed, although how do I do the next step.
I.E: How to I check this when leaving the page, on here you get "This page is asking you to confirm that you want to leave - data you have entered may not be saved."?
EDIT: found correct answer here to another question https://stackoverflow.com/a/2366024/560287
I'm very sure that if you search, 'jQuery detect form change plugin', you will find something much more usable than this semi-pseudo code i'm about to write:
formChanged = function(form) {
form.find('input[type="text"], textarea').each(function(elem) {
if (elem.defaultValue != elem.value) {
return true;
}
});
// repeat for checkbox/radio: .defaultChecked
// repeat for ddl/listbox: .defaultSelected
return false;
}
usage:
if (formChanged($('form')) { // do something }
Note that this is to detect changes against the original rendered value. For instance, if a textbox has a value = "x", and the user changes it to "y", then changes it back to "x"; this will detect it as NO change.
If you do not care about this scenario, you can just do this:
window.formChanged = false;
$(':input').change(function() {
window.formChanged = true;
});
Then you can just check that value.
Yes, it is JavaScript as HTML is just a markup language.
Yes, jQuery can be used for this. It's preferable over vanilla JavaScript as it makes things easier, although it does add some overhead.
There are a number of ways to check if any of a form's controls have changed.
To check for changes from the default, most can be checked against the defaultValue property. For radio buttons, you should always have one checked by default, so check if it's still selected or not. Similarly for selects, set the selected attribute for the default option and see if it's still selected, and so on.
Alternatively, if all your form controls have an ID or unique name, you can collect all their values onload and then check their values when the form is submitted.
Another method is to listen for change events on each form control, but that is a bit over the top.
Here's a POJS version that takes the same approach as rkw's answer:
/*
Check if any control in a form has changed from its default value.
Checks against the default value for inputs and textareas,
defaultChecked for radio buttons and checkboxes, and
default selected for select (option) elements.
*/
function formChanged(form) {
var control, controls = form.elements;
var tagName, type;
for (var i=0, iLen=controls.length; i<iLen; i++) {
control = controls[i];
tagName = control.tagName.toLowerCase();
type = control.type;
// textarea
if (tagName == 'textarea') {
if (control.value != control.defaultValue) {
return true;
}
// input
} else if (tagName == 'input') {
// text
if (type == 'text') {
if (control.value != control.defaultValue) {
return true;
}
// radio and checkbox
} else if (type == 'radio' || type == 'checkbox') {
if (control.checked != control.defaultChecked) {
return true;
}
}
// select multiple and single
} else if (tagName == 'select') {
var option, options = control.options;
for (var j=0, jLen=options.length; j<jLen; j++) {
option = options[j];
if (option.selected != option.defaultSelected) {
return true;
}
}
}
}
// Not really needed, but some like the return value to
// be a consistent Type
return false;
}
Note that you need to be careful with select elements. For a single select, you should always set one option to selected, as if there is no default selected, some browsers will make the first option selected and others wont.

clearing radio input using jQuery

I have a bunch of radio buttons that are below. These radio buttons are part of a larger form and are optional, so If a user clicks on one, then decides he/she doesn't want the option selected, there is no way to undo this.
I was wondering if there was any jQuery etc, that, when clicking a link for example, clear any radio selection, based on the group name in the HTML?
Thanks
var group_name = "the_group_name";
// if jquery 1.6++
$(":radio[name='" + group_name + "']").prop('checked', false);
// prev than 1.6
// $(":radio[name='" + group_name + "']").attr('checked', false);
Working demo: http://jsfiddle.net/roberkules/66FYL/
var Custom = {
init: function() {
checkAllPrettyCheckboxes = function(caller, container){
// Find the label corresponding to each checkbox and click it
$(container).find('input[type=checkbox]:not(:checked)').each(function(){
if($.browser.msie){
$(this).attr('checked','checked');
}else{
$(this).trigger('click');
};
});
};
uncheckAllPrettyCheckboxes = function(caller, container){
// Find the label corresponding to each checkbox and unselect them
$(container).find('input[type=checkbox]:checked').each(function(){
$('label[for="'+$(this).attr('id')+'"]').trigger('click');
if($.browser.msie){
$(this).attr('checked','');
}else{
$(this).trigger('click');
};
});
};
I have created it in an init function, and adter then i called the init.
}
window.onload = Custom.init;
I have created a solution like roberkules' solution, except mine clears the radiobutton if you click the radiobutton itself while it's checked. Use this if you don't want to add an extra "Clear" button to your layout.
http://jsfiddle.net/P9zZQ/6/
// Requires JQuery 1.4+ (possibly earlier)
$(function () {
// Turn off a radiobutton if clicked again while on
var checkOff = function (event) {
var target = $(event.target);
if (target.is('label')) {
// deal with clicked label
if (target.attr('for')) {
// label has 'for' attribute
target = $('#' + target.attr('for'));
} else {
// label contains a radiobutton as a child
target = target.find('input[type=radio]');
}
}
if (target.is('input:checked[type=radio]')) {
event.preventDefault();
window.setTimeout(function () {
target.attr('checked', false);
}, 200);
}
}
// Find all radiobuttons and labels inside .radio-clearable containers
$(
'.radio-clearable input[type=radio], ' +
'.radio-clearable label').mousedown(function (event) {
// When clicked -- clear if it was checked
checkOff(event);
}).keydown(function (event) {
// When receiving space, escape, enter, del, or bksp -- clear if it was checked
if (event.which == 32 || event.which == 27 || event.which == 13 || which == 46 || which == 8) {
checkOff(event);
}
});
});
Usage: For any radiobutton you want to be clearable in this manner, wrap it in a container with class "radio-clearable".
The code is triggered by clicking or sending a key (Space, Escape, Enter, Del, BkSp) to the radiobutton element or to its label.

How to uncheck a radio button by clicking on it a second time

I have been searching in a lot of topics but I haven't found anything that really correspond to my problem :
I want to make radio buttons uncheckable (i.e. uncheck a radio button by clicking on it when it's already checked).
I found some solutions using a hidden radio button as a temporary comparison object but this doesn't fits to my existing context, so I would like to do the same without another radio button.
I tried to simply test and change the status/value of the radio button on "onclick" event but it hasn't been very successfull...
Thanks in advance,
Clem.
That's not what radio buttons are. If you try to make this work, you will just confuse your users.
If you want something that can be checked and then unchecked, use a checkbox. Radio buttons are for selecting exactly one of some set of options.
better so:
onclick="
var isChecked = $(this).attr('is_che');
if (isChecked) {
$(this).removeAttr('checked');
$(this).removeAttr('is_che');
}
else {
$(this).attr('checked', 'checked');
$(this).attr('is_che', 'true');
}"
I know this sort of action is non-standard for radio buttons, but the poster requested the functionality. The following is code that I've used in the past. I've found it not to be the most optimized (assuming a large # of radio buttons), but I also haven't taken the time to do that optimization.
// Allow for radio button unchecking
$(function(){
var allRadios = $('input[type=radio]')
var radioChecked;
var setCurrent = function(e) {
var obj = e.target;
radioChecked = $(obj).attr('checked');
}
var setCheck = function(e) {
if (e.type == 'keypress' && e.charCode != 32) {
return false;
}
var obj = e.target;
if (radioChecked) {
$(obj).attr('checked', false);
} else {
$(obj).attr('checked', true);
}
}
$.each(allRadios, function(i, val) {
var label = $('label[for=' + $(this).attr("id") + ']');
$(this).bind('mousedown keydown', function(e){
setCurrent(e);
});
label.bind('mousedown keydown', function(e){
e.target = $('#' + $(this).attr("for"));
setCurrent(e);
});
$(this).bind('click', function(e){
setCheck(e);
});
});
});

Categories