Disable an input field when checking a checkbox in Backbone - javascript

I'm completely new to Backbone.js and jQuery and I'm trying to set an input field of a form to "disabled" when I check a checkbox. I'm not sure if I have to do it the way I show in the code below, if so what should I do in the disableInput function?
JS
events: {
'change #myCheckbox': 'disableInput',
},
disableInput : function(){
...
}
HTML
<div class="x">
<input type="text" id="myInput">
<input type="checkbox" id="myCheckbox">
<div>
EDIT: This may seem like dupplicate of other posts, but those questions are about vanilla JS I'm using Backbone here so it's not the same.

If you want to go the pure CSS route, you can place the checkbox above the text and switch the order to your liking using flexbox. Then, you can write CSS that changes the opacity and pointer-events for the checkbox sibling.
.x {
display: flex;
}
.x #myCheckbox {
order: 2;
}
.x #myCheckbox:checked + #myInput {
pointer-events: none;
opacity: 0.6;
}
<div class="x">
<input type="checkbox" id="myCheckbox">
<input type="text" tabindex="-1" id="myInput">
</div>
Tab Issue
In order to stop someone from tabbing into the input, you can add tabindex="-1" to the input.

Here is a simple one liner
Granted I am not familiar with backbone.js but you should be able to figure out how to incorporate this.
function disableInput(){
document.getElementById("myInput").disabled=document.getElementById('myCheckbox').checked
}
<div class="x">
<input type="text" id="myInput">
<input type="checkbox" onchange="disableInput();" id="myCheckbox">
<div>

I think Backbone way would be the following
events: {
"change #myCheckbox": function() {this.disableInput.apply(this, arguments);}
},
disableInput: function(args) {
var checked = $(args.target).is(":checked");
this.$el.find("#myInput").disabled = checked;
}

Related

On input type=radio checked, add a class to input=text

How can I link a radio button and a text input filled so when the radio is selected the text in the input text area will also change to lets say... red-bold?
I know the logic is:
When radio-A and input-text-A is checked, add CSS class to input-text-A.
When unchecked remove class. If radio-B is selected change input-text-B, and so on...
But right now the simple script targets all text inputs.
$('input[type=text]').addClass('red');
.red {
color: red;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-inline">
<label class="" for="">
<input class="" type="radio" name="answer-Q1" value="option1"> A. </label>
<input type="text" name="answers" class="" placeholder="" required>
</div>
<br>
<div class="form-inline">
<label class="">
<input class="" type="radio" name="answer-Q2" value="option1"> B. </label>
<input type="text" name="answers" class="" placeholder="" required>
</div>
Give your markup, there's actually no need to add any classes or use javascript, you can do what you want with pure CSS:
input[type="radio"]:checked + input[type="text"] {
color: red;
font-weight: bold;
}
As for how to add the class with jQuery, I tend to write "robust" solutions that are maybe a bit longer, but are not as "brittle" (meaning: if markup changes a bit, the script will still work). The way I would write this - assuming no control over markup - would be using jQuery's closest and find to locate the target text inputs:
// no-conflict-save document ready shorthand
jQuery(function($) {
// bind to the "change" event of all inputs that are radio buttons
jQuery('input[type="radio"]').on('change', function() {
// find the text input
var $text_input = $(this).closest('div').find('input[type="text"]');
// if there isn't one, get out
if ( ! $text_input.length ) {
return;
}
// if the radio button is checked, add the class
if ($(this).is(':checked')) {
$text_input.addClass('red');
} else {
// otherwise, remove the class
$text_input.removeClass('red');
}
});
});
However, if I DID have control over markup, I would add a class to the radio input element, and use that to both make the script more "generically" useful, as well as narrow down the scope of which inputs were being bound (which would allow this same script to work effectively on checkboxes + text inputs as well):
// no-conflict-save document ready shorthand
jQuery(function($) {
// bind to the "change" event of any inputs with the "watch-change" class
jQuery('input.watch-change]').on('change', function() {
// find the text input. Note, this would find multiple text inputs if they existed.
var $text_input = $(this).closest('div').find('input[type="text"]');
// if there isn't a text input to work with, get out
if ( ! $text_input.length ) {
return;
}
// if the radio button is checked, add the class
if ($(this).is(':checked')) {
$text_input.addClass('red');
} else {
// otherwise, remove the class
$text_input.removeClass('red');
}
});
});
And, honestly, with a better understanding of your project scope, it might be possible to write an even more efficient, re-usable snippet of script.
Do this:
$("input[type=radio]").on("change", function(e) {
if (e.currentTarget) {
e.currentTarget.next("input[type=text").addClass("red");
}
});
Here is the working code.
$('input:radio').click(function() {
$('label:has(input:radio:checked)').addClass('rightAnswer');
$('label:has(input:radio:not(:checked))').removeClass('rightAnswer');
});
.container {margin:0 auto; margin-top:50px;}
.rightAnswer {font-weight:bold; color:#2979FF;}
.inputAnswers {width:200px;}
.block {display:block;}
input[type="radio"]:checked + input[type="text"] {
color: #2979FF;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<label class="block" for="answer-Q1A">
<input type="radio" class="" name="answer-Q1" value="1"> A.
<input type="text" name="answers" class="inputAnswers" id="answer-Q1A" placeholder="" required></label>
<label class="block" for="answer-Q1A">
<input type="radio" class="" name="answer-Q1" value="1"> B.
<input type="text" name="answers" class="inputAnswers" id="answer-Q1A" placeholder="" required></label>
<label class="block" for="answer-Q1A">
<input type="radio" class="" name="answer-Q1" value="1"> C.
<input type="text" name="answers" class="inputAnswers" id="answer-Q2A" placeholder="" required></label>
</div>

Find nearest div with class disableDiv and disable all of its contents

In this code I am checking the chekbox with class disableDivCheckbox and the code is disabling all of the div content with class disableDiv. But if I apply this combination to another checkbox and another div, this is not working properly. So I want to find closest div with class disableDiv and disable only that div. I am using disabale * because I want to disbale div and its contents.
$(".disableDivCheckbox").click(function () {
if ($(this).is(":checked")) {
$('.disableDiv *').removeAttr("disabled");
}
else {
$('.disableDiv *').val('').prop('checked', false).attr("disabled", "disabled");
}
});
fiddle : https://jsfiddle.net/8c0x1pho/
You can try this approach:
Get checked state and save it in a variable
Navigate to all necessary elements using this. It will make your code more modular.
Try not to use * selector. Use more specific selectors as this will specify element types you are manipulating and make your code more reusable.
Instead of attr and removeAttr, you can just set value of disabled as true or false . You can just use !$(..).is(":checked")
Sample:
// Only call functions. DON'T declare any functions in ready.
$(document).ready(function() {
// Have a common function.
// If size grows, this can be exported to its own file
registerEvents();
// Initialise on load states.
updateUIStates("#addBusinessObjectivesCheckbox")
});
function registerEvents() {
$(".disableDivCheckbox").click(function() {
updateUIStates(this)
})
}
function updateUIStates(el) {
var isNotChecked = !$(el).is(":checked");
var inputs = $(el)
.parents(".checkbox")
.siblings(".disableDiv")
.find('input');
inputs.attr("disabled", isNotChecked)
isNotChecked && inputs.val('').prop('checked', false)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<fieldset id="AddBusinessObjectivesFieldset" class="">
<legend>
Add business objectives
</legend>
<div class="checkbox">
<label>
<input type="checkbox" value="addBusinessObjectivesCheckbox" name="addBusinessObjectivesCheckbox" class="disableDivCheckbox" id="addBusinessObjectivesCheckbox"> Add business objectives
</label>
</div>
<div style="border: 2px solid;margin-bottom: 5px;border-color: gray;padding: 0px 0px 0px 5px;margin-top: 5px;margin-right: 10px;" class="disableDiv">
<div class="form-inline" style="margin-top:5px;margin-bottom:5px;">
<table>
<tr>
<td>
<div class="radio">
<label>
<input type="radio" name="AddBusinessObjectives" id="" value="0" class=""> Fixed N
</label>
</div>
</td>
<td>
<div class="radio">
<label>
<input type="radio" name="AddBusinessObjectives" id="" value="1" class=""> Random upto N
</label>
<input type="text" placeholder="Enter N" id="indexTextboxAddBusinessObjectives" name="indexTextboxAddBusinessObjectives" style="width:70px" class="" />
</div>
</td>
</tr>
</table>
</div>
</div>
</fieldset>
Pointers
$(document).ready() is more like init function. Try to call functions instead of defining in it. This will make easier to understand as it will depict a flow.
Use pure functions and call then. Like onChange, you can call few functions: updateUIStates(), postDataToServer(), processResponse(), otherTodos(). This may look like overkill but in long run this will help.
Create a tree structure in your markup.
<div class="container">
<div class="checkbox-container">...</div>
<div class="input-containers">...</div>
</div>
This will ease navigation part. No matter what structure you use, keep it standardised. This will keep your JS clean.
Try this,
$(".disableDivCheckbox").click(function () {
if ($(this).is(":checked")) {
$(this).closest('.disableDiv *').removeAttr("disabled");
} else {
$(this).closest('.disableDiv *').val('').prop('checked', false).attr("disabled", "disabled");
}
});
This means that, you will disable all content of only that disableDiv class to which disableDivCheckbox belongs.
Give it a try, this will work.

Condtionally disable button by Radio and Checkbox

I would like to conditionally disable a button based on a radio and checkbox combination. The radio will have two options, the first is checked by default. If the user selects the second option then I would like to disable a button until at least one checkbox has been checked.
I have searched at length on CodePen and Stack Overflow but cannot find a solution that works with my conditionals. The results I did find were close but I couldn't adapt them to my needs as I am a Javascript novice.
I am using JQuery, if that helps.
If needed:
http://codepen.io/traceofwind/pen/EVNxZj
<form>
<div id="input-option1">First option: (required)
<input type="radio" name="required" id="required" value="1" checked="checked">Yes
<input type="radio" name="required" id="required" value="2">No
<div>
<div id="input-option2">Optionals:
<input type="checkbox" name="optionals" id="optionals" value="2a">Optional 1
<input type="checkbox" name="optionals" id="optionals" value="2b">Optional 2
<div>
<div id="input-option3">Extras:
<input type="checkbox" name="extra" id="extra" value="3">Extra 1
<div>
<button type="button" id="btn">Add to Cart</button>
</form>
(Please excuse the code, it is in short hand for example!)
The form element IDs are somewhat fixed. The IDs are generated by OpenCart so I believe the naming convention is set by group, rather than unique. I cannot use IDs such as radio_ID_1 and radio_ID_2, for example; this is an OpenCart framework facet and not a personal choice.
Finally, in pseudo code I am hoping someone can suggest a JQuery / javascript solution along the lines of:
if radio = '2' then
if checkboxes = unchecked then
btn = disabled
else
btn = enabled
end if
end if
Here is a quick solution and I hope that's what you were after.
$(function() {
var $form = $("#form1");
var $btn = $form.find("#btn");
var $radios = $form.find(":radio");
var $checks = $form.find(":checkbox[name='optionals']");
$radios.add($checks).on("change", function() {
var radioVal = $radios.filter(":checked").val();
$btn.prop("disabled", true);
if (radioVal == 2) {
$btn.prop("disabled", !$checks.filter(":checked").length >= 1);
} else {
$btn.prop("disabled", !radioVal);
}
});
});
Here is a demo with the above + your HTML.
Note: Remove all the IDs except the form ID, button ID (since they're used in the demo) as you can't have duplicate IDs in an HTML document. an ID is meant to identify a unique piece of content. If the idea is to style those elements, then use classes.
If you foresee a lot of JavaScript development in your future, then I would highly recommend the JavaScript courses made available by Udacity. Although the full course content is only available for a fee, the most important part of the course materials--the videos and integrated questions--are free.
However, if you don't plan to do a lot of JavaScript development in the future and just need a quick solution so you can move on, here's how to accomplish what you are trying to accomplish:
$(document).ready(function(){
$('form').on('click', 'input[type="radio"]', function(){
conditionallyToggleButton();
});
$('form').on('click', 'input[type="checkbox"]', function(){
conditionallyToggleButton();
});
});
function conditionallyToggleButton()
{
if (shouldDisableButton())
{
disableButton();
}
else
{
enableButton();
}
}
function shouldDisableButton()
{
if ($('div#input-option1 input:checked').val() == 2
&& !$('form input[type="checkbox"]:checked').length)
{
return true;
}
return false;
}
function disableButton()
{
$('button').prop('disabled', true);
}
function enableButton()
{
$('button').prop('disabled', false);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div id="input-option1">First option: (required)
<input type="radio" name="required" id="required" value="1" checked="checked">Yes
<input type="radio" name="required" id="required" value="2">No
<div>
<div id="input-option2">Optionals:
<input type="checkbox" name="optionals" id="optionals" value="2a">Optional 1
<input type="checkbox" name="optionals" id="optionals" value="2b">Optional 2
<div>
<div id="input-option3">Extras:
<input type="checkbox" name="extra" id="extra" value="3">Extra 1
<div>
<button type="button" id="btn">Add to Cart</button>
</form>
Note that the JavaScript code above is a quick-and-dirty solution. To do it right, you would probably want to create a JavaScript class representing the add to cart form that manages the behavior of the form elements and which caches the jQuery-wrapped form elements in properties.

javascript if condition on checkbox functioning only once

I am fairly new to javascript programming and just can't seem to get this right even after going through the questions here, basically i have a checkbox which displays two radio buttons only when it is unselected
<span><strong>Not Available</strong></span>
<input type="checkbox" placeHolder="" id="available" style="" name="available" required value="Yes"/>
<span style=" visibility: hidden; " id="BACSSpan">BACS</span><input type="radio" id="BACS" name="paymentSpecified" value="BACS" style="visibility: hidden;">
<span style="visibility: hidden;" id="ChequeSpan">Cheque</span> <input type="radio" id="Cheque" name="paymentSpecified" value="Cheque" style=visibility: hidden;">
I have used the following javascript:
$('body').on('click', '#available', function ()
{
if ($('#available:checked'))
{
$('#BACSSpan').css('visibility','hidden');
$('#BACS').css('visibility','hidden');
$('#ChequeSpan').css('visibility','hidden');
$('#Cheque').css('visibility','hidden');
} else
{
$('#BACSSpan').css('visibility','visible');
$('#BACS').css('visibility','visible');
$('#ChequeSpan').css('visibility','visible');
$('#Cheque').css('visibility','visible');
}
})
What it should do is alternate between showing the two radio buttons, but it is not doing anything, but when i reverse the order of the condition i.e opposite of what i want; then the required functionality happens once only
The thing is that $('#available:checked') is a jQuery object - not a bool value. To get bool value you should do:
if ($(this).is(':checked')) {
...
}
else {
...
}
If you don't want to change your code a lot, you can simply add .length.
if ($('#available:checked').length) {
//Do Something
}

getting Id of the element

I am using jquery validation plugin. and designing the webpage using various elements (e.g,div ,li etc) .
There are tabs(tab1,tab2,tab3 ect) and through internal link these tabs contain several nos of fields(field1,,field2,....filed n).
Actually I want to mark the bg-color of the tab(e.g,tab2) as 'red' if there is any 'required' field missed .
For that I have tried the following code...
if(!(jQuery('#admissionForm').valid())) {
var n = $("label.error").parents("div.tab-body").index();
console.info(n);
var sel = "li.ui-state-default:nth-child(" + n + ")";
console.info(sel);
jQuery('label.error').each(function(n) {
$("label.error").parents("div#form-wizard").children("ul.ui-tabs-nav").children(sel).children("a").css("background-color","red");
});
}
The problems are
This code works for only one tab.
The .each() function takes the highest index.For example if there are error in all tabs then it marks only the 'tab3' tab not all the tabs.
So I want code which can mark the tabs. as respective error occurred as well doesn't mark the tabs which does contain any error.
Plz.. somebody help me out.
Thanx.. in advance...
This could be a little tricky to help you with. I'm not sure how familiar you are with the validate plugin.
You can't really do it the way you want it to, because you need to check all panels' inputs and see if they were valid or not.
The only way to differentiate that, without using the internal validation, is by using label.error:visible and label.error:hidden to see if they were valid or not. That is where your first problem lie. Since you have tabs, they are hidden even though they might be errored.
Which is why your example can only mark one tab or all tabs.
To solve this, you need to replace the current validation handler and unhighlight, so that you can do some highlighting and checking on your own.
I've arranged this JSFiddle that you can "fiddle" around with, hopefully the comments are enough to help you.
The idea is that at validation, you check which inputs were invalid, then get the parent panel and add an error class to the corresponding tab. When the user has corrected the error, or there is no error, the unhighlight will remove the error class from the tab.
And here's the code. Using JQuery, JQuery UI and JQuery validation plugin.
Javascript
$("#tabs").tabs();
$("#submitForm").button();
$("#validatetabs").validate({
submitHandler: function(form) {
alert("Done!");
},
invalidHandler: function(form, validator) {
//Check if there are any invalid fields
var errors = validator.numberOfInvalids();
if (errors) {
//Get all panels with errors
var errorpanels = $(validator.invalidElements()).closest(".ui-tabs-panel", form);
//Get ui tab sibling for every panel and add error
errorpanels.each(function(){
$(this).siblings(".ui-tabs-nav").children("li").addClass("ui-state-error");
});
}
},
unhighlight: function(element, errorClass, validClass) {
$(element).removeClass(errorClass);
//Get panel
var panel = $(element).closest(".ui-tabs-panel", element.form);
if (panel.size() > 0) {
//Check to see if there are any more errors on this panel
if (panel.find("." + errorClass + ":visible").size() == 0) {
//Find matching tab for this elements panel id
panel.siblings(".ui-tabs-nav")
.find("a[href='#" + panel[0].id + "']")
.parent().removeClass("ui-state-error");
}
}
}
});
HTML
<form id="validatetabs" method="get" action="">
<div id="tabs">
<ul>
<li>Tab1</li>
<li>Tab2</li>
<li>Tab3</li>
</ul>
<div id="tabs-1">
A required field: <input id="inp1" name="inp1" class="required" type="text"/>
<br/>
Another required field: <input id="inp1a" name="inp1a" class="required" type="text"/>
</div>
<div id="tabs-2">
A required field: <input id="inp2" name="inp2" class="required" type="text"/>
<br/>
Another required field: <input id="inp2a" name="inp2a" class="required" type="text"/>
</div>
<div id="tabs-3">
A required field: <input id="inp3" name="inp3" class="required" type="text"/>
<br/>
Another required field: <input id="inp3a" name="inp3a" class="required" type="text"/>
</div>
</div>
<p>
<input id="submitForm" class="submit" type="submit" value="Submit"/>
</p>
</form>
CSS
label, input{
display: block;
width: 100px;
}
label.error{
position: absolute;
background: white;
width: auto;
margin-left: 125px;
margin-top: -26px;
padding: 2px;
color: red;
font-style: italic;
}

Categories