I have next code:
<tr>
<td>
<select class="select_big" name="additional_field" id="<?=$field['id'];?>" required>
<option value="0">Выберите значение</option>
...
</td>
</tr>
<tr>
<td>
<select class="select_big" name="additional_field" id="<?=$field['id'];?>" required>
<option value="0">Выберите значение</option>
...
</td>
</tr>
<tr>
<td>
<select class="select_big" name="additional_field" id="<?=$field['id'];?>" required>
<option value="0">Выберите значение</option>
...
</td>
</tr>
<tr>
<td>
<select class="select_big" name="additional_field" id="<?=$field['id'];?>" required>
<option value="0">Выберите значение</option>
...
</td>
</tr>
When I select the second "select" element, I need to disable all the next one.
If I select 1 need to disable 3 and 4, if I select 2 I need to disable only 4.
Count of element could be different.
How I can get all elements next the select?
I try next:
<script type="text/javascript">
$("[name=additional_field]").change(function(e) {
field_data = '#' this.id.replace(/[* .]/g, "\\$&");
$(field_data).parent().parent().nextAll().each(function(i) {
console.log($(this)('[name=additional_field]'));
});
});
</script>
But I receive next error:
Uncaught TypeError: object is not a function
Help me please.
I think you can do it simpler without confusing traversal of the parent nodes:
var $sel = $('.select_big').change(function() {
$sel.filter(':gt(' + $sel.index(this) + ')').prop('disabled', +$(this).val());
});
Demo: http://jsfiddle.net/VFcF9/
It will also reenable selectboxes if you select default option back.
The error you were getting is because of this line:
$(this)('[name=additional_field]')
The first part, $(this), returns a jQuery object, and that object is not a function so you can't follow it with more parentheses.
As for your requirement to disable all of the following select elements, perhaps:
$("[name=additional_field]").change(function(e) {
$(this).closest("tr").nextAll("tr").find("[name=additional_field]").prop("disabled", true);
});
This should do it
$("[name=additional_field]").change(function(e) {
var f = $(this).closest('tr') //find the closest parent tr
.nextAll('tr') //find all tr that follows
.find('select.select_big') //from them, get all select
//f should be all the selects the follow what changed
});
Related
I'm using jQuery 1.12.4 to set get the value of the closest preceding element using class selector. I'm unable to select the closest element.
$(function() {
$("[class='quickSelect']").blur(function() {
var obj = $(this);
alert($(this).parent());
// alert($(this).closest("[class~='endDateField']"));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td align="right">
Start Date
</td>
<td>
<input type="text" name="debitStartDate" value="" class="dateField startDateField">
</td>
<td align="right">
End Date
</td>
<td>
<input type="text" name="debitEndDate" value="" class="dateField endDateField">
</td>
<td class="debitApportioner" style="align:right">
Quick Select
</td>
<td class="debitApportioner" colspan="2">
<select class="quickSelect">
<option> SELECT </option>
<option> JANUARY </option>
<option> FEBRUARY </option>
<option> MARCH </option>
</select>
<input class="quickSelect" type="text" />
</td>
</tr>
</table>
Try this:
$(".quickSelect").blur(function() {
var obj = $(this);
obj.closest('tr').find('.endDateField'); // will find the endDateField in the current row
});
closest() only traverses up the trees ancestors and stops at the first element that matches the selector so the above says find the closest ancestor tr to the input then find any endDateField inside that tr
I need a way to retrieve elements of a given element which are not children of certain other elements. To distinguish between these "parent" elements I've been using a data attribute.
This is an example of my following HTML stucture:
<form method="post" data-component-id="3">
<table border="0">
<thead>
<tr>
<th></th>
<th>First Name</th>
<th>Last Name</th>
<th>Date of Birth (dd/mm/yyyy)</th>
<th>Sex</th>
</tr>
</thead>
<tbody>
<tr data-component-id="8">
<td>Spouse</td>
<td><input name="txtFirstName_1" type="text" maxlength="255" id="txtFirstName_1" data-mapping-id="Person.Firstname"></td>
<td><input name="txtLastName_1" type="text" maxlength="255" id="txtLastName_1" data-mapping-id="Person.Lastname"></td>
<td><input name="txtDOB_1" type="text" maxlength="10" id="txtDOB_1" data-mapping-id="Person.Birthday"></td>
<td>
<select name="ddlSex_1" id="ddlSex_1" data-mapping-id="Person.Sex">
<option value=""></option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</td>
</tr>
<tr data-component-id="9">
<td>Child</td>
<td><input name="txtFirstName_2" type="text" maxlength="255" id="txtFirstName_2" data-mapping-id="Person.Firstname"></td>
<td><input name="txtLastName_2" type="text" maxlength="255" id="txtLastName_2" data-mapping-id="Person.Lastname"></td>
<td><input name="txtDOB_2" type="text" maxlength="10" id="txtDOB_2" data-mapping-id="Person.Birthday"></td>
<td>
<select name="ddlSex_2" id="ddlSex_2" data-mapping-id="Person.Sex">
<option value=""></option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</td>
</tr>
<tr data-component-id="9">
<td>Child</td>
<td><input name="txtFirstName_3" type="text" maxlength="255" id="txtFirstName_3" data-mapping-id="Person.Firstname"></td>
<td><input name="txtLastName_3" type="text" maxlength="255" id="txtLastName_3" data-mapping-id="Person.Lastname"></td>
<td><input name="txtDOB_3" type="text" maxlength="10" id="txtDOB_3" data-mapping-id="Person.Birthday"></td>
<td>
<select name="ddlSex_3" id="ddlSex_3" data-mapping-id="Person.Sex">
<option value=""></option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</td>
</tr>
</tbody>
</table>
<input type="button" name="submit" value="SUBMIT">
Note: The reason there are two data-component-id="9" attributes is because I treat this attribute as a type for mapping purposes in my back-end. (8 = Spouse data, 9 = Child data)
I created a JavaScript function which accepts one element and recursively builds a Component object, holding an ID, an array of its fields, and sub-components (recursive).
// Component Object
function Component(componentID, fields, subComponents) {
this.ComponentID = componentID; // Numeric
this.Fields = fields; // Array
this.Components = subComponents; // Array
}
// Recursively build component (and sub-components)
$.fn.formDataToComponent = function() {
var componentID = $(this).attr("data-component-id");
var componentName = "";
var fields=[];
var subComponents=[];
var subComponentsIndex=0;
// Recursively create the sub components
$(this).find("[data-component-id]").each(function(oSubComponent){
subComponents[subComponentsIndex] = $(oSubComponent).formDataToComponent();
subComponentsIndex++;
});
$(this).find('[data-mapping-id]').each(function() {
// $(this).find('[data-mapping-id]') will retrieve all elements with the data attribute (therefore 12 elements will be selected)
// With the list of these elements, I want to select ONLY those which are closest to the parent element with the attribute "data-component-id".
// Therefore in this particular scenario I only want to select the 4 elements of each "tr" element with each recursive call.
// I need to do so in a way that is dynamic and is based on the data attribute as I'll be using this with various forms.
});
return new Component(componentID, componentName, fields, subComponents);
}
I've looked at using the .not() function in jQuery but I don't think this works how I think it does. I'll continue searching for the solution, but if anyone knows of an easy/efficient way to do so please, I would really appreciate the help!
Solution
For a solution to your problem, check jQuery's .filter function here: http://api.jquery.com/filter/
// Get list of sub components
var subComponentArray = $(this).find("[data-component-id]");
// Get all fields that are not within the sub components
$(this).find('[data-mapping-id]').filter(function(){
return $(this).closest(subComponentArray).length === 0;}).each(function(index) {
// DO STUFF
});
For a solution to your problem, check jQuery's .filter function here:
http://api.jquery.com/filter/
and do something like this:
$(this).find('[data-mapping-id]').filter(function(){
return $(this).closest("[parent selector you don't want]").length === 0;
}).each(function() { .... });
Might be able to use not(). Using your Root, Child and Field tags as example if you only wanted the nested Field inside Child you can do:
$('Field').not("Root > Field');
This would exclude any Field that was a direct child of Root
It isn't clear what you are trying to filter exactly
How can I find the input box that is made hidden using hide() in jQquery?
$("#tab1").on('click', 'td button.save', function() {
var $thisParent = $(this).parent().parent().find("td:eq(1)").find("input").val();
$(this).parent().parent().find("td:eq(1)").find("input").hide().end().html('<span>' + $thisParent + '</span>');
});
// Here, this portion is not working:
$("#tab1").on('click', 'td span.edit', function() {
$(this).parent().parent().find("td:eq(1)").find("input").show();
alert($(this).parent().parent().find("td:eq(1)").find("input").prop("tagName"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="tab1" width="80%">
<tr>
<td></td>
<td>
<input class="fillcolumn" type="text" />
</td>
<td> <span class="edit">✎</span> <span class="remove">✘</span>
</td>
<td>
Weightage:
<select>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</select>
</td>
<td>
<button class="save">Save</button>
</td>
</tr>
</table>
The above code is not working, I mean, it is not turn the input box on with its value. Any help?
Few things need to be changed,
The appended span does not have edit class, so the click won't fire.
Use append() instead of html() as html() deletes the <input> tag.
Instead of .parent().parent() use .closest()
$(this).closest('tr')
.find("td:eq(1)")
.find("input").hide().end()
.append('<span class="edit">' + $thisParent + '</span>');
Demo
$("#tab1").on('click', 'td button.save', function() {
var $thisParent = $(this).closest('tr').find("td:eq(1)").find("input").val();
$(this).closest('tr').find("td:eq(1)").find("input").hide().end().append('<span class="edit">' + $thisParent + '</span>');
});
// Here, this portion is not working
$("#tab1").on('click', 'td span.edit', function() {
$(this).closest('tr').find("td:eq(1)").find("input").show();
alert($(this).parent().parent().find("td:eq(1)").find("input").prop("tagName"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="tab1" width="80%">
<tr>
<td></td>
<td>
<input class="fillcolumn" type="text" />
</td>
<td> <span class="edit">✎</span> <span class="remove">✘</span>
</td>
<td>Weightage:
<select>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</select>
</td>
<td>
<button class="save">Save</button>
</td>
</tr>
</table>
Further improved use of selectors. Refer Fiddle
instead of html() use append()
$("#tab1").on('click', 'td button.save', function(){
var $thisParent = $(this).parent().parent().find("td:eq(1)").find("input").val();
$(this).parent().parent().find("td:eq(1)").find("input").hide().end().append('<span>' + $thisParent + '</span>');
});
When you call save the input is removed from the page.
I guess what you want to do is hide the input when save is clicked and add in a new span with the value from the input?
this should help you move on:
http://jsbin.com/pufiroxolo/1/edit?html,js,output
but like #Shaunack D says lots of optimisations can be done with this! I've just used what was provided so not to confuse things!
When you call JQuery hide() on a DOM element, JQuery adds the style attribute for the dom as display:none.
You can do a find() using jquery for all text boxes and then check if each textbox has the style display: none.
Something like this
var listOfHidden = []
$($.find("input")).each(function()
{
if ($(this).css("display") == 'none'){listOfHidden.push(this)}
});
//variable listOfHidden will have the list of all hidden text
I am trying to retrieve the index of the row when the user has clicked on the check box. It works for the codes that I have written for the first two rows when the check box are ticked. However when I tried to insert more rows, the index that I retrieve after the check box is tick gave me a false result, i.e -1.
Can anyone help me with this? I have research for a long time and I still can't get it to work. I tried setting the clone argument to true but it still failed.
//Insert a new row after the last row in the table
$("#add").click(function() {
clickCount++;
var numRows = $('#getnumRows').val();
var index = $('#mytable tbody>tr:last td:nth-child(2)').text();
var i=Number(index);
var intNumRow=Number(numRows)+i;
for (; i < intNumRow; i++)
{
$('#mytable tbody>tr:last').clone(true,true).insertAfter('#mytable tbody>tr:last');
//$("#mytable tbody>tr>td:last td:nth-child(1)").children('input').addClass('chkbox');
$('#mytable tbody>tr:last td:nth-child(2)').text(i+1);
var input= $('#mytable tbody>tr:last').find('td').children('input');
input.val('');
input.attr("checked", false);
}
});//end click tag
var chkBox=$("#mytable tbody>tr>td ").children('.chkbox');
chkBox.on('click',null,function ()
{
var isChecked=$('.chkbox');
if (isChecked.is(':checked')) {
var index=chkBox.index(this);
alert(index); //added alert to intentional check the index retrieve from the checked checkbox of the row![enter image description here][1]
var insertNewRow=ajaxNewRowInfo(partNo,serviceName);
insertNewRow.success(function(data)
{
var row=$('#mytable tbody>tr').eq(index);
for(i=2;i<data.length;i++)
{
$(row.children(' td:nth-child('+(i+3)+')')).children('input').val(data[i]);
}
});//insertNewRow end tag
}//if end tag
else{
alert('You Un-Checked it');
}
});//chckbox end tag
<!--Add rows -->
<div class="form-group">
<label class="col-sm-1 control-label" style='margin-top:0.6%;'>Rows</label>
<input class="form-control" style='width:100px;' type='text' id='getnumRows' placeholder='No.of Rows'>
<button type="submit" id="add" class="btn btn-success" style="margin-left:200px; margin-top:-35px; ">Add rows</button>
</div>
<!------------->
<tbody>
<tr id='tableRow1'>
<td><input type="checkbox" class='chkbox'/></td>
<td> 1</td>
<td>
<select class="form-control" class="serviceDropdown">
<option></option>
<option value='1'>Oil Change Service</option>
<option value='2'> Tyre Service</option>
<option value='3'>Vehicle Service</option>
<option value='4'>Battery Service</option>
<option value='5'>Clutch Brake Service</option>
<option value='6'>Suspension Service</option>
<option value='7'>Brake Service</option>
<option value='8'>Tuning and Diagnostic Service</option>
</select>
</td>
</tbody>
[The first image shows the alert box which the index of the check box row is able to retrieved. The second image shows when new rows are added through cloning, the index of the alert box shows -1.]
http://postimg.org/image/913o3lyuv/
http://postimg.org/image/fg2p0a5kn/
Consider Element Indexing w/ jQuery Index()
Ex. http://codepen.io/anon/pen/XJRJEg
If .index() is called on a collection of elements and a DOM element or
jQuery object is passed in, .index() returns an integer indicating the
position of the passed element relative to the original collection.
HTML
<table id="hi">
<thead>
<tr>
<th>Heading</th>
<th>Heading 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
</tr>
</tbody>
</table>
jQuery
$( "table#hi tbody tr" ).click(function() {
var index = $( "table#hi tbody tr" ).index( this );
alert(index);
});
DOCUMENTATION
Hi I am new to javascript and html and was wondering if someone could help me understand why this error keeps occuring. The basic idea is that i have a dropdownlist that is populated with several options. When the customer selects an option an onchange event fires that will write the value of the selected option into a textarea. However when i debug it I get the message above I have included the relevant snippets of code below:
function selectReason() {
var selectindex = document.getElementById("selectmessage").selectedIndex;
var selecttext = document.getElementById("selectmessage").value;
document.getElementById("Txt").value = selecttxt;
}
<TR style="DISPLAY: none; VISIBILITY: hidden" id=sel>
<TD width="60%" align=left>Please select a reason</TD>
<TD width="40%" align=left>
<SELECT id="selectmessage" onchange="selectReason()" style="WIDTH: 425px"></SELECT>
</TD>
</TR>
You might be missing your <table> tags as that was causing a problem for me. Your provided snippet also has var selecttext and document.getElementById("Txt").value = selecttxt; <- missing an e.
The provided snippet below works for me. Possibly just failing to close a tag somewhere in your function/html.
Also (this could be you added inline to provide a better picture) you should avoid inline styles and (to me) functions. Include a .css and .js file.
function selectReason() {
var selectindex = document.getElementById("selectmessage").selectedIndex;
var selecttext = document.getElementById("selectmessage").value;
var elem = document.getElementById("hey");
elem.innerHTML = selecttext;
}
// Events to attach
function init () {
var elem = document.getElementById('selectmessage');
elem.addEventListener('change', selectReason)
}
// Run 'init' when the DOM is ready (jQuery's $(document).ready() )
document.addEventListener("DOMContentLoaded", init, false);
<table>
<TR>
<TD>Please select a reason</TD>
<TD>
<SELECT id="selectmessage">
<option>Hello</option>
<option>Yes</option>
</SELECT>
</TD>
</TR>
<tr>
<td id='hey'></td>
</tr>
</table>
Maybe this could help you
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<table>
<tbody>
<tr>
<td>
<select name="" id="selectmessage">
<option value="red">red</option>
<option value="gree">green</option>
<option value="blue">blue</option>
</select>
</td>
</tr>
</tbody>
</table>
<textarea name="" id="txt" cols="30" rows="10">
</textarea>
<script type="text/javascript">
$(document).on('ready', function(){
$('#selectmessage').on('change', function(){
var val = $(this).val();
var txt = $('#txt');
txt.val(val);
});
});
</script>
</body>
</html>
hope :)