I have a table showing project names as shown in below image ,
On delete button click, I am passing the selected check-boxes data as array of objects to my controller
[{id:1,name:'Name 8'},{id:2,name:'Name 7'}]
Then deleting the names from the table at the server side. This all works fine but how do i remove the rows from DOM after deleting them?? I went through this post which says how to remove ng-repeat elemets from DOM but in that case the elements are removed one at a time, by passing the $index to the splice() function
In my case i need to remove multiple rows. If ill have to use the splice function in my controller how do i get the index from the selected rows object? Or is there any better way of doing it.
Hope my question is clear!
Update: jsFiddle
Solution: Well i had to modify #wickY26 answer a bit to suite my scenario. Here is my update jsFiddle
What i did was , in the delete() change code to
angular.forEach($scope.projects, function (row, index) {
if($scope.projects[index].checked) {
$scope.projects.splice(index,1);
}
});
You can keep selected rows on an object via binding checkbox with ng-model,
so example table html should be like this
HTML
<table class="table table-bordered">
<tbody>
<tr ng-repeat="row in data" ng-class="{'success' : tableSelection[$index]}">
<td>
<input type="checkbox" ng-model="tableSelection[$index]" />
</td>
<td ng-repeat="cell in row">
{{cell}}
</td>
</tr>
</tbody>
</table>
and if you define a function in your controller which travel through your data and splice array depends on tableSelection object boolean values...
UPDATE
after your comment I debug my code and see I cannot remove multiple rows same time, so I look at my code and change some part of it...
at my example you cannot delete multiple rows same time because everytime you splice an element from data array you shift indexes of array for rest, so right way to do it starting from last index,
Here new CONTROLLER
$scope.removeSelectedRows = function() {
//start from last index because starting from first index cause shifting
//in the array because of array.splice()
for (var i = $scope.data.length - 1; i >= 0; i--) {
if ($scope.tableSelection[i]) {
//delete row from data
$scope.data.splice(i, 1);
//delete rowSelection property
delete $scope.tableSelection[i];
}
}
};
I update my PLUNKER added comments and some other functionallty as well...
Related
I have two tables. The client should be able to drag and drop each table's row. They can either drop the row into a new position on the current table, or add the row to a specific position on the other table.
I'm able to insert the new row into the desired position on either table (and delete the original), but when I try to drag-and-drop that element a second time, it's parent element comes back as null, preventing me from repeating the drag-and-drop function a second time.
I need to solve this with pure, vanilla javascript.
//Table Structure (there are two of these, I'm trying to save space here)
<table id="thisTable" class="dropzone">
<thead>
...
</thead>
<tbody id="thisBody">
<tr id="123" class="drag-row draggable="true">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr id="124" class="drag-row draggable="true">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
//Collect Variables from the original row, the target table and the row being dropped into.
//Code to Insert New Row
function addRow(table_id, copy_id, target_id) {
let targetRow =document.getElementById(target_id);
let targetIndex = targetRow.rowIndex;
let copyRow = document.getElementById(copyId); // find row to copy
let targetTable = document.getElementById(tableID); // find table to append to
let clone = copyRow.cloneNode(true); // copy children too
//clone.id = "newID"; // change id or other attributes/contents
//table.appendChild(clone); // add new row to end of table
//targetTable.children[1].insertAdjacentElement("afterbegin", clone);
// Insert a row at desired index
let newRow = targetTable.insertRow(targetIndex);
newRow.id = clone.id;
newRow.draggable = "true";
newRow.classList.add("drag-row");
newRow.innerHTML = clone.innerHTML;
}
//Code to delete original row
dragSrcEl.remove();
I don't think I'll need to add in all the drag-and-drop code, because those seem to be working fine (when the parent element of the inserted node isn't null).
I've gone through a couple questions similar to this one and it seems that some commands in vanilla create new elements without tying them to the DOM? Supposedly by using the append() command you could add a new row to a table without disconnecting it from the DOM, but I tried that and got no result.
Which of the commands I'm using above would disconnect the newly inserted row from the DOM?
Is there a safe way, in vanilla js, to copy the contents of a row and inserted into a specific index of another (or the same table)?
It's frustrating because I finally got the code working... once.
Any thoughts?
Ah, I forgot to add the necessary event listeners to the newly inserted row, that would explain why drag-and-drop stopped working for them :)
I have the following situation I can not solve. I would be very thankful if anyone had an idea:
My webpage contains a table of players. Each line (player) contains two checkboxes: One that selects if the player is active (checked) or not, the other which team he/she belongs to (checked=Team 1; unchecked=Team 2).
So each line looks sth like this:
<tr>
<td><input id="plyr2_active" type="checkbox" name="plyr_active[]" value="2"></td>
<td><input type="checkbox" id="plyr2_team" name="plyr_team[2]" data-on-color="danger" data-off-color="success" data-on-text="RED" data-off-text="GREEN" checked value="1"></td>
</tr>
I'd like to add a button that, when clicked, will run a function that randomizes the teams of the ACTIVE players. Meaning that the players will be shuffled and half of them belong to one, the other half to the other team.
What I tried: Get all checkbox states in an array, then shuffle() the array and try to change the checked-state via bootstrap. Miserably failed :-(
Any help will be much appreciated. Thanks!!
Okay, this should help to get you started. It shows how to pull a list of active players (using jQuery) from your table.
Assuming you have a button with an id of 'shuffleBtn':
<button id="shuffleBtn">Shuffle<button>
and a table with id 'players':
<table id='players'>
:
</table>
-
$("#shuffleBtn").click(function() {
var newPlayerArray = [],
id = 1;
$("#players tr td:first-child").each(function() {
if ($(this).find('input:first').prop('checked')) {
newPlayerArray.push(id);
}
id++;
});
console.log(newPlayerArray);
});
This will display an array of the active players (assuming the first row is player 1, the second player 2, etc.) on the console.
Example: [1,3,4]
It then iterates each row () and grabs the first column (). Then for each of those it finds the first <input> and checks if the 'checked' property is present (this means the checkbox has been clicked).
I am just pushing the row index (starting at 1) so you may need to change how you interpret the associated player.
I have a table that uses Angular orderby. I use a function called tcoSort that makes a calculation and then sorts the table. The problem is when I call displayFullPricing() from the radio button in the rows - the table loses the sorting.
<table class="table table-striped table-hover">
<tr ng-repeat="prices in productVariant.prices | orderBy: tcoSort">
<td>£{{prices.monthly.retailPrice}}</td>
<td>£{{prices.nonRecurring.retailPrice | number:0}}</td>
<td><input type="radio" name="{{productVariant.code}}" ng-click="displayFullPricing($index)"></td>
</tr>
$scope.tcoSort = function (productVariant) {
if(!$scope.isDisplayPrice){
return productVariant.nonRecurring.retailPrice + (productVariant.monthly.retailPrice * 36);
}
};
$scope.displayFullPricing = function (index) {
$scope.isDisplayPrice = true; //This is to stop the table sort running more than once.
I put this here to act as a flag as everytime this function was called from the radio button, tcoSort would fire again and sort the table.
This meant that the radio button would only work once.
//rest of code
}
I guess the issue is that I am creating the flag to stop the sort happening every time I click a radio button in the table. But If i don't put it there, the $index is always set to the top result - so it would always be 0.
Instead of passing the $index of the relevant item to your displayFullPricing function you should just pass the object itself, e.g.
ng-click="displayFullPricing(prices)"
Presumably somewhere in // rest of code you're just selecting the relevant item based on its index anyway?
I am trying to create a code using backbone.The user inputs text into two fields Item and price. This info then is appended to a table and creates a new row for every input pair entered.
I've created a template for the table. My question when creating my view since the data from the text fields of item and price need to be sorted into the corresponding cells, how do I append the new rows correctly. Can I just make a view for the row? Or do I need to do it for each cell?
<div id="container">
<script id="grocery-list-template" type="text/template">
<table>
<thead>
<tr>
<th>Item</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td><%=something to get item%></td>
<td><%=something to get the price%></td>
<td></td>
<td><button class="complete"></button><button class="remove"></td>
</tr>
</tbody>
</table>
</script>
</div>
This is essentially what Im trying to do, but I dont know how to specify the row AND the cell? Do I have to make a view for each cell using tagname: td or can I just keep tagname: tr and route the data into the apropriate cells? I found an example that just appended a list using li elements so I was trying to adapt some of it to my code
var TableView = Backbone.View.extend({
tagname: "tr",
classname: "itemAndprice",
template:_.template($("grocery-list-template").html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
this.$el.attr("id", this.model.id);
if (this.model.get('done')) this.$el.addClass('done');
$("#GroceryList").append(this.$el);
return this;
},
You can create a view for the whole row. For each row you would need a row-model with item and price attributes which you would pass into the row-view's constructor. This pretty much looks like the TableView in your code (except I would expect that to be called RowView instead, the TableView being a different, 'parent' view)
Given that your model contains item and price attributes, the row-view-template should contain
....
<td><%=item%></td>
<td><%=price%></td>
....
Then this.model.toJSON() would give you a hash with item and price attributes which would be passed into this.template, populating <%=item%> and <%=price%> with the relevant values.
You can also take a look at underscore's template function for further information.
Note however that the row-view and the table-view should be two different views. From your code it seems that you have a template appropriate for a table-view (which also contains a single row that shouldn't be there) and a view appropriate as a row-view.
Having two views you would pass a collection of row-models in the table-view which would iterate over the collection and add a row(-view) for each model. When the user creates a new item you'd add a model into the collection and re-render the table.
Hope this helps.
I am using datatables and have this tr element in table
<tr class="gradeA even row_selected" id="3692">
<td class=" sorting_1">3692</td>
<td class="">koza</td>
<td class="" title="10:12:30">2013-12-31</td>
<td class="">2014-02-06</td>
<td class="">FULL packet</td>
<td class="">NONE</td>
<td class="">Name</td>
</tr>
I would like to update 1st and 4th td element using fnUpdate function. I have tried to update for only one td but it does not update.
In Chrome, console log I am getting this error:
Uncaught TypeError: Cannot set property '_aData' of undefined
Here is what I have tried:
// dynamically update row
$('#example').dataTable().fnUpdate( ['Zebra'], parseInt('3692'));
3692 is the id of the td element to know which row I need to update, and the zebra is the value to change. I know that I have not included which cell to update but I don't know how to do that. On datatables api, following example is given:
oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], 1 ); // Row
Please review the docs here http://datatables.net/api
Your question is not complete, as you need to specify what column(td) you want to modify, but here's what I would try (assuming you want to update the second column).
$('#example').dataTable().fnUpdate('Zebra' , $('tr#3692')[0], 1 );
The second parameter will be the row, and the third is the column.
Note that I passed in a string.
I prefer this:
var myDataTable= $('#myDataTableId').DataTable();
var row = myDataTable.row( '#idRow');
myDataTable.cell(row, 2).data("New Text").draw();
Note:
2 is column, cell inside modified row.
This works for me
var tableRow = $(this).closest('tr').index(); // GET TABLE ROW NUMBER
$('#table').dataTable().fnUpdate('Zebra', [tableRow], 1, false)
You don't need to specify the column. Your issue is that you are using row ID when the doc states that 2nd argument can be the aoData index or the element.
Make sure your number of columns is correct, but you should be able to do it like so:
$('#example').dataTable().fnUpdate( ['Zebra'], $('#example tr#3692')[0]);
In my case I wanted to update an entire row with data coming from backend as an object. Referring to:
$('#example').dataTable().fnUpdate('Zebra' , $('tr#3692')[0], 1);
I modified it a bit and used this lines of code to update an entire row without having to draw entire data table:
// get an selected row/row under edit action
let ele = $("#DTTableID")..dataTable().find('tr.row_selected');
$("#DTTableID").dataTable().fnUpdate(obj, ele);
Here obj is data object and ele is selected row.
Try:
$('#datatable').dataTable().fnUpdate(result, $('[data-id=' + idvalue + ']'), 8 );
This is best way to update column value without error and add table row with data-id="row id value" ....it works fine.