Concise way to highlight label when items in dropdown changes? - javascript

I want to highlight labels with a color when the associated dropdown value changes.
<tr>
<td>
<select id="first_dd" data-bind="value: first">
<option>cat</option>
<option>dog</option>
<option>squirrel</option>
<option>birds</option>
</select>
</td>
<td>
<label id="first_lb">
soft</label>
</td>
</tr>
<tr>
<td>
<select id="second_dd" data-bind="value: second">
<option>lion</option>
<option>elephant</option>
<option>kangaroo</option>
<option>buffalo</option>
</select>
</td>
<td>
<label id="second_lb">
dangerous</label>
</td>
</tr>
I want to change the color of the first_lb when the first_dd items changed by the user.
How could I accomplish this in JavaScript/jQuery with less code?
Any suggestions highly appreciated.

So, here goes "less code".
Add change event handler to the select.
Try this:
$("#first_dd").change(function(){
$("#first_lb").css('color',"yellow");
});
DEMO
EDIT:
As your question asked only for first_dd and first_lb so I added code only for that part. To apply this to all selects use jquery .each().
If, you adding elements dynamically then you must use on to bind events, else it is enough to use .change().
So as you mentioned your requirements, do this:
$('select').each(function(){ //for each select elements in document
$(this).on('change',function(){ //bind change event
var id = $(this).attr('id').replace('dd','lb'); //get id for label
$("#"+id).css("color","yellow"); //highlight
})
})
DEMO

Make use of for attribute to connect labels with related select dom elements like
<select id="first_dd" data-bind="value: first">
<option>cat</option>
<option>dog</option>
<option>squirrel</option>
<option>birds</option>
</select>
<label for="first_dd">soft</label>
Add JS to detect Change and add class
$('select').each(function(){
$(this).on('change',function(){
$('label[for="'+$(this).attr('id')+'"]').addClass('changed')
})
})
And add appropriate CSS for changed class
.changed {
color: #000;
}

Related

Only one checkbox between two <td> at each <tr>

I have a code like this:
<tr>
<td>
<input type="checkbox" name="ordered[]" value="xxx"></input>
</td>
<td>
<input type="checkbox" name="inStock[]" value="yyy"></input>
</td>
</tr>
The code is repeated for each result in MySQL.
Also I'm using this code:
<script>
$('input[type="checkbox"]').on('change', function() {
// uncheck sibling checkboxes (checkboxes on the same row)
$(this).siblings().prop('checked', false);
});
</script>
I need to select only one checkbox per row (per table tr). What should I change in javascript?
Thanks!
I think you need something like this
$( document ).ready(function() {
$('input[type="checkbox"]').on('change', function() {
var checkedValue = $(this).prop('checked');
// uncheck sibling checkboxes (checkboxes on the same row)
$(this).closest('tr').find('input[type="checkbox"]').each(function(){
$(this).prop('checked',false);
});
$(this).prop("checked",checkedValue);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="checkboxes">
<tr>
<td>
<input type="checkbox" name="inStock[]" />inStock
</td>
<td>
<input type="checkbox" name="ordered[]" value="xxx" />ordered
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="inStock[]" value="yyy" />inStock
</td>
<td>
<input type="checkbox" name="ordered[]" value="xxx" />ordered
</td>
</tr>
</table>
I think what you are asking for is a RadioButton. Just give them different ids but the same name and you will be able to select just one of them.
Try applying selector based on element name:
$('input[name="ordered[]"]').on('change', function() {
Or you would probably want to add some other attribute to identify the specific element you wish to select.
Since you haven't specified which sibling, say you can grab the first element out of a jQuery object using first:
$(this).siblings().first().prop('checked', false);
You can also do
$(this).siblings(".bar").eq(0).text()
You can use the eq method to reduce the matched set of elements to one at a specific index:
If you use radio buttons and use the same name for all of them, you are only able to select one radio button at a time and the other ones gets uncheked and like our friend mentioned you need to include your <td></td> tags in <tr></tr>tags.

Dynamically populate user input corresponding json data with jquery

I have a json data that is like this,
[
{
"metalTypeId": 1,
"metalTypeName": "copper"
},
{
"metalTypeId": 3,
"metalTypeName": "steel"
}
]
My html is structured like this:
<table id="lineItemTable">
<tr class="row_to_clone">
<td>
<select>
<option>Select One Option</option>
<option>copper</option>
<option>steel</option>
</select>
</td>
<td>
<p></p>
</td>
</tr>
<tr class="row_to_clone">
<td>
<select>
<option>Select One Option</option>
<option>copper</option>
<option>steel</option>
</select>
</td>
<td>
<p></p>
</td>
</tr>
</table>
What I want to do is when the user select one of the options in the dropdown, I want to populate the corresponding json data to the p tag in my td. And my table contains two identical rows.
So for example, if user select copper for the first table row, and select steel for the second table row, the corresponding p will populate text "1" and "3" to the html page. If user do not select both rows, only the row that is selected will populate corresponding data to the p tag.
I am green to jQuery so I wrote some js code but it does not work as expected:
the variable that stores the json data is named as jasonData:
$('select').on('change', function (e){
$.each(jasonData, function(i, v) {
if (jasonData.metalTypeName == $('select').val()) {
$('p').text(v.metalTypeId);
return;
}
}); //end each()
}); // end on()
By looking at my code I already know one issue, the p and select select both two table row fields, but I do not know how to correctly fix it. The code may have other issues, please advice.
Your code is very close to working. You just need to cache the active select when it triggers the change event so you can reference it later; compare the active object in your each (you were incorrectly referencing the whole array); and use a few selectors to find the right paragraph. However, you may want to consider using something closer to David's answer. It's a bit cleaner than this method.
var jasonData = [
{
"metalTypeId": 1,
"metalTypeName": "copper"
},
{
"metalTypeId": 3,
"metalTypeName": "steel"
}
];
$('select').on('change', function (e){
var selected = this;
$.each(jasonData, function(i, v) {
if (v.metalTypeName === selected.value) {
$(selected).closest('.row_to_clone').find('p').text(v.metalTypeId);
return;
}
}); //end each()
}); // end on()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="lineItemTable">
<tr class="row_to_clone">
<td>
<select>
<option>Select One Option</option>
<option>copper</option>
<option>steel</option>
</select>
</td>
<td>
<p></p>
</td>
</tr>
<tr class="row_to_clone">
<td>
<select>
<option>Select One Option</option>
<option>copper</option>
<option>steel</option>
</select>
</td>
<td>
<p></p>
</td>
</tr>
</table>
I really recommend you not to use selectors so general such as "select" and "p"; while you are expanding your code, you'll get into issues because of these so generalized; I recommend you using some classes to help you or ID's.
Also, if you can change the structure of that JSON you won't need to do that each, basically you're forcing a O(n) problem there when you can something easier.
Here's an example I wrote for you doing the functionality that you want
http://jsfiddle.net/6v4zzgjj/
Now, if you want to make the selection of the results easier you can try the following
//Rename this variable better IE jsonData;
var jasonData = {"copper": { "metalTypeId": 1,"metalTypeName": "copper"}, "steel": {"metalTypeId": 3,"metalTypeName": "steel"}};
//Now the selector could be something like
$('.metalSelector').on('change', function (e){
var value = $(this).val();
$('#result').text(jasonData[value].metalTypeId);
});
That easy!

Getting nearest text box to radio button in table

I am having trouble getting the text box nearest to my selected radio button. Here is what I have tried so far which keeps returning me 'undefined'.
HTML:
<fieldset class="capacity-field">
<legend>Capacity</legend>
<table style="margin-bottom: 20px">
<tr>
<td>
<input type="radio" name="capacity" value="raw" checked>Raw (TB):
</td>
<td>
<input type="text" name="raw-capacity" value="256" size="2"> TB
</td>
</tr>
<tr>
<td>
<input type="radio" name="capacity" value="usable">Usable (TB):
</td>
<td>
<input type="text" name="usable-capacity" value="161.28" size="2"> TB
</td>
</tr>
<tr>
<td>
<input type="radio" name="capacity" value="effective">Effective (TB):
</td>
<td>
<input type="text" name="effective-capacity" value="161.28" size="2"> TB
</td>
</tr>
</table>
JavaScript/jQuery
function cap_growth_update(toUpdate) {
var capacity = $("input[name='capacity']:checked").next("input[type='text']").val();
alert(capacity);
}
$(document).ready(function(){
cap_growth_update("T");
});
I know the value of toUpdate is arbitrary at this point, but it will be used as a selector later down the line and thus is included.
The jQuery next() function looks for a sibling element, but since these elements are separated under different td elements, you'll have to climb up the DOM:
$("input[name='capacity']:checked").closest("tr").find("input[type='text']").val();
So what it does, is to go to the closest parent, and then search for the children text input.
Try using parents() with eq() and find()
$("input[name='capacity']:checked").parents().eq(1).find("input[type='text']").val();
Note this is only a suggestion I make based on your markup, your goal could be achieved in other ways (jQuery is a rich library to traverse and manipulate DOM)
$(function() {
$("input:radio").click(function() {
if ($(this).is(":checked")) {
var value = $(this).closest("tr").find("input:text").val();
}
});
});
The code checks for a click event on a radio element then check if the element is checked, if it's checked then obtain the parent row of the radio element, find an input text inside the row an get the value of the input text the it saves the value at the var value, so you can do whatever with the value :)
Regards!

Select Element doesn't work after clone

Hi! Guys I know nothing when it comes to JQuery... Please help me with this.
I created bootstrap form with a button add another field if the user want additional input fields. The new field are cloned from the original field.
The date-picker didn't work at first (on cloned field) so I add code to solve that.. (which I was luck to do and it took me 7hrs to get it correct)..
but then I found out even the cloned select box aren't working also.
-> Since the selector was using ID (#e1), I thought that was a reason so I changed it to class (.e1). That didn't help.
->So I tried the same method (like how I did on date-picker) but it also failed..
Here is the Code:
-> At Page header
<script src="assets/js/jquery-2.0.3.min.js"></script>
<script>
function cloneRow()
{
var row = document.getElementById("rowToClone"); // find row to copy
var num = Math.floor((Math.random() * 500) + 1);
var table = document.getElementById("tableToModify"); // find table to append to
var clone = row.cloneNode(true); // copy children too
clone.id = "row" + num; // change id or other attributes/contents
table.appendChild(clone); // add new row to end of table
clone.querySelectorAll('[id="id-date-picker-1"]')[0].id = "id-date-picker-" + num; //Put Unique ID
//For Selector
$(function(){
$('.e1').select2();
$('.clone').click(function() {
var clone = $('.select2').clone();
var cloned = clone.find('.e1');
cloned.removeClass('select2').removeAttr('id');
clone.appendTo('.elements');
$(cloned).select2();
});
});
}
</script>
The Row to be cloned
<tbody id="rowToClone">
<tr>
<td>
<div class="form-group" style="width: 100%;">
<select class="e1" style="width:100%;">
<option value="AL" />Alabama
<option value="AK" />Alaska
<option value="AZ" />Arizona
</select>
</div>
</td>
<td>
<div class="form-group" style="width: 100%;">
<select class="e1" style="width:100%;">
<option value="VA" />Virginia
<option value="WA" />Washington
</select>
</div>
</td>
</tr>
-> The trigger button
<button type="button" onclick="cloneRow()" class="btn btn-default purple"><i class="fa fa-plus"></i> Add </button>
->Page Footer
//On Page Footer
//--Jquery Select2--
$(".e1").select2(); //I added this line
$("#e1").select2();
$("#e2").select2({
placeholder: "Select a State",
allowClear: true
});
-> Please help me.. I will appreciate.
A couple of problems (your HTML for the options is invalid), but a lot of plugins, that change the DOM, simply do not like to be cloned. They store instance information in element data and are often not re-entrant (cannot reapply the plugin to elements that already have the DOM changes).
As taking existing rows to clone can get messy, I would suggest a slightly different approach to the cloning, that will avoid these problems.
Simply keep a separate template row in your page, that you can clone, inside a dummy script block:
<script id="rowToClone" type="text/template">
<tr>
<td>
<div class="form-group" style="width: 100%;">
<select class="e1" style="width:100%;">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option></select>
</div>
</td>
<td>
<div class="form-group" style="width: 100%;">
<select class="e1" style="width:100%;">
<option value="VA">Virginia</option>
<option value="WA">Washington</option></select>
</div>
</td>
<td>
<div class="form-group" style="width: 100%;">
<input type="text" class="datapicker"/>
</div>
</td>
</tr>
</script>
type="text/template" is unknown, so the script is ignored by all browsers.
Then the clone becomes as simple as:
$('#clonerow').click(function(){
$('#table tbody').append($('#rowToClone').html());
// now apply any plugins to the new row
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/j1smswmt/2/
Here is an expanded version with datepicker applied to each new row:
$('#clonerow').click(function(){
$('#table tbody').append($('#rowToClone').html()).find('tr:last .datapicker').datepicker();
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/j1smswmt/3/
Notes:
Your options are currently invalid. You need to enclose the text inside matching <option> & </option> tags.
As you are using jQuery avoid using inline onclick handlers. They separate the event registration from the event handler for no real benefit. Do it the jQuery way instead.
In case anyone still experience this issue but would still want to use the jQuery clone:
If you are using Bootstrap, you actually just need to remove the bootstrap-select and then reinitialise the normal cloned select.
Just add these two lines of code after you do your clone:
clone.find('.bootstrap-select').remove();
clone.find('select').selectpicker();
Based on answer from this Github issue: https://github.com/silviomoreto/bootstrap-select/issues/605

Get all selects after a current select element in a row

Let's say I have a table like this with multiple selects in very row:
<table>
<tr>
<td>
<select name="selectA" id="selectA">
....
</select>
</td>
<td>
<select name="selectB" id="selectB">
....
</select>
</td>
<td>
<select name="selectC" id="selectC">
....
</select>
</td>
</tr>
<tr>
<td>
<select name="selectA2" id="selectA2">
....
</select>
</td>
<td>
<select name="selectB2" id="selectB2">
....
</select>
</td>
<td>
<select name="selectC2" id="selectC2">
....
</select>
</td>
</tr>
<tr>
<td>
<select name="selectA3" id="selectA3">
....
</select>
</td>
<td>
<select name="selectB3" id="selectB3">
....
</select>
</td>
<td>
<select name="selectC3" id="selectC3">
....
</select>
</td>
</tr>
</table>
What I want to do is, when a select element changes, I want to get all select elements in the same row after the changed select element and change something with them as well.
So if selectA changes, I want to get selectB and selectC. If selectB changes, I want to get selectC. And so on. How to do that with jQuery?
Try this:
$('select').change(function() {
$(this).parent().nextAll().find('select')...
});
i.e. take the element's .parent() (which will be the <td>), then for all of its following siblings .nextAll(), .find() all <select> elements within them.
There are many jquery plugins that facilitate creating cascading dropdowns, which, in a nutshell, is what you want to achieve.
Here's a google search on "cascading dropdown jquery"; pretty much every result is a jQuery plugin :)
A slight modification of the Alnitak solution would be to bind the event handler on table level instead, so that you end up with only one function bound doing the job:
$('table').change(function(event) {
$(event.target).parent().nextAll().find('select')...
event.stopPropagation();
});
This will get you all the selects that are in the same row:
$("table select").change(function(){
var $select_mates=$('select', $(this).closest('tr'));
});
If you don't want the element itself:
$("table select").change(function(){
var $me=$(this);
var $select_mates=$('select', $me.closest('tr')).not($me);
});
My solution uses the jQuery Selector Context.
EDIT: Now I recognized I haven't seen after a current select element :). Let's see:
$("table select").change(function(){
var $me=$(this);
var $select_mates=$('select', $me.closest('tr'));
var $select_after_mates=$select_mates.slice($select_mates.index($me)+1);
});
Ok, this works, I've finally figured out how to do this:
$("table select").change(function(){
$(this).parent().nextUntil().find("select option:first").attr("selected", "selected");
});
i would try something like
//"obj" being your <select> HTML element
jQuery(obj).parent().find("select").not(obj);
UPDATE
I know the answer is already there but i thought for completeness I'd add a fix:
//"obj" being your <select> HTML element
// .parent().parent() gets the row
// .find("select" finds all the selects contained somewhere in that row.
// .not(obj) removes your current <select>
jQuery(obj).parent().parent().find("select").not(obj);

Categories

Resources