Set focus to the next input element - javascript

I have a bootstrap form where I want to set the focus to the next 'enabled' input element upon pressing enter key. When I press enter in Barcode input element, I want to set the focus to the Quantity input element since it is the next enabled input element.
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-3 pr-0">
<div class="form-group">
<label for="txtBarcode">Barcode</label>
<input type="text" id="txtBarcode" name="barcode" class="form-control form-control-sm">
</div>
</div>
<div class="col-7 pl-2 pr-0">
<div class="form-group">
<label for="txtPartDesc">Description</label>
<input type="text" id="txtPartDesc" name="part_desc" value="" class="form-control form-control-sm" disabled>
</div>
</div>
<div class="col-2 pl-2">
<div class="form-group">
<label for="txtUom">UoM</label>
<input type="text" id="txtUom" name="barcode" value="" class="form-control form-control-sm" disabled>
</div>
</div>
</div>
<div class="row">
<div class="col-4 pr-0">
<div class="form-group">
<label for="txtQuantity">Quantity</label>
<input type="text" id="txtQuantity" name="barcode" class="form-control form-control-sm">
</div>
</div>
</div>
What I have tried so far is:
$(":input").keydown(function(event){
if (event.keyCode === 13) {
$(this).nextAll(':input:enabled').first().focus();
}
});
But this doesn't work as I expect.

next(), nextAll(), and the other similar methods are for finding siblings. Since none of your inputs are actual siblings this will not work.
What you can do however is:
Get a jQuery object of all the enabled inputs
var enabledInputs = $("input:enabled");
Get the index of the current input in that jQuery object using index()
var idx = enabledInputs.index(this);
Then using that index get the element at index+1 using eq()
enabledInputs.eq(idx+1).focus();
Demo
$(":input").keydown(function(event){
if (event.keyCode === 13) {
var enabledInputs = $("input:enabled");
var idx = enabledInputs.index(this);
enabledInputs.eq(idx+1).focus()
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-3 pr-0">
<div class="form-group">
<label for="txtBarcode">Barcode</label>
<input type="text" id="txtBarcode" name="barcode" class="form-control form-control-sm">
</div>
</div>
<div class="col-7 pl-2 pr-0">
<div class="form-group">
<label for="txtPartDesc">Description</label>
<input type="text" id="txtPartDesc" name="part_desc" value="" class="form-control form-control-sm" disabled>
</div>
</div>
<div class="col-2 pl-2">
<div class="form-group">
<label for="txtUom">UoM</label>
<input type="text" id="txtUom" name="barcode" value="" class="form-control form-control-sm" disabled>
</div>
</div>
</div>
<div class="row">
<div class="col-4 pr-0">
<div class="form-group">
<label for="txtQuantity">Quantity</label>
<input type="text" id="txtQuantity" name="barcode" class="form-control form-control-sm">
</div>
</div>
</div>

The next input is not a sibling of the #barcode input, so nextAll won't work at that point. Try navigating to the parent's parent, the div class="col-, and then use nextAll to recursively search through that parent's siblings until a matching element is found:
$(":input").keydown(function(event) {
if (event.keyCode !== 13) return;
$(this)
.parent()
.parent() // get to the `class=col-#` element
.nextAll(':input:enabled')
.first()
.focus();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<div class="row">
<div class="col-3 pr-0">
<div class="form-group">
<label for="txtBarcode">Barcode</label>
<input type="text" id="txtBarcode" name="barcode" class="form-control form-control-sm">
</div>
</div>
<div class="col-7 pl-2 pr-0">
<div class="form-group">
<label for="txtPartDesc">Description</label>
<input type="text" id="txtPartDesc" name="part_desc" value="" class="form-control form-control-sm" disabled>
</div>
</div>
<div class="col-2 pl-2">
<div class="form-group">
<label for="txtUom">UoM</label>
<input type="text" id="txtUom" name="barcode" value="" class="form-control form-control-sm" disabled>
</div>
</div>
</div>
<div class="row">
<div class="col-4 pr-0">
<div class="form-group">
<label for="txtQuantity">Quantity</label>
<input type="text" id="txtQuantity" name="barcode" class="form-control form-control-sm">
</div>
</div>
</div>

If I understand your question correctly then one solution to this problem is to update your keydown() handler like so:
if (event.keyCode === 13) {
// Get all enabled inputs in the document
var inputs = $('input:enabled');
// Iterate all inputs, searching for the index of the "next" input to "this"
for(var i = 0; i < inputs.length; i++) {
// If the "global" index of "this" input is found
if( $(inputs).eq(i).is( $(this) ) ) {
// Then select the "next" input by incrementing the index, and call
// focus on that input if it exists
inputs.eq(i + 1)
.css({ border : '1px solid red' }) // Added to help visualise focus, remove this line
.focus();
// Exit the loop now that focus has been called on "next" input
break
}
}
}
The idea here is to select the next input element based on the order that they occur in the DOM, rather than to select the next input element based on adjacent siblings to the input that "enter" is pressed. This solution also corrects a few minor errors in your code's selector syntax. Here's a working demo:
$("input").keydown(function(event){
if (event.keyCode === 13) {
var inputs = $('input:enabled');
for(var i = 0; i < inputs.length; i++) {
if( $(inputs).eq(i).is( $(this) ) ) {
inputs.eq(i + 1)
.css({ border : '1px solid red' }) // Added to help visualise focus, remove this line
.focus()
break
}
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-3 pr-0">
<div class="form-group">
<label for="txtBarcode">Barcode</label>
<input type="text" id="txtBarcode" name="barcode" class="form-control form-control-sm">
</div>
</div>
<div class="col-7 pl-2 pr-0">
<div class="form-group">
<label for="txtPartDesc">Description</label>
<input type="text" id="txtPartDesc" name="part_desc" value="" class="form-control form-control-sm" disabled>
</div>
</div>
<div class="col-2 pl-2">
<div class="form-group">
<label for="txtUom">UoM</label>
<input type="text" id="txtUom" name="barcode" value="" class="form-control form-control-sm" disabled>
</div>
</div>
</div>
<div class="row">
<div class="col-4 pr-0">
<div class="form-group">
<label for="txtQuantity">Quantity</label>
<input type="text" id="txtQuantity" name="barcode" class="form-control form-control-sm">
</div>
</div>
</div>

Related

How to set empty or null value doesn't worked in Jquery change

I want the value in the input text to be null after the hide process
This is my view :
<div class="form-group row">
<label for="status" class="col-sm-4 col-form-label col-form-label-sm">Status Karyawan</label>
<div class="col-sm-8">
<select id="status" name="status" class="form-control form-control-sm" required>
<option value="" selected>Pilih Status Karyawan</option>
<option value="Kontrak">Kontrak</option>
<option value="Tetap">Tetap</option>
</select>
</div>
</div>
<div class="form-group row" id="tgl_pengangkatan" style="display:none">
<label for="tgl_pengangkatan" class="col-sm-4 col-form-label col-form-label-sm">Tgl. Pengangkatan</label>
<div class="col-sm-8 input-group">
<input name="tgl_pengangkatan" type="text" class="form-control datepicker form-control-sm" id="tgl_pengangkatan" placeholder="yyyy-mm-dd" value="">
</div>
</div>
<div class="form-group row" id="tgl_berakhir_kontrak" style="display:none">
<label for="tgl_berakhir_kontrak" class="col-sm-4 col-form-label col-form-label-sm">Tgl. Akhir Kontrak</label>
<div class="col-sm-8 input-group">
<input name="tgl_berakhir_kontrak" type="text" class="form-control datepicker form-control-sm" id="tgl_berakhir_kontrak" placeholder="yyyy-mm-dd" value="">
</div>
</div>
And than, this is my script:
<script>
$(function () {
$("#status").change(function() {
var val = $(this).val();
if(val === "Kontrak") {
$("#tgl_berakhir_kontrak").show();
$("#tgl_pengangkatan").hide();
$("#tgl_pengangkatan").val('');
}
else if (val === "Tetap") {
$("#tgl_pengangkatan").show();
$("#tgl_berakhir_kontrak").hide();
$("#tgl_berakhir_kontrak").val('');
}
});
});
I want to make it like that to minimize errors in the input process, thanks.
The element you are trying to change should be called with its name, not the id. Try changing it as:
$('[name="tgl_berakhir_kontrak"]').val('');
By the way, it's not a good practice to give identical name and id to separate elements on the same page.

JQuery: input change -> find parent -> find next input -> value returns undefined

I am trying to get the next closest input of same class or different class that is available in the next row div child it says undefined am unable to get it.
[Fiddle]
$(".std_amt").change(function() {
alert($(this).parent('.row').next(".row").children("input.std_amt").val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-lg-3">
<div class="form-group ">
<input class="form-control std_amt" type="text" name="relative_name_0" id="relative_name_0" value="">
<label class="help-inline"></label>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="form-group ">
<input class="form-control std_amt" type="text" name="relative_name_1" id="relative_name_1" value="">
<label class="help-inline"></label>
</div>
</div>
</div>
Try to use closest instead of parent like below
$(".std_amt").change(function() {
alert($(this).closest('.row').next(".row").find("input.std_amt").val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-lg-3">
<div class="form-group ">
<input class="form-control std_amt" type="text" name="relative_name_0" id="relative_name_0" value="">
<label class="help-inline"></label>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="form-group ">
<input class="form-control std_amt" type="text" name="relative_name_1" id="relative_name_1" value="">
<label class="help-inline"></label>
</div>
</div>
</div>
.parent('.row') looks at the direct parent, it does NOT climb the tree. You need to use closest('.row') to reference the row. And you should use find() and not children() since the input is not a direct child.
$(this).closest('.row').next(".row").find("input.std_amt")

Add div tag to existing rendered html

I have div with multiple tags in it. I want to add the with so i can convert my existing to bootstrap grid view. Here is my html as below:
<div class="render-wrap" id="fb-render-wrap">
<div class="fb-text form-group customdiv col-md-12 field-text-1505825076921">
<label for="text-1505825076921" class="fb-text-label">Name<span class="fb-required">*</span></label>
<input type="text" name="text-1505825076921" id="text-1505825076921" required="required" aria-required="true" data-msg="Name is requird.">
</div>
<div class="fb-date form-group customdiv col-md-12 field-date-1505825086301">
<label for="date-1505825086301" class="fb-date-label">From Date<span class="fb-required">*</span></label>
<input type="date" name="date-1505825086301" id="date-1505825086301" required="required" aria-required="true" data-msg="From Date is requird.">
</div>
</div>
And I want the output as below:
<div class="render-wrap" id="fb-render-wrap">
<div class="fb-text form-group customdiv col-md-12 field-text-1505825076921">
<div class="col-md-3">
<label for="text-1505825076921" class="fb-text-label">Name<span class="fb-required">*</span></label>
</div>
<div class="col-md-5">
<input type="text" name="text-1505825076921" id="text-1505825076921" required="required" aria-required="true" data-msg="Name is requird.">
</div>
</div>
<div class="fb-date form-group customdiv col-md-12 field-date-1505825086301">
<div class="col-md-3">
<label for="date-1505825086301" class="fb-date-label">From Date<span class="fb-required">*</span></label>
</div>
<div class="col-md-3">
<input type="date" name="date-1505825086301" id="date-1505825086301" required="required" aria-required="true" data-msg="From Date is requird.">
</div>
</div>
</div>
I have tried to iterate through div using customdiv css but don't know how to append the div.
$('.customdiv').children().each(function () {
if ($(this).prop("tagName").toLowerCase() == "label") {
$(this).prepend('<div class="col-md-3">');
$(this).append("</div>");
} else {
$(this).prepend('<div class="col-md-5">');
$(this).append("</div>");
}
});
Somebody help me out to achieve this in best way.
Create a div and append the child and then add the new element into the parent, so that you can achieve your result html
$(document).ready(function() {
$(".form-group").each(function(i, obj) {
var tt = $('<div class="col-md-3"></div>');
$(tt).append($(obj).find("label"));
$(obj).append(tt);
var tt = $('<div class="col-md-5"></div>');
$(tt).append($(obj).find("input, select, textarea"));
$(obj).append(tt);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="render-wrap" id="fb-render-wrap">
<div class="fb-text form-group customdiv col-md-12 field-text-1505825076921">
<label for="text-1505825076921" class="fb-text-label">Name<span class="fb-required">*</span></label>
<input type="text" name="text-1505825076921" id="text-1505825076921" required="required" aria-required="true" data-msg="Name is requird.">
</div>
<div class="fb-date form-group customdiv col-md-12 field-date-1505825086301">
<label for="date-1505825086301" class="fb-date-label">From Date<span class="fb-required">*</span></label>
<input type="date" name="date-1505825086301" id="date-1505825086301" required="required" aria-required="true" data-msg="From Date is requird.">
</div>
</div>
Have a look:
$('.customdiv').children().each(function () {
if ($(this).is('label')) {
$(this).wrap('<div class="col-md-3"></div>');
} else {
$(this).wrap('<div class="col-md-5"></div>');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="render-wrap" id="fb-render-wrap">
<div class="fb-text form-group customdiv col-md-12 field-text-1505825076921">
<label for="text-1505825076921" class="fb-text-label">Name<span class="fb-required">*</span></label>
<input type="text" name="text-1505825076921" id="text-1505825076921" required="required" aria-required="true" data-msg="Name is requird.">
</div>
<div class="fb-date form-group customdiv col-md-12 field-date-1505825086301">
<label for="date-1505825086301" class="fb-date-label">From Date<span class="fb-required">*</span></label>
<input type="date" name="date-1505825086301" id="date-1505825086301" required="required" aria-required="true" data-msg="From Date is requird.">
</div>
</div>

Second Time Checkbox Not Working

I have created a two javascript.
1.When i click the checkbox the input field is appeared and when i unchecked input field is disappeared.
2.Second is when i click the add more items the all fields are created one more time.
Now the problem is when is created a second and more items the checkbox is not working.
HTML Code:
<div class="container">
<div class="row">
<div class="col-lg-12 col-md-12">
<div data-role="dynamic-fields">
<div class="form-inline">
<div class="row">
<div class="col-md-3">
<div class="form-group">
<input type="text" class="form-control" id="Name1" placeholder="Food Name" name="Name1" style="width:120%;" required data-rule-minlength="2">
<label class="sr-only" for="field-name">Name</label>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<input type="text" class="form-control" id="field-value" placeholder="Description" style="width:120%;" required>
<label class="sr-only" for="field-value">Description</label>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<select id="select1" name="select1" style="width:130%;" class="form-control" required>
<option value=""></option>
<option value="1">Food Type 1</option>
<option value="2">Food Type 2</option>
<select>
<label for="select1">Food Type</label>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<input type="text" value="" class="form-control" data-role="tagsinput" placeholder="Tags" />
<label class="sr-only" for="field-tags">Tags</label>
</div>
</div>
</div>
<div class="row">
<div class="form-inline">
<div class="col-md-3">
<div class="form-group">
<input type="text" class="form-control" id="Name1" placeholder="Price" name="price" style="width:120%;" required data-rule-minlength="2">
<label class="sr-only" for="field-name">Price</label>
</div>
</div>
<div class="col-md-2">
<div class="checkbox checkbox-styled">
<label><em>Half Plate Price</em>
<input type="checkbox" value="" id="trigger2" name="question"> </label>
</div>
</div>
<div class="col-md-1">
<div id="hidden_fields2">
<input type="text" id="hidden_field2" name="hidden" placeholder="Price" class="form-control" style="width:140%;margin-left:-35px;height: 29px;margin-top: 24px;font-weight: 380;font-size: 16px;line-height: 1.5;"> </div>
</div>
<div class="col-md-3">
<div class="checkbox checkbox-styled">
<label><em>Quarter Plate Price</em>
<input type="checkbox" value="" id="trigger" name="question"> </label>
</div>
</div>
<div class="col-md-1">
<div id="hidden_fields">
<input type="text" id="hidden_field" name="hidden" placeholder="Price" class="form-control" style="width:140%;margin-left:-100px;height: 29px;margin-top: 24px;font-weight: 380;font-size: 16px;line-height: 1.5;"> </div>
</div>
</div>
</div>
<button class="btn btn-icon-toggle btn-delete" data-toggle="tooltip" data-placement="bottom" title="Delete Field" data-role="remove"> <span class="md md-delete"></span> </button>
<button class="btn btn-primary" data-toggle="tooltip" data-placement="bottom" title="Add More Field" data-role="add"> Add More Items </button>
</div>
<!-- /div.form-inline -->
</div>
<!-- /div[data-role="dynamic-fields"] -->
</div>
<!-- /div.col-md-12 -->
</div>
<div class="form-group">
<button type="button" name="submit" href="#" class="btn ink-reaction btn-raised btn-primary">Submit Items</button>
</div>
<!--end .form-group -->
</div>
Checkbox Js:
<script type="text/javascript">
$(function() {
// Get the form fields and hidden div
var checkbox = $("#trigger");
var hidden = $("#hidden_fields");
hidden.hide();
checkbox.change(function() {
if (checkbox.is(':checked')) {
// Show the hidden fields.
hidden.show();
} else {
// Make sure that the hidden fields are indeed
// hidden.
hidden.hide();
$("#hidden_field").val("");
}
});
});
$(function() {
var checkbox = $("#trigger2");
var hidden = $("#hidden_fields2");
hidden.hide();
checkbox.change(function() {
if (checkbox.is(':checked')) {
// Show the hidden fields.
hidden.show();
} else {
hidden.hide();
$("#hidden_field2").val("");
}
});
});
</script>
Add more items JS:
$(function() {
// Remove button
$(document).on('click', '[data-role="dynamic-fields"] > .form-inline [data-role="remove"]', function(e) {
e.preventDefault();
$(this).closest('.form-inline').remove();
});
// Add button
$(document).on('click', '[data-role="dynamic-fields"] > .form-inline [data-role="add"]', function(e) {
e.preventDefault();
var container = $(this).closest('[data-role="dynamic-fields"]');
new_field_group = container.children().filter('.form-inline:first-child').clone();
new_field_group.find('input').each(function() {
$(this).val('');
});
container.append(new_field_group);
});
});
page Screenshot:
There are a couple of problems here:
You are cloning elements and then trying to access them via the same ID (you should use class)
Your functions don't target just clicked element but any element with the selector.
You are cloning elements so you need bind the click event to a non-cloned element: e.g. via $(document).on
I've updated some of your code to demonstrate what I'm talking about. In the html, I've added classes in the trigger2 and hidden_fields2 elements and display:none style to the hidden fields so they are hidden by default.:
<div class="col-md-2">
<div class="checkbox checkbox-styled">
<label><em>Half Plate Price</em>
<input type="checkbox" value="" class="trigger2" id="trigger2" name="question"> </label>
</div>
</div>
<div class="col-md-1">
<div id="hidden_fields2" class="hidden_fields2" style="display:none;">
<input type="text" id="hidden_field2" name="hidden" placeholder="Price" class="form-control" style="width:140%;margin-left:-35px;height: 29px;margin-top: 24px;font-weight: 380;font-size: 16px;line-height: 1.5;"> </div>
</div>
In the javascript, I've changed the function to run from a $(document).on event bind and used the element class instead of the id. I've also changed the code so it only effects the checkbox you change and the closest hidden elements:
$(function() {
$(document).on('change', '.trigger2', function(){
var checkbox = $(this);
var parent = checkbox.closest('.form-inline');
var hidden = parent.find(".hidden_fields2");
hidden.hide();
if (checkbox.is(':checked')) {
// Show the hidden fields.
hidden.show();
} else {
hidden.hide();
$(".hidden_field2").val("");
}
});
});
You need to use the same logic on your other functions and inputs.

JQuery checked event working only once

The problem I am having is that my JQuery checked event only seems to be working once. My aim is for textboxes to be enabled when the corresponding checkbox is checked. Here is a cut down version of the HTML:
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="forenameCheck" name="forenameCheck" onchange="valueChanged()">
<label for="forename" class="control-label">Forename</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="forename" disabled name="forename" placeholder="Forename">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="surnameCheck" name="surnameCheck" onchange="valueChanged()">
<label for="surname" class="control-label">Surname</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="surname" disabled name="surname" placeholder="Surname">
</div>
</div>
</div>
and this is the JQuery:
function valueChanged()
{
if($("#forenameCheck").is(":checked")){
$("#forename").prop("disabled",false);
}
else{
$("#forename").prop("disabled",true);
}
if($("#surnameCheck").is(":checked")){
$("#surname").prop("disabled",false);
}
else{
$("#surname").prop("disabled",true);
}
}
I am very new to JQuery and have no idea why this isn't working. "Forename" works fine but "Surname" does not. This is the JSFiddle of the code. What's strange is that it does not work at all on JSFiddle. It's also worth noting that i'm using bootstrap with this too.
If anyone can help it would be much appreciated!
I would handle each element separately.
$("#forenameCheck").change(function() {
var isDisabled = !$(this).is(":checked");
$("#forename").prop("disabled", isDisabled);
});
It would be better to handle each element separately in your case. Here is the code:
$("#forenameCheck").change(function() {
var isDisabled = !$(this).is(":checked");
$("#forename").prop("disabled", isDisabled);
});
$("#surnameCheck").change(function() {
var isDisabled = !$(this).is(":checked");
$("#surname").prop("disabled", isDisabled);
});
Here is an updated JSFiddle
Update
I just tried the following code (not in JSFiddle, just in a plain html file) and it works.
<script type='text/javascript' src='http://code.jquery.com/jquery-compat-git.js'></script>
<script>
function valueChanged()
{
if($("#forenameCheck").is(":checked")){
$("#forename").prop("disabled",false);
}
else{
$("#forename").prop("disabled",true);
}
if($("#surnameCheck").is(":checked")){
$("#surname").prop("disabled",false);
}
else{
$("#surname").prop("disabled",true);
}
}
</script>
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="forenameCheck" name="forenameCheck" onchange="valueChanged()">
<label for="forename" class="control-label">Forename</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="forename" disabled name="forename" placeholder="Forename">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="surnameCheck" name="surnameCheck" onchange="valueChanged()">
<label for="surname" class="control-label">Surname</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="surname" disabled name="surname" placeholder="Surname">
</div>
</div>
</div>
It seems it is not working in JSFiddle because of how the code is loaded in it. It is giving the following JavaScript error:
Uncaught ReferenceError: valueChanged is not defined
If you view the source of the JSFiddle output you will see that the JavaScript code is wrapped in window.onload=function(){ and this might be causing issues.
Your code is far too complicated. Replace onchange="valueChanged()" with onchange="valueChanged(this)" and use this javascript:
function valueChanged(button) {
button.parentNode.nextElementSibling.childNodes[1].disabled=!button.checked;
}
Result:
function valueChanged(button) {
button.parentNode.nextElementSibling.childNodes[1].disabled=!button.checked;
}
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="forenameCheck" name="forenameCheck" onchange="valueChanged(this)">
<label for="forename" class="control-label">Forename</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="forename" disabled name="forename" placeholder="Forename">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="surnameCheck" name="surnameCheck" onchange="valueChanged(this)">
<label for="surname" class="control-label">Surname</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="surname" disabled name="surname" placeholder="Surname">
</div>
</div>
While we're unable to answer the question of "why isn't my code working," since the code in your question is apparently dissimilar to the code you attempted to type1, I'd like to offer a simple plain JavaScript alternative to the posted solutions.
This approach binds the event-handler using JavaScript itself, in order for easier future maintenance (since it prevents having to search the HTML to update the function calls) and applies the same function to each of the check-boxes. This approach allows for the same function to handle the change event of each check-box, rather than individually binding a change event-handler to every check-box element on the page, which is unnecessarily repetitive (and rapidly inflates the document size).
This is dependant upon the relationship of the check-box ids and their associated <input /> elements' id (though an alternative, below, is posted which uses the structure of the HTML):
// re-naming the function according what it does, this is
// entirely personal, so change, or revert, according to taste:
function changeToggle() {
// the changed check-box ('this' is passed in
// via the use of addEventListener(), later:
var checkbox = this,
// replacing the 'Check' from the element's id
// with an empty string (to get the id of the
// associated <input />:
id = checkbox.id.replace('Check', ''),
// retrieving the associated <input />:
input = document.getElementById(id);
// updating the disabled property of the <input />,
// to be the opposite of the checked state of
// the check-box:
input.disabled = !checkbox.checked;
}
// retrieving all <input /> elements that are descendants of
// an element with the class of 'row':
var checkboxes = document.querySelectorAll('.row input[type=checkbox]');
// using Array.prototype.forEach, and Function.prototype.call,
// to iterate over the NodeList returned by querySelectorAll():
Array.prototype.forEach.call(checkboxes, function(check) {
// check is the array-element of the array we're currently
// iterating, in this case the check-box nodes; here we're
// binding a change event-handler, naming the function
// created earlier:
check.addEventListener('change', changeToggle);
});
function changeToggle() {
var checkbox = this,
id = checkbox.id.replace('Check', ''),
input = document.getElementById(id);
input.disabled = !checkbox.checked;
}
var checkboxes = document.querySelectorAll('.row input[type=checkbox]');
Array.prototype.forEach.call(checkboxes, function(check) {
check.addEventListener('change', changeToggle);
});
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="forenameCheck" name="forenameCheck" />
<label for="forename" class="control-label">Forename</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="forename" disabled name="forename" placeholder="Forename" />
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="surnameCheck" name="surnameCheck" />
<label for="surname" class="control-label">Surname</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="surname" disabled name="surname" placeholder="Surname" />
</div>
</div>
</div>
To use the HTML structure, particularly that the <label> for the associated <input /> is the next element-sibling to the check-box:
function changeToggle() {
var checkbox = this,
// retrieving the nextElementSibling (the first
// element that follows as a sibling, rather than
// nextSibling, which includes comment, and text,
// nodes):
label = checkbox.nextElementSibling,
// accessing the HTMLLabelElement's htmlFor
// property, to retrieve the string from its
// 'for' attribute (getAttribute('for') would
// also work):
id = label.htmlFor,
input = document.getElementById(id);
// as above:
input.disabled = !checkbox.checked;
}
function changeToggle() {
var checkbox = this,
label = checkbox.nextElementSibling,
id = label.htmlFor,
input = document.getElementById(id);
input.disabled = !checkbox.checked;
}
var checkboxes = document.querySelectorAll('.row input[type=checkbox]');
Array.prototype.forEach.call(checkboxes, function(check) {
check.addEventListener('change', changeToggle);
});
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="forenameCheck" name="forenameCheck" />
<label for="forename" class="control-label">Forename</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="forename" disabled name="forename" placeholder="Forename" />
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-lg-3 col-md-3 col-xs-3">
<input type="checkbox" class="" id="surnameCheck" name="surnameCheck" />
<label for="surname" class="control-label">Surname</label>
</div>
<div class="col-lg-7 col-md-7 col-xs-7">
<input type="text" class="form-control" id="surname" disabled name="surname" placeholder="Surname" />
</div>
</div>
</div>
References:
Array.prototype.forEach().
document.querySelectorAll().
EventTarget.addEventListener().
Function.prototype.call().
HTMLLabelElement.
Node.nextElementSibling.
Footnotes:
Your comment, below the question, addressing Pointy:
#Pointy Thank you for pointing that out. I didn't see that there. The text editor must have automatically put them there as I was typing.
Source.

Categories

Resources