Cloning table row in Jquery - javascript

Running into a bit of a brick wall with jquery, I currently have the following code:
http://jsfiddle.net/uSLhb/1/
The clone method being:
$("#addMore").click(function() {
$('.user_restriction:last').clone().insertAfter(".user_restriction:last");
return false;
});
As you can see I have it set up so you can easily clone the row.
The problem I am facing is showing the correct select list (In the 'Field' column) in the new cloned elements, depending on what field they select from the first select (In the 'table' column) field in the row.
Wondering if anyone can help me find a solution, thanks!

The problem you are facing occurs, because you are using IDs for your selects.
IDs must be unique in a page, otherwise you'll run into trouble. If you're cloning a select with an id, the id will be cloned too, thus producing an invalid document.
Have a look at the example I created on JsBin
Markup:
<tr class="user_restriction">
<td>
<select name="table[]" class="userselect">
<option value="" selected>---</option>
<option value="members">Members</option>
<option value="staff_positions">Staff Positions</option>
</select>
</td>
<!-- and so on, basically just changed ids to classes -->
</tr>
I changed all the IDs to classes and altered the change-handler, because this was your second problem.
An event-handler gets bound to the elements that are selected, not to those you add afterwards. This is a proper use-case for event-delegation, when the handler is bound to a parent and catches, in this example, the change event from a child select-element, no matter when it was added to the DOM.
Using jQuery, this is a way to achieve this:
$('table.table').on('change', '.userselect', function() {
var activeRow = $(this).parents('tr');
activeRow.find('td').eq(1).find('select').hide();
if(this.value.length === 0){
activeRow.find('td').eq(1).find('select').eq(0).show();
}else{
activeRow.find("." + this.value).show();
}
});
The handler is bound to your table - element, .userselect is a class I added to the first select in a row. So every change on an element that was added later would be handled too. In the handler, I changed the behaviour to affect only the actual table-row, not the whole table.

Working example here - I had to use jsbin as fiddle was playing up!
Clone does not maintain the selected state, so you'll need to grab the value before cloning and set it after.
Your click now becomes:
$("#addMore").click(function() {
var value = $('.user_restriction:last').find('select').val();
$('.user_restriction:last').clone().insertAfter(".user_restriction:last");
//alert(value);
$('.user_restriction:last').find('select').val(value);
return false;
});

Related

Bug when trying to update an HTML table value in the DOM

I am trying to implement a simple update functionality for the values in my table. I have an edit button, which triggers a modal where I edit the values and save them. In order the values to be immediately update in the DOM I am using the following jquery code on save:
$('#lblEditDeleteProducts').find("tr .nameDom").text("new val");
$('#lblEditDeleteProducts').find("tr .brandDom").text("new val");
$('#lblEditDeleteProducts').find("tr .priceDom").text("new val");
The problem is that with this code intead of one row in my table all the rows get updated with the "new value". I am very new to jquery and I am out of ideas how to solve this, so any help will be appreciated.
Here is my table structure :
As there is not much information of your HTML code
var selectedTR;
$("#lblEditDeleteProducts tr").click(function(){
selectedTR=$(this);
//init your modal pop up here or do it globally
})
Let assume the ID of save button is #save
$("#save").click(function(){
selectedTR.find(".nameDom").text("new val"); // get relative value from the mdoal input
selectedTR.find(".brandDom").text("new val");
selectedTR.find(".priceDom").text("new val");
})
If you are interested you can use this plugin also (advanced feature) datatable inline edit
The selectors that find is using are too general, so they're selecting all matching rows.
$('#lblEditDeleteProducts').find("tr .nameDom").text("new val");
Here's what jQuery is doing with that particular line of code (the same thing applies to all the others, too):
Get lblEditDeleteProducts by ID
Using that node, find() all descendant elements that match the selector tr .nameDom
Update the text of all nodes that it finds.
In your case, that selector matches every element in every row because they're all descendants of #lblEditDeleteProducts; there's no way to filter out just those you want with the code that you've written.
You'll need a way of explicitly determining which row to update.
Based on your comment that the edit button is in the each row, you can reference the corresponding row with closest
$("EDIT BUTTON SELECTOR").click(function(){
var $btn = $(this);
var $row = $btn.closest("tr");
$("DIALOG SELECTOR").dialog({
buttons:{
Save: function(){
//bunch of stuff
$row.find("td.nameDom").text("new val");
}
}
});
});

How to get the value in a select change event in angular2

I want to navigate useing a dynamically generated select drop down.
It doesn't appear I can do that directly, so I'd simply like to make a function call when the select changes.
To do that, I have this:
---In the template---
<select (change)="navSelected($event)">
<option *ngFor="let button of navButtons;"
value="button.route" >{{button.label}}</option>
</select>
suffice it to say that 'navButtons' is an array of objects that have a 'label' field.
---In the class---
navSelected(navName) {
console.log(navName + " Clicked!");
}
This actually works fine.
I got to this point from the great help of Mark Rajcok and his answer in this older question:
How can I get new selection in "select" in Angular 2?
That said, I'd like to be able to pass the selected value in the navSelected() function call. I'm unsure how to do that.
I have tried adding [ngValue]="button" on a wild guess from other searches to the option tag and then referencing the button variable in the (change) event handler (so: (change)="navSelected(button.label)" and other combos, to no avail. I've seen a lot of references to ngModel but they seem old and I'm not entirely sure they apply anymore (and I couldn't get them to work anyway in RC4).
I could probably pull some jquery or whatever out to find the select and get it's value, but that seems very rinky-dink compared to simply being able to call the function correctly.
The value you are looking for is on the $event.target and you can get it with $event.target.value, see my example below.
navSelected($event) {
console.log($event.target.value + " Clicked!");
}
If you are looking to get the selected text of the option you can do this
navSelected($event) {
let selectElement = $event.target;
var optionIndex = selectElement.selectedIndex;
var optionText = selectElement.options[optionIndex];
console.log(optionText + " Clicked!");
}
As a shortcut for #eltonkamami 's answer, you can pass your object like this:
<select (change)="navSelected(navButtons[$event.target.selectedIndex])">
<option *ngFor="let button of navButtons;">{{button.label}}</option>
</select>
And capture it like this:
navSelected(button: [type of navButtons]){
console.log(button);
}
Instead of $event. Try using the below typecast function.
$any($event.target).value
Which will stop the type checking in the template.

How to get data element of checkbox on change event

I've got a dynamic table of items with checkboxes next to each item. When a user selects a checkbox I want to grab the "Name" item from the table and add it to a textbox. See image:
The way I'm trying to accomplish this is by adding a "change" event to every checkbox and populating it's "data-name" element with the name of the text.
<tbody>
#foreach (var item in Model.Items)
{
<tr>
<td><input type="checkbox" name="selectBox" data-name="#item.Name" /></td>
As you can see I'm populating data-name with the item name as a way to get around pulling it directly (which I don't know how to do). Now in javascript/jquery I'm tying an event to every checkbox and attempting to get the data element using the following code:
$('input[name=selectBox]').change(function (item) {
var text = $(item).attr('data-name');
});
When the code runs the event is firing for all checkboxes, but "text" is undefined when I expect it to be the name data.
Looking for an answer to my method of doing this AND/OR a better way involving skipping the data element all together and getting the name value directly. Thanks for looking.
Try this:
var text = $(this).data('name');
The first parameter of your change function is the event, not the element itself. Also, jQuery automatically sets the function scope (this) to the element being changed.
See Documentation
In your case item is event object not DomElement, you can get element through event property currentTarget
$('input[name=selectBox]').change(function (item) {
var text = $(item.currentTarget).attr('data-name');
});
or use this because this refer` on current Element, it is the same as in previous example but shorter
$('input[name=selectBox]').change(function (item) {
var text = $(this).attr('data-name');
});

Selection from dropdownlist javascript event

I have this html part code :
<p><label>Taxe </label>
<select id="id_taxe" name="id_taxe" style="width: 100px;" onchange="taxselection(this);"></select>
<input id="taxe" name="taxe" class="fiche" width="150px" readonly="readonly" />%
</p>
Javascript method :
function taxselection(cat)
{
var tax = cat.value;
alert(tax);
$("#taxe").val(tax);
}
I'd like to set the value of taxe input to the selected value from the dropdownlist.It works fine only where the dropdownlist contains more than one element.
I try onselect instead of onchange but I get the same problem.
So How can I fix this issue when the list contains only one element?
This works:
$('#id_taxe').change(function(){
var thisVal = $(this).val();
var curVal = $('#taxe').val();
if(thisVal != curVal)
$('#taxe').val(thisVal);
$('#select option:selected').removeAttr('selected');
$(this).attr('selected','selected');
});
Use the change method which is very efficient for select boxes. Simply check the item selected isn't currently selected then if not, set the value of the input to the selected value. Lastly you want to remove any option's attr's that are "selected=selected" and set the current one to selected.
Just include this inside a $(document).ready() wrapper at the end of your HTML and the change event will be anchored to the select field.
Hope this helps.
http://jsbin.com/populo
Either always give an empty option, or in your code that outputs the select, check the amount of options, and set the input value straight away if there's only 1 option.
A select with just 1 option has no events, since the option will be selected by default, so there's no changes, and no events.
As DrunkWolf mentioned add an empty option always or you can try onblur or onclick event instead, depending on what you are actually trying to do.
Ok, just to stay close to your code, do it like this: http://jsfiddle.net/z2uao1un/1/
function taxselection(cat) {
var tax = cat.value;
alert(tax);
$("#taxe").val(tax);
}
taxselection(document.getElementById('id_taxe'));
This will call the function onload and get value of the element. You can additionally add an onchange eventhandler to the element. I highly recommend not doing that in the HTML! Good luck.

Jquery checkboxes within containing table selector question

My current code:
<script type="text/javascript">
function checkAll(checked) {
$("input[type='checkbox']:not([disabled='disabled'])").attr('checked', checked);
}
</script>
<input type="checkbox" id="cbxSelectAll" onclick="checkAll(this.checked);" />
The short version:
How do I modify the function call and method above to check all checkboxes inside a table containing the checxbox form element.
The long version:
I am creating a WebUserControl containing a grid view in asp.net that is going to have a delete option. I would like the delete to be a series of checkboxes with one a box in the header to select all of them. What this amounts to for non ASP.NET people is a table with a header row that has a checkbox and every row also has a checxbox.
I have used the above code to check all boxes on the entire page. That won't work here though because I want to have multiple of these on the page at once each working independently. I know I could use a selector to select all the boxes if I ID'd the table but that would require some coding to name the table uniquely and then put that name in the script block.
Really what I would like is to modify the script above to check all checkboxes in the containing table of the "select all" box. The table containing the checkbox could be nested within others but I don't see any being nested within it, or if there are and the nested table also contains checxboxes I don't care if they also get selected.
Thanks for your help.
First, don't mix your HTML and your Javascript. Use event handler binding instead.
Second, use closest to get the nearest ancestor element of a particular type:
$(document).ready(function(){
$('#cbxSelectAll').click(function() {
$(this)
.closest('table') // get the parent table element
.find("input:checkbox:enabled") // find children that match the selector
.attr('checked', this.checked); // set their checked value
});
});
Change your inline attribute to this:
<input type="checkbox" id="cbxSelectAll" onclick="checkAll.call(this);" />
And your checkAll() to this:
function checkAll() {
$(this).closest('table').find("input:checkbox:enabled").attr('checked', this.checked);
}
Using .call(), it is called from the context of the element clicked.
Then the jQuery gets the closest()(docs) <table> and finds the inputs using the checkbox-selector(docs) and the enabled-selector(docs) .
Then when using the attr()(docs) method, you can use this.checked to set the checkboxes to the current state of the one checked.
You can find the table containing the select all using .closest
function checkAll(checked) {
var $table = $(this).closest('table');
$table.find("input[type='checkbox']:not([disabled='disabled'])")
.attr('checked', checked);
}
If there might be several nested tables it's often easiest to specify the one you want with a class, e.g. $(this).closest('table.tableOfCheckboxes'); where you add class tableOfCheckboxes to the table you want to find.

Categories

Resources