I'm using a table with the jquery dataTable plugin.
When I use the function fnAddData it works, except when the table is empty. Then, I get this error :
Cannot read property 'className' of undefined
This is how I add my data:
$("#table-1").dataTable().fnAddData([
data[0],
data[1],
data[2],
data[3],
data[4],
data[5],
data[6],
data[7],
data[8],
]);
And I have the same problem with fnDeleteRow with this error message:
Cannot read property 'nTr' of undefined
Here's how I use fnDeleteRow, I have no trouble when the table is not empty...
$("#table-1").dataTable().fnDeleteRow(tr)
where tr is a selector.
Am I missing something?
Here's my HTML tab with one last row :
<table id="table-1" class="table table-hover table-nomargin table-colored-header dataTable" aria-describedby="table-1_info">
<thead>
<tr role="row">
<th class="sorting" role="columnheader" tabindex="0" aria-controls="table-1" rowspan="1" colspan="1">Pays</th>
</tr>
</thead>
<tbody role="alert" aria-live="polite" aria-relevant="all">
<tr class="odd">
<td class=" sorting_1">
<div id="address23name">test</div>
</td></tr></tbody></table>
And here's my JS
$("#deleteAddressButton").click(function(){
var id = $("#deleteAddressId").val();
$.post("/Contacts/deleteAddress",
{data: id}, function(data) {
var id = $.parseJSON(data);
var tr = $("tr:has(td:has(div:contains(\"address\" + id + \"Name\")))");
$("#table-1").dataTable().fnDeleteRow(tr)
});
})
jQuery doesn't allow DataTables to access the data in the way that it prefers. In order to give it the node that it wants, you will probably need to apply [0] or .get(0) to the end of your jQuery object. That is actually what jQuery returns -- an object -- and normally exactly what you would be comfortable working with.
DataTables wants a node.
Here are some links that show the developer giving hints about how to access the data in different circumstances -- but with the same error in the 2nd link:
here
and
here
The moral of the story is that if DataTables is expecting a table "node", you need to do some extra footwork to remove the extra jQuery container that it is placed within.
Your code would, therefore, look like this and I believe should handle your error condition. Otherwise, be sure to search for your error and function name on DataTables.net. That forum is very active and helpful.
var tr = $("tr:has(td:has(div:contains(\"address\" + id + \"Name\")))");
$("#table-1").dataTable().fnDeleteRow(tr[0])
or
var tr = $("tr:has(td:has(div:contains(\"address\" + id + \"Name\")))");
$("#table-1").dataTable().fnDeleteRow(tr.get(0))
or of course, add it to the end of your lengthy $("tr:has...) statement.
Option 2:
Just hide the row you want to delete
If these ideas don't help, you may find allan's answers here insightful.
Here's a simple jsfiddle, which allows you to add a row to an empty table:
http://jsfiddle.net/7UZGM/
So what's different about your table? When you say "empty", does it still have a thead/tr/th section and an empty tbody section? These are required for datatables to work properly.
$('#dt').dataTable();
$('#btn').on('click',function() { addData(); });
function addData()
{
$("#dt").dataTable().fnAddData([
"col 1", "col 2", "col 3"]);
}
Related
I have a HTML table where one of the columns value is dynamically added. I have an update button, upon clicking it I want this data to get updated in my sql database. For this, I am planning to first fetch the table data and put into view , then send data to controller and then updating sql.
I am stuck at the first step,
Descibing table below
<thead>
<tr>
<th>ID</th>
<th >Name</th>
<th>Active</th>
<th>Order By</th>
</tr>
</thead>
<tbody>
#if (ViewBag.data != null)
{
foreach (var item in ViewBag.data)
{
<tr>
<td >#item.AutoID</td>
<td #item.Text</td>
<td >#item.Active</td>
<td>#item.OrderBy</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
<input type="submit" value="Update Preference" class="BtnUpdOrderId" />
</div>
I tried this below js function to fetch the data
$(".BtnUpdOrderId").click(function () {
var tr = $(this).closest('tr');
var id = tr.find('input[name="autoid"]').val();
var text = tr.find('input[name="text"]').val();
var active = tr.find('input[name="active"]').val();
var orderby = tr.find('input[name="orderby"]').val();
alert('type1 : ' + id + ' ' + text + ' ' + active + ' ' + active);
});
but not sure why nothing came in alert
var TableData = new Array();
$('#tblLookup1 tr').each(function (row, tr) {
TableData = TableData + $(tr).find('td:eq(0)').text();
alert(TableData);
});
then tried the above block of code to get data in a variable but still not able to get anything.
Once I get the data I can try sending from view->controller.
So need the following help:
what mistake am I making?
once this is fixed, how to send data to sql? (this is a ado.net based mvc project)
you might want to consider creating a json object:
Creating json object in mvc and returning from controller
then build your table Convert JSON array to an HTML table in jQuery
finally, the update need only post back the json object
https://dontpaniclabs.com/blog/post/2013/02/27/posting-json-data-to-an-mvc-controller-via-ajax/
if you going to use this jason object make sure you use serialization
https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?pivots=dotnet-6-0
your have to patch these concepts together but there are a lots of tutorials and examples online so it be a good learning experience
I hope this helps
helpful links:
https://www.sqlshack.com/modifying-json-data-using-json_modify-in-sql-server/
Updating a JSON object using Javascript
https://www.geeksforgeeks.org/how-to-convert-json-data-to-a-html-table-using-javascript-jquery/
create json object from html table using selected colums using jquery
I am using Angular http service to perform a DELEET operation , Its working fine , after deleting the data record I have to remove that row also from table .
Below is my code for all that
$scope.DeleteSchedule = function (recordId) {
var v =$window.confirm('Are you sure you want to delete ?');
if (v == true) {
var row = '#row' + recordId;
var table = 'table #tbl_Schedule_Delete tr ' + row;
$http({
url: '#Url.Action("DeleteSchedule", "Admin")',
method: "DELETE",
params: {
recordId: recordId
}
}).then(function mySuccess(response) {
alert('Row Deleted Successfully');
angular.element(document.querySelector(table)).remove();
//$('table #tbl_Schedule_Delete tr' + row).remove();
}, function myError(response) {
$window.alert('Warning! It failed.');
});
}
}
Refrence to jQuery remove() seems to do nothing
value of variable table will be 'table #tbl_Schedule_Delete tr #row35'
angular.element(document.querySelector(table)).remove();
I checked console log and there is no error or warning . How to do this in angular JS
Update 1 :
Below is Table Mark Up
<tr id="row34" role="row" class="odd">
<td id="delete34" class="sorting_1">
<a id="deletebtn_34" ng-click="DeleteSchedule('34')"><i class="fa fa-times fa-lg" aria-hidden="true" style="color:#e90029"></i></a>
</td>
<td>34</td>
<td>11956</td>
<td>Tota Ram</td>
<td>04-10-2017</td>
<td>02-12-2017</td>
<td>Haryana</td>
<td>Badaun</td>
<td>03-11-2017</td>
</tr>
I wouldn't delete the row using angular.element but show/hide the row with ng-if of ng-show.
<tr id="row34" role="row" class="odd" ng-show="!deleted[34]">
in combination with:
after deletion in your controller:
scope.deleted[recordId] = true;
The problem is with your selection query. The selector
table #tbl_Schedule_Delete tr #row35
actually matches the following HTML structure:
<table>
<any-element id="#tabl_Schedule_Delete">
<tr>
<any-element id="#row35"></any-element>
</tr>
</any-element>
</table>
As you can see, this doesn't match your HTML structure. This is because your selection query contains a couple of whitespaces when matching elements and ids. This causes it to look for child elements when matching the ids.
To fix it, your selector should instead look like this:
var table = 'table#tbl_Schedule_Delete tr' + row;
// Notice the lack of whitespaces after 'table' and 'tr'
Side note: using document.querySelector() inside angular.element() is redundant. You could simply use angular.element(table) since, angular.element is equivalant to using $(selector) (it's actually exactly the same, in case that you have jquery loaded)
I have a table that sets out a list of rules. When the checkboxes are clicked, I need them to take this "true" value and post to an API endpoint. This has been set up, but what I am getting back is that "associated_rule" is undefined.
I have tried setting $scope.associated_rule.selected = true; in my controller, but this still doesn't define the variable and throws up the same error in the console.
Here is my HTML form:
<form name="rules_form" method="post" ng-submit="attach()">
<table class="table table-striped table-hover" ng-model="associated_rules">
<thead>
<th>Rule Types:</th>
<th>Description:</th>
<th>Start Time:</th>
<th>End Time:</th>
<th>Apply Rule to Vehicle:</th>
</thead>
<tr ng-repeat="associated_rule in associated_rules">
<td>#{{ associated_rule.resource_ids.accounts }}</td>
<td>#{{ associated_rule.description }}</td>
<td>#{{ associated_rule.start_time }}</td>
<td>#{{ associated_rule.end_time }}</td>
<td><input type="checkbox" ng-model="associated_rule.selected" aria-label="rule"></td>
</tr>
</table>
<button class="btn btn-primary" ng-click="attach()">Attach</button>
</form>
My Controller event:
$scope.attach = function () {
$scope.associated_rule.selected = true;
var i;
for (i = 0; i < $scope.associated_rule.selected.length; i++) {
//need to create a loop where the true value is picked up and then I can send the data using a POST method. But I'm stuck on this.
}
console.log(the result of the event);
};
For now, I just want the results to console.log, so I can see that the event is creating the loop and displaying the results. After that, I should be OK.
Any help would be much appreciated.
I have fixed this by defining the $scope.rule as an empty array and setting the $scope.rule.selected to "false" by default.
Great! step one! But the checkboxes are ALL selecting when you click A checkbox - think this may be the ng-repeat causing me a pain in the backside.
$scope.rule = [];
$scope.rule.selected = false;
So, how do I ensure that only the checkboxes set that I select and not all at once?
Fixed this too; as the above was just making the entire array selected; as i wasn't drilling down into the array. This did it:
ng-model="rules.selected[associated_rule.id]"
by modelling the a rule within that defined array, it shows up when testing. Brill. :)
By mistake you are changing the value of your check box on clicking the button:
$scope.associated_rule.selected = true;
This will give the current value, selected or not selected
$log.log($scope.associated_rule.selected);
Using Ng-table, I have tried to create one table view, that could be controlled from AngularJS parameters.
To control the header text, I need to put it in data-title or ng-data-title (Example: data-title="'Test'")
But, it always makes the table header empty.
Instead of filling it:
Code Snippet:
<td ng-repeat="v in tableSettings.data" data-title="v.name">
{{v.data?v.data(row):row[v.id]}}
</td>
Full Code:
<table ng-table="table" class="table" show-filter="{{tableSettings.filter}}">
<tr ng-repeat="row in $data">
<td ng-repeat="v in tableSettings.data" ng-click="tableSettings.click(row)" ng-attr-data-title="'{{v.name}}'"
ng-if="v.type!='switch'"
sortable="'{{sortable?sortable:v.id}}'">
{{v.data?v.data(row):row[v.id]}}
</td>
</tr>
</table
When I try to parse Angular into it, I just get errors: (press to see the errors)
"'{{v.name}}'" "{{v.name}}"
Is there a way to fix it, or even to parse it manualy from AngularJS?
Ok the problem is that the data-title attribute is meant to be used with static text (well known columns) such as data-title="'My first column'"
If what you need is dynamic columns you got to use the ng-table-dynamic directive.
For example:
<table ng-table-dynamic="tableParams with cols" show-filter="true" class="table table-bordered table-striped">
<tr ng-repeat="row in $data track by row.id">
<td ng-repeat="col in $columns">{{::row[col.field]}}</td>
</tr>
</table>
Take notice in the directive declaration uses a special syntax tablePrams with cols. Here the cols is a $scope variable that must follow the following schema for this to work properly.
$scope.cols = [
{ title: 'ID', field: 'id', filter: { id : 'text' }, show: true, sortable: 'id' },
{ title: 'Installation', field: 'installationAt' },
...
];
Title and field are mandatory whereas filter, show, sortable depend on your usage scenario.
You can play around with this code pen
I have JSON data which i need to displayed in a table and then apply datatable on that table. Some part of the table is static while others must be created dynamically. There will be dynamic headers and offcource the data data to be shown will be taken from JSON. My Static HTML Code is as follows
<table border="1" align="center" id="info-table">
<thead>
<tr>
<th>Roll No</th>
<th>Student Name</th>
<th>Student ID</th>
<th>Class</th>
Now i have to dynamically add more headers so for that i am using $.each. After that i need to add The TD's to show the data. The code is as follows
obj = $.parseJSON(json.responseText);
if (obj.collection.response.error) {
displayError(obj.collection.response.error);
} else {
//Prepare fields for Attendance codes
$.each(obj.collection.response.attendanceCodes, function(key, value){
$('#info-table tr').append("<th>"+value.title+"</th>");
});
//Add the static headers
$('#info-table tr').append("<th>Teacher Comment</th><th>Admin Comment</th></tr></thead><tbody>");
//Prepare fields for EachStudent
$.each(obj.collection.response, function(i, val){
if(i != 'attendanceCodes'){
$('#info-table').append("<tr><td>"+val.rollNo+"</td><td>"+val.studentName+"</td><td>"+val.studentId+"</td><td>"+val.className+"</td><td align=\"center\"><div class=\"radio-green\"><input type=\"radio\" checked=\"checked\" name=\"attend-"+val.studentId+"\" /></div></td><td align=\"center\"><div class=\"radio-red\"><input type=\"radio\" name=\"attend-"+val.studentId+"\" /></div></td><td><input type=\"text\" style=\"width:200px;\" name=\"teacher-comment-"+val.studentId+"\" /></td><td>- - -</td><td></td><td></td><td></td><td></td></tr>");
}
});
//$('#info-table').dataTable();
}
},
dataType:"JSON"
But this code is not working and i am getting error in console that says:
Uncaught TypeError: Cannot read property 'childNodes' of null
It will be better if you use any jquery plugin for that.Like datatable or jqgrid.It will give good support to JSON and XML based data.
http://trirand.com/blog/jqgrid/jqgrid.html
Yes i got the answer...
We will have to remove the closing tr and thead and the new code for that area will be and it worked.
//Add the static headers
$('#info-table tr').append("<th>Teacher Comment</th><th>Admin Comment</th>");