How do I set two mutually exclusive check boxes in Jquery? - jquery-selectors

$(document).ready(function() {
$("input:txtAge1").click(function(event) {
if ($(txtAge1).attr("checked") == true) {
$(txtAge2).attr("checked", "unchecked");
$(txtAge2).attr("checked") == false)
}
if ($(txtAge2).attr("checked") == true) {
$(txtAge1).attr("checked", "unchecked");
$(txtAge1).attr("checked") == false)
}
});
});
<input type="checkbox" id="txtAge1" name="option1" value=""/>21<br>
<input type="checkbox" id="txtAge2" name="option2" value=""/>55<br>
I am trying to select either one checkbox or the other. So if one box is UNchecked, it should either be not allowed or force the
other box to BE checked ...in other words, enforce either one or the other but never allow
a "undefined" condition

Maybe I'm dumbing down the issue a bit, but why not try using radio buttons?
You can set one to be selected to avoid the user submitting an empty value.
Update: Since your customer wants checkboxes, here's a solution in jQuery:
$(document).ready(function(){
$('.radioButton').click(function() {
$('.radioButton').prop("checked", false);
$(this).prop("checked", true);
});
});
That's the jQuery code. You should set your input boxes up like this:
<input type="checkbox" id="txtAge1" class="radioButton" name="option1" value=""/>21
<input type="checkbox" id="txtAge2" class="radioButton" name="option2" value=""/>55
That should work, but it's untested. I might've missed something.

One solution is to add two click events, one for each checkbox. When one is clicked, the other is unclicked.
$("#checkbox1").click(function() {
$("#checkbox2").prop('checked', false);
});
$("#checkbox2").click(function() {
$('#checkbox1').prop('checked', false);
});

I ran into this issue recently, except I needed checkboxes instead of radio buttons as having both options unchecked was a requirement. I resolved it with something like this (adapted to the OP's code):
<input type="checkbox" id="txtAge1" />21
<input type="checkbox" id="txtAge2" />55
$(document).ready({
$("#txtAge1").click(function() {
if($("#txtAge1").is(':checked')) {
$("#txtAge2").prop('checked', false);
}
});
$("#txtAge2").click(function() {
if($("#txtAge2").is(':checked')) {
$("#txtAge1").prop('checked', false);
}
});
)};
Might not be that pretty, but it works.

I also wanted to note the excellent link http://rndnext.blogspot.com/2009/08/mutually-exclusive-html-select-elements.html here.
One caution though, I used it to mutex two dynamically generated select lists inside a div. . Since the content to be manipulated is not available at page load, it was not working as expected. Following solutions at jQuery - selecting dynamically created divs helped resolve the issue.

I would use this function. Allows mutual exclusion and allows uncheking:
$('#divId').find(':checkbox').click(function() {
var state=$(this).prop("checked");
$(':checkbox').prop("checked", false);
$(this).prop("checked", state);
});

$("input[type=checkbox]").click(function () {
$(this).siblings().prop("checked", false);
})

Related

backgrid.js - how to prevent multi-row selection?

I am new to backgrid and using it in a form to allow the user to select a row (via a checkbox) and then click "Submit". I cannot figure out how to configure my grid to behave like "radio buttons" in that only one row can be selected. Is this something backgrid natively supports or do I need to write a handler to "unselect" previously selected rows?
Here is a quick-n-dirty method:
wellCollection.on('backgrid:selected', function(model, selected) {
if (wellGrid.getSelectedModels().length > 1) {
model.trigger("backgrid:select", model, false);
alert('Only one selection is allowed.');
}
});
The downside is this approach requires the use of "SelectAll" which is really counter-intuitive to the user. I would prefer to be able to not use "SelectAll" but it is required to get the getSelectedModels object populated.
You could create a custom cell that renders radio buttons. The implementation below may need some more work but something like this will get you started:
var RadioCell = Backgrid.Cell.extend({
events: {
"click .selectedRadio": "makeSelected"
},
render: function () {
this.template = Mustache.to_html($("#radioCell").html(), this.model.toJSON());
this.$el.html(this.template);
this.delegateEvents();
return this;
},
makeSelected: function () {
// set all to inactive
this.model.collection.invoke('set', { "SomeModelAttrib": false });
// check if radio is checked and set the value on the model
var radioValue = $("input[name='someSelection']").is(":checked");
this.model.set("SomeModelAttrib", radioValue);
}
});
and the mustache template:
<script type="text/template" id="radioCell">
<input type='radio' class='selectedRadio' name='someSelection' value="{{SomeModelAttrib}}" {{#SomeModelAttrib}}checked{{/SomeModelAttrib}}>
</script>

AngularJS and Tab Order (Disabled Buttons)

I have a form, and I'm navigating only with TAB. Tab order should be input > select > button, but because of the ng-disable on the SUBMIT, on certain browsers the TAB out of the select will kick you somewhere else.
HTML
<div ng-app="myApp">
<div ng-controller="FirstCtrl">
<form name="myForm" ng-submit="submit()" novalidate>
First Name: <input type="text" ng-model="Data.FirstName" required><br>
Last Name: <select ng-model="Data.LastName" required>
<option value="Bigglesworth">Bigglesworth</option>
<option value="Burgermeister">Burgermeister</option>
</select><br>
<input type="submit" value="Submit" ng-disabled="myForm.$invalid" />
</form>
</div>
</div>
JS
var myApp = angular.module('myApp', []);
myApp.factory('Data', function(){
return {
FirstName: '',
LastName: ''
};
});
myApp.controller('FirstCtrl', function( $scope, Data ){
$scope.Data = Data;
$scope.submit = function() {
console.log('you just submitted, foolio');
}
});
JsFiddle here.
On Mac FF the final tab kicks you to the address bar before enabling the submit button. Mac Chrome works as you'd expect, focusing on the submit button after final tab. I know Windows is janky, but don't have exact specs to post.
Thoughts? How can I do this in a fool-proof fashion?
EDIT
I've selected #David B.'s answer as it's the best Angular solution. I ended up using a somewhat hidden element right after the the submit button so the focus would stay in the same general area. Lame and hacky, I know, but for a tight deadline it worked.
<h3><button class="fakebtn_hack">Confirmation</button></h3>
<style>.fakebtn_hack {background:none; border:none; color: #FF6319; cursor: default; font-size: 1em; padding: 0;}</style>
This happens because Firefox doesn't send a change event on key-driven changes of the select. Angular doesn't see the change until the tab is hit, so the submit button isn't enabled until after the tab has been processed by the browser (and focus sent to some other element, e.g., the address bar). The W3C standard suggests not sending the event until the control loses focus, although Chrome sends one for any change and Firefox does if the change was mouse-driven.
See the angularjs issue tracker for more: https://github.com/angular/angular.js/issues/4216
As suggested in the issue tracker, solve it by manually issuing the change event via the following select directive (http://jsfiddle.net/j5ZzE/):
myApp.directive("select", function () {
return {
restrict: "E",
require: "?ngModel",
scope: false,
link: function (scope, element, attrs, ngModel) {
if (!ngModel) {
return;
}
element.bind("keyup", function () {
element.trigger("change");
})
}
}
})
You'll need JQuery loaded before AngularJS to have the trigger function available on the element object.
Manually include an empty option (<option value=""></option>) in your select or the first option will be auto-selected when the control receives focus.
Unlike the default behavior, this empty option will not disappear after selecting a real option. I suppose you could remove the empty option by declaring all the options via ng-options or ng-repeat and then removing the empty one from the bound scope once a real option has been selected, but I've never tried it.

Javascript focus event goes to next form field

I am fairly new to Javascript and have a basic question. I have an HTML form with first_name and last_name input fields. I have the following Javascript code in the header but after the code runs, the focus goes to the next field (last_name). Why is that and how do I correct it?
Thank you.
<script>
function validateForm()
{
valid = true;
//validate first name
if (document.contactform.first_name.value == "")
{
//alert user first name is blank
alert("You must enter a first name");
document.getElementById("first_name").focus();
return false;
}
return valid;
}
</script>
and the form field code is:
input type="text" name="first_name" id="first_name" maxlength="50" size="30" onBlur="validateForm()"
A fix for this is to add a slight delay.. like so:
setTimeout(function() {
document.getElementById('first_name').focus()
}, 10);
Here is your example with this fix in jsfiddle: http://jsfiddle.net/FgHrg/1/
It seems to be a common Firefox problem.. I don't know exactly why but it has something to do with Firefox loading the javascript before the DOM is fully loaded.. in otherwords getElementById('first_name') returns null. But adding the slight delay fixes this problem.

jQuery Stop .blur() event when clicking "submit" button

I am building a small landing page with a simple demo e-mail signup form. I want to have the form field open up when focused, and then shrink back down on blur.
However the problem I'm facing is when you click the submit button this instigates the blur function, hiding the button and shrinking the form. I need to find a way to stop the .blur() method only when the user is clicking to focus on the submit button. Is there any good workaround for this?
Would appreciate any help I can get!
I know this question is old but the simplest way to do it would be to check event.relatedTarget. The first part of the if statement is to prevent throwing an error if relatedTarget is null (the IF will short circuit because null is equivalent to false and the browser knows that it doesn't have to check the second condition if the first condition is false in an && statement).
So:
if(event.relatedTarget && event.relatedTarget.type!="submit"){
//do your animation
}
It isn't the prettiest solution, but it does work. Try this:
$("#submitbtn").mousedown(function() {
mousedownHappened = true;
});
$("#email").blur(function() {
if (mousedownHappened) // cancel the blur event
{
mousedownHappened = false;
}
else // blur event is okay
{
$("#email").animate({
opacity: 0.75,
width: '-=240px'
}, 500, function() {
});
// hide submit button
$("#submitbtn").fadeOut(400);
}
});​
DEMO HERE
Try this inside .blur handler:
if ($(':focus').is('#submitbtn')) { return false; }
why not rely on submit event instead of click? http://jsbin.com/ehujup/5/edit
just couple changes into the html and js
wrap inputs into the form and add required for email as it obviously suppose to be
<form id="form">
<div id="signup">
<input type="email" name="email" id="email" placeholder="me#email.com" tabindex="1" required="required">
<input type="submit" name="submit" id="submitbtn" value="Signup" class="submit-btn" tabindex="2">
</div>
</form>
in js, remove handler which listen #submitbtn
$("#submitbtn").on("click", function(e){
e.stopImmediatePropagation();
$("#signup").fadeOut(220);
});
and use instead submit form listerer
$("#form").on("submit", function(e){
$("#signup").fadeOut(220);
return false;
});
you may use $.ajax() to make it even better.
Doing this you gain point in terms of validation and the native browser's HTML5 validator will make check email format where it is supported.

In JQuery, How can I avoid two $(this) selectors from causing conflict to each other as part of an each() method?

everybody.
I'm sort of newbie in JQuery and I'm trying to do the following: I've got both select and checkbox elements and I want certain changes to occur each time the document is loaded or refreshed. What I mean is, the background of the selects should be different depending on whether an empty option (or prompt) is currently selected or not. Also, depending on the former, an (accompanying) checkbox should be enabled or disabled as well (empty option selected => checkbox disabled OR the other way around).
Now, I won't be inputting any ids (from selects or checkboxes) manually. Instead, I want to get them all dinamically by using an each method on the correct selector. And that's where the problem arises.
So, lets say we've got this:
<select id="select_01">
<option value="">Whatever as prompt...</option>
<option value="first">First option</option>
</select>
<input id="check_box_01" type="checkbox" />
<select id="select_02">
<option value="first" selected="selected">First option</option>
<option value="">Whatever as prompt...</option>
</select>
<input id="check_box_02" type="checkbox" />
and in a script I put this:
$(document).ready(function() {
$("select,:checkbox").each(function() {
mySelectId = $("#" + $(this).attr("id"));
myCheckboxId = $("#" + $(this).attr("id"));
if (mySelectId.attr("value") === "") {
mySelectId.css({
"background": "grey"
});
myCheckboxId.attr("disabled", "disabled");
}
});
});
The problem, as you can see, is the $("select,:checkbox").each method not being able to discern which $(this) represents what (well, that and my own obvious lack of knowledge to solve this problem).
If I leave one of the selectors out, everything works well but (obviously) it only affects selects or checkboxes, but not both. Something like this works (the background changes as it should but checkboxes are left unaffected):
$(document).ready(function() {
$("select").each(function() {
mySelectId = $("#" + $(this).attr("id"));
if (mySelectId.attr("value") === "") {
mySelectId.css({
"background": "grey"
});
}
});
});
¿Can I make mySelectId and myCheckboxId two different, easily recognizable variables within the scope of the method? Any help will be greatly appreciated. Thanks in advance!
Carlos Pardilla.
PD: (I wanted to say "Hi everybody" on top, but the edits keep on cutting the whole greeting - dont' know why)
In your loop, the each() function, you do not get the elements as pairs.
You get them one-by-one.
I would do it in two steps (two loops), one for the selects, one for the checkboxes.
if ( $(this).is("select") ) {
mySelectId = $("#" + $(this).attr("id"));
}else if (( $(this).is(":checkbox") ) {
myCheckboxId = $("#" + $(this).attr("id"));
}
Well, I finally managed to get it working thanks to the both of you:
$(document).ready(function() {
$("select, :checkbox").each(function() {
if ($(this).is("select")) {
mySelectId = $("#" + $(this).attr("id"));
if (mySelectId.attr("value") === "") {
mySelectId.css({
"background": "grey"
});
}
} else if ($(this).is(":checkbox")) {
myCheckboxId = $("#" + $(this).attr("id"));
if (mySelectId.attr("value") === "") {
myCheckboxId.attr("disabled", "disabled");
}
}
});
});
The only thing I do not find myself entirely confortable with is with having to repeat if (mySelectId.attr("value") === "") {, (I try to apply Rails's DRY philosophy when possible), but I'm sure I'll find a workaround.
I find the is() method (wich I wasn't previously too familiar with) to be of much help in situations such as these.
Feel free to tinker with this as you'll please: http://jsfiddle.net/CarlosPF/DsHUp/
Many thanks to you both! Your help has been invaluable.
Carlos Pardilla.