I have a HTML that looks like:
I am trying to get current parent closest object value.
In this case I'm trying to get values of owner_address, owner_name.
<div class = "form-group row">
<div class="col-xs-6 form-group">
<input id="owner_name" type="text></input>
</div>
<div class="col-xs-6 form-group">
<input id="owner_address" type="text></input>
</div>
</div>
<div class="form-group row">
<div class="col-xs-6 form-group">
<input onclick="runFunction($(this))" id="update" type="text></input>
</div>
</div>
JS part where I try to get values.
<script>
function runFunction(thisObj){
var owner_name = thisObj.parent().closest('#owner_name').val()
#Gives me undefined.
}
</script>
I already tried selecting it using ID; it doesn't work in my case because the data are being rendered inside a modal; where each modals are unique. I want to get specific owner name inside my each unique modal; that is why I thought using $(this) would be convenient.
try this
var owner_name = thisObj.parent().parent().closest('.form-group').find('#owner_name).val()
try this demo: https://jsfiddle.net/xianshenglu/4nt42cso/4/
i change the js,if you use id selector you don't have to use other selectors.
function runFunction(thisObj){
var owner_name = $('#owner_name').val()
alert(owner_name);
}
also change your html,just correct the syntax error.for example,there should not be code like this:</input>,,,,
<div class="form-group row">
<div class="col-xs-6 form-group">
<input id="owner_name" type="text" />
</div>
<div class=" col-xs-6 form-group ">
<input id="owner_address " type="text" />
</div>
</div>
<div class="form-group row">
<div class="col-xs-6 form-group">
<input onclick="runFunction($(this))" id="update" type="text" />
</div>
</div>
Put this in your fucntion and check it return desired value or not.
thisObj.parent().parent().parent().find( "#owner_name" ).val();
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")
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.
I am using this code inside $(document).ready(function(){ ... }):
$('#flavours').on('click', '.toggle-quantity', function(e){
e.preventDefault();
var $quantity_percent = $(this).parent().find('.quantity_percent');
if($quantity_percent.is(':hidden')){
console.log("is hidden");
$quantity_percent.show();
}else{
console.log("is not hidden");
$quantity_percent.hide();
}
});
What's happening is the console.log() is working, but the $quantity_percent is not showing/hiding.
Additionally, if I add an alert('test') to the beginning of the function (just after e.preventDefault) this also doesn't work, but the console.log() continues to work (it correctly logs 'is not hidden').
EDIT: Relevant HTML markup:
<div id="flavours">
<div class="row flavour" id="flavour_1" style="display: block;">
<div class="form-group">
<div class="col-xs-12">
<fieldset>
<legend>Flavour 1</legend>
<div class="col-sm-4">
<label>Flavour Name</label>
<input type="text" value="" name="flavour_name[]" data-flavour-id="1" id="flavour_name_1" class="form-control autocomp" placeholder="Flavour name">
<input type="hidden" value="" name="flavour_id[]" id="flavour_id_1" class="form-control flavour_id">
<p class="flavour_info"></p>
</div>
<div class="col-sm-6">
<label>Flavour Quantity <span class="fa fa-filter"></span> <span class="hidden-sm">Switch to </span>drops per ml</label>
<div class="input-group" id="quantity_percent">
<input type="text" class="form-control" id="flavour_percentage_1" name="flavour_percentage[]" placeholder="Flavour Quantity">
<span class="input-group-addon">%</span>
</div>
<div class="input-group" id="quantity_drops" style="display: none;">
<input type="text" class="form-control" id="flavour_drops_1" name="flavour_drops[]" placeholder="Flavour Quantity">
<span class="input-group-addon">drops/ml</span>
</div>
<p class="flavour_recommended_percentage"></p>
</div>
<div class="col-sm-2">
<label> </label>
<button class="btn btn-danger btn-block remove-flavour"><span class="glyphicon glyphicon-remove"></span> Remove</button>
</div>
</fieldset>
</div>
</div>
</div>
$(this).parent() is a label element which doesn't have a child with .quantity_percent
Also quantity_percent is an id and not a class. Use the ID selector
So use
var $quantity_percent = $('#quantity_percent');
instead of
var $quantity_percent = $(this).parent().find('.quantity_percent');
Note: IDs must be unique in HTML
EDIT: as per OPs comments
I updated it to a class rather than ID (as it's on a dynamically growing list)
Usage
var $quantity_percent = $(this).closest('.col-sm-6').find('.quantity_percent');
The .parent() targets the <label> therefore it can't find .quantity_percent
I have the following pattern of div id's defined in my code. Please take a look at it:
<div id="wideWrapper">
<div id="divContentFrame">
<div class="ContentContainer">
<cfform id="someid" action="" method="post">
<input class="noDisplay" name="token" id="sCsrfToken" value="" type="hidden">
<div id="messageInfoWrap">
<div class="messageInfo">
<div class="messageInfoFields ">
<div class="field required">
<label for="subject">From Address:<span class="indicator">*</span></label>
<input name="inpKey" id="inpKey" value="" type="text">
</div>
and so on....
</div> // for messageInfoWrap
<div class="messageInfoFields referenceName">
<div class="field required">
<label for="refname">Function Name:</label>
<input name="sRefName" id="inputDescription" type="text">
<span class="border"></span>
<span class="arrow right"></span>
</div>
</div>
In jquery function call, I am trying to access the content of From Address field in the following manner:
$("#divContentFrame #inppKey").val(d.DATA.CURRinpkey[0]);
But it's not picking up the content. Am I doing something wrong here?
Because the same thing when I am doing for another form field like:
$("#divContentFrame #inputDescription").val() it's working fine.
$("#divContentFrame #inpKey").val();
not
$("#divContentFrame #inpKey").val;
I haven't found any issue other than the missing closing tag for input.
Here your code just works fine.
<div id="wideWrapper">
<div id="divContentFrame">
<div class="ContentContainer">
<div id="messageInfoWrap">
<div class="messageInfo">
<div class="messageInfoFields ">
<div class="field required">
<input name="inpKey" id="inpKey" value="" type="text"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
$("#divContentFrame #inpKey").val('test');
And isn't d.DATA.CURRinpkey[0] an object?!
The use of two selectors here is unecessary and adds unecessary overhead. You also misspelled inpKey as inppKey. Use
$("#inpKey").val()
instead.