Two way data binding using jQuery dataTable and ASP.NET MVC - javascript

I have a form which gets it's data using jQueryDataTable.
$('#myTableName').DataTable(
{
"ajax": {
"url": "/API/Loaddata",
"type": "GET",
"datatype": "json"
},
"columns": [
{
"data": "IsSelected",
"render": function (data, type, row) {
if (type === 'display') {
return '<input type="checkbox" class="editor-active">';
}
return data;
},
"className": "dt-body-center"
// "autoWidth": true
},
{ "data": "Name", "autoWidth": true }
],
"rowCallback": function (row, data) {
// Set the checked state of the checkbox in the table
$('input.editor-active', row).prop('checked', data.active == 1);
}
}
);
Now to get data I have following code,
private static IEnumerable<CircState> rCirc;
[AllowAnonymous]
public ActionResult LoadData()
{
rCirc= _repo.GetAll().OrderBy(circ => circ.ID).Select(x => new CState { IsSelected = true, Name = x.Name });
return Json(new { data = circuits }, JsonRequestBehavior.AllowGet);
}
This works fine an I get following JSON, which is bound to my view:
{
"data":
[
{"IsSelected":true,"Name":"SMyDataPoint__01"},
{"IsSelected":true,"Name":"SMyDataPoint__04"},
{"IsSelected":true,"Name":"SMyDataPoint__07"},
{"IsSelected":true,"Name":"SMyDataPoint__08"},
{"IsSelected":true,"Name":"SMyDataPoint__09"},
{"IsSelected":true,"Name":"SMyDataPoint__10"},
{"IsSelected":true,"Name":"SMyDataPoint__11"}
]
}
This is my UI code:
<div class="form-group">
#Html.LabelFor(model => model.Cirs, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-5">
<table id="filtersTable">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
</tr>
</thead>
</table>
</div>
</div>
Now when I am tick/untick an item and click on submit button, How can I get the unslected items.
What I need is two-way binding between View and Model , so When I call following code , I should get all the items based on there state(true/false).
$('#btnRunReport').click(function (e) {
e.preventDefault();
$.ajax({
type: "GET",
url: "/Circuits/SelectedCircs/",
success: function (result) {
console.log(result);
},
error: function (result) {
console.log('Error');
}
});
});
[AllowAnonymous]
public ActionResult SelectedCirs()
{
//rCirc is the global variable decalred on top (In First API)
var selectedCircs = rCirc.Where(x => x.IsSelected == false);
return Json(selectedCircuits);
}

Related

JQuery Datatable Reload From Server MVC

I have a Datatable of JQuery generated at first-page load. I am trying to refresh it according to the selected criteria from the selectlist.
My Datatable initialized first like the following code.
<table class="table table-striped table-hover" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Select All <input type="checkbox" class="checkbox" id="chkBoxAll"></th>
#foreach (System.Data.DataColumn col in Model.DataTypesTable.Columns)
{
<th> #col.Caption</th>
}
</tr>
</thead>
<tbody>
#foreach (System.Data.DataRow row in Model.DataTypesTable.Rows)
{
<tr>
<td> <input type="checkbox" class="checkbox" name="chkBox" value="#row.ItemArray[0]"></td>
#foreach (var cell in row.ItemArray)
{
<td>
#cell.ToString()
</td>
}
</tr>
}
</tbody>
</table>
<script>
$(document).ready(function() {
$('#dataTable').DataTable();
});
</script>
It initializes well at first. However, when I try to reload it on the selectlistchange event, it doesn't reload anything and displays an error like this.
DataTables warning: table id=dataTable - Requested unknown parameter 'Id' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4
<script type="text/javascript">
$("#slctDeviceList").change(function () {
var selectedValue = $("#slctDeviceList option:selected").text();
$.ajax({
traditional: true,
dataType: 'html',
type: "GET",
url: '#Url.Action("GetDeviceDataTypes", "Home")',
data: { slctDeviceList: selectedValue },
success: function (result) {
console.log("Success");
console.log(result);
$("#dataTable").DataTable({
destroy: true,
data: result,
columns: [
{ data: "Id", name: "Id" },
{ data: "Data Name", name: "Data Name" },
{ data: "Description", name: "Description" },
{ data: "Device Type", name: "Device Type" }
], columnDefs: [{
"defaultContent": "-",
"targets": "_all"
}]
});
},
error: function (result) {
console.log("error");
}
});
});
</script>
Controller:
public JsonResult GetDeviceDataTypes(string slctDeviceList)
{
ChartRepository repository = new ChartRepository();
System.Data.DataTable dt = repository.GetDataTypes(slctDeviceList);
var json = this.Json(new { data = dt }/*, _jsonSetting*/);
return json;
}
My data is like below from the developer tools:
Please help me out to resolve the issue... Thanks in advance.
After long tries and losing hairs.. I have found a solution clear and add the rows again instead of destroy command. Here is the solution below.
<script type="text/javascript">
$("#slctDeviceList").change(function () {
var selectedValue = $("#slctDeviceList option:selected").text();
$.ajax({
traditional: true,
dataType: 'json',
type: "GET",
url: '#Url.Action("GetDeviceDataTypes", "Home")',
data: { slctDeviceList: selectedValue },
success: function (result) {
console.log("Success");
var dataTable = $("#dataTable").DataTable();
dataTable.clear().draw();
$.each(result, function myfunc (index, value) {
// use data table row.add, then .draw for table refresh
dataTable.row.add([
'<input type="checkbox" class="checkbox" name="chkBox" value="' + value.Id + '">',
value.Id,
value.DataName,
value.Description,
value.DeviceType
]).draw();
});
},
error: function (result) {
console.log("error");
}
});
});
</script>
Also, it is important to return a json object from the controller action.
PS. If the Json Object has an initial tag like data, you may need to change the looping value.Id to value.data.Id. But it is better to not use any tag.
public JsonResult GetDeviceDataTypes(string slctDeviceList)
{
ChartRepository repository = new ChartRepository();
System.Data.DataTable dt = repository.GetDataTypes(slctDeviceList);
JsonSerializerSettings _jsonSetting = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore };
var json = this.Json(dt , _jsonSetting);
return json;
}

asp.net mvc 4 - linq Contains operator is working as if it were a StartsWith operator

controller:
[HttpPost]
public JsonResult Index(string search)
{
var data = LoadExplore_SP("sp_View_Explore");
List<ExploreModel> stuff = new List<ExploreModel>();
foreach (var row in data)
{
stuff.Add(new ExploreModel
{
Thing_Title = row.Thing_Title
});
}
//Searching records from list using LINQ query
var ThingList = (from N in stuff
where N.Thing_Title.Contains(search)
select new { N.Thing_Title });
return Json(ThingList, JsonRequestBehavior.AllowGet);
}
view:
<script type="text/javascript">
$(document).ready(function () {
$("#Thing_Title").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Home/Index",
type: "POST",
dataType: "json",
data: { search: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Thing_Title, value: item.Thing_Title };
}))
}
})
},
messages: {
noResults: "", results: ""
}
});
})
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="form-group">
<div class="col-md-12">
#Html.EditorFor(model => model.Thing_Title, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
}
My problem is that I can't get the linq where clause to work the way it should. Instead of returning results like %search%, it is returning all records like 'search%' instead.
Do you know why it's behaving this way?

Autocomplete does not appear in view, ASP.NET MVC

I have one field in my view, it is a textbox field. But I'd like to change that field to an Autocomplete dropdown.
Below is my view:
#Html.TextBoxFor(model => model.SearchFilterPaymentCode, new { #class = "form-control", #id = "searchInput1" })
#Html.HiddenFor(model => model.ID)
<script>
$(document).ready(function () {
$("#searchInput1").autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("getJenisPembayaran", "Payment1")',
dataType: "json",
data: {
term: request.term
},
success: function (data) {
response($.map(data, function (val, item) {
return {
label: val.Name,
value: val.Name,
ID: val.ID
}
}))
}
})
},
select: function (event, ui) {
$("#ID").val(ui.item.ID);
$("#SearchFilterPaymentCode").val(ui.item.label);
}
});
})
</script>
and below is my controller
public JsonResult getJenisPembayaran(string term)
{
var objCustomerlist = db.ParamJenisPembayarans.Where(x => x.Name.ToUpper()
.Contains(term.ToUpper()))
.Select(x => new ParamJenisPembayaranViewModel
{
ID = x.ID,
JenisPembayaran = x.Name
}).Distinct().ToList();
return Json(objCustomerlist, JsonRequestBehavior.AllowGet);
}
When I debug the controller and fill the textbox with a few words, I get some data from the database, that means the controller is working well but the data does not appear in the view. What's wrong with my code?

under HTML table Autocomplete for HtmlEditor Control

I have a Html table having multiple rows with one drop down and one textbox control.
I want auto complete function for that text box.I implemented the following code for auto complete but it is firing for only first row.The rows are added Dynamically (in jquery) its not workig for those rows.
CODE:
<table class="table table-bordered table-hover datatable-highlight" id="tWDE_Items">
<thead>
<tr>
<th style="display:none">ItemId</th>
<th>Item Name</th>
<th>UOM</th>
</tr>
</thead>
<tbody>
#foreach (var Item in Model.Data_Wde_ItemGrid)
{
<tr class="datarow">
<td style="display:none">#Item.Item_Id</td>
<td>#Html.EditorFor(m => Item.Item_Name, new { htmlAttributes = new { #class = "form-control" } }) </td>
<td>#Html.DropDownListFor(m => Item.UOM_Id, new SelectList(Item.UOMDetails, "UomId", "UomName"), htmlAttributes: new { #class = "form-control", id = "UomId" })</td>
</tr>
}
</tbody>
</table>
Java Script :
$('#Item_Item_Name').autocomplete({
source: function (request, response) {
debugger;
var param = { ItemName: $('#Item_Item_Name').val() };
$.ajax({
url: "/WDE/GetAutoCompleteItemList",
data: JSON.stringify(param),
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
val: item.split('÷')[0],
label: item.split('÷')[1]
}
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
change: function (e, i) {
if (i.item) {
}
else {
$('#Item_Item_Name').val('');
$('#Item_Item_Id').val('');
}
},
select: function (e, i) {
debugger;
$('#Item_Item_Name').val(i.item.label);
$(this).closest("tr").find("td").eq(2).html(i.item.val);
},
minLength: 1
});
Your autocomplete() call works only on the elements that are in the dom the time you call it. So for dynamically added elements you'll need the call the function again (after the new row was added).
One more thing to notice is that any call using the element id ($('#Item_Item_Name')) will work only for the first element with that id, because ids are meant to be unique. So you'll need to change the selector to get the input from the new row.
Create a function that inits the autocomplete And after every row you add, call that function on the element you want.
function initAutoComplete(elem) {
$(elem).autocomplete({ /* the same as you use now */ });
}
// after you addded the new row
initAutoComplete($(newRow).find('.autocopmlete-input'));

Add child row as nested datatable within exisiting datatable

I have a datatable that lists a number of 'stages' (which relate to work employment procedures being carried out against the individual employee).
I have managed to code this so the table can display child rows. I want each child row to display another datatable which will list associated tasks for the selected stage.
So far I have managed to add and display a child row with the table header. See here:
[Child Row][1]
My HTML is as follows:
<div class="table-responsive">
<table class="table table-hover " id="stage_datatable">
<thead>
<tr>
<th>Select</th>
<th><!-- Detail --></th>
<th>ID</th>
<th>Stage</th>
<th>Title</th>
<th>Desc</th>
<th>Date/Time</th>
<th>Location</th>
<th>Rep Required</th>
<th>Logged By</th>
<th>Date Logged</th>
</tr>
</thead>
</table>
The Jquery for my stage table is here:
function loadStageTable (action, id) {
$.ajax ( {
url: './stages/stage_ajax.php',
method: 'GET',
data: {action: action, id:id}, // id could be taskID or caseID
dataType: 'json',
success: function (data) {
console.log(data);
console.log("success");
iTableCounter = 0;
var table = $('#stage_datatable').DataTable ( {
"searching": false,
"sort": false,
data:data,
select: {
style: 'os'
},
responsive: true,
columns: [
{ 'data': null },
{
"data": null,
"className": 'details-control',
"orderable": false,
"defaultContent": ''
},
{ 'data': 'meeting_id' },
{ 'data': 'stage_desc' },
{ 'data': 'meeting_title' },
{ 'data': 'meeting_desc' },
{ 'data': 'meeting_date_time' },
{ 'data': 'meeting_location' },
{ 'data': 'rep_required' },
{ 'data': 'logged_by' },
{ 'data': 'start_date' }
],
"columnDefs": [ {
"targets": -11,
"data": null,
"defaultContent": "<button class='btn btn-xs btn-primary'>Select</button>"
},
{
"targets": -3,
"className": "dt-body-center",
"render": function (data, type, full, meta){
var is_checked = data == true ? "checked" : "";
return '<input type="checkbox" class="checkbox" ' + is_checked + ' disabled />';
}
}]
});
console.log("stage datatable processed");
$('#stage_datatable tbody').on('click', 'td.details-control', function () {
var tr = $(this).parents('tr');
    var row = table.row( tr );
    if ( row.child.isShown() ) { // Close this row if already open
$('div.slider', row.child()).slideUp( function () {
row.child.hide();
tr.removeClass('shown');
} );
    }else {
// table id is required for child rows and will be unique
iTableCounter = iTableCounter + 1
row.child(getChildRow).show(); // call getChildRow function to obtain the child row html
var caseID = localStorage.getItem('caseID');
console.log(caseID);
loadMyTaskTable('get case tasks', caseID); // this is the AJAX function invoked to retrieve tasks. THIS DOESN'T WORK
tr.addClass('shown');
$('div.slider', row.child()).slideDown("slow");
    }
});
},
failure: function (data) {
console.log ("failed");
}
});
In the above I have coded an event that triggers the child row to be inserted:
$('#stage_datatable tbody').on('click', 'td.details-control', function () {
var tr = $(this).parents('tr');
var row = table.row( tr );
if ( row.child.isShown() ) { // Close this row if already open
$('div.slider', row.child()).slideUp( function () {
row.child.hide();
tr.removeClass('shown');
} );
}else {
// table id is required for child rows and will be unique
iTableCounter = iTableCounter + 1
row.child(getChildRow).show(); // call getChildRow function to obtain the child row html
var caseID = localStorage.getItem('caseID');
console.log(caseID);
loadMyTaskTable('get case tasks', caseID); // this is the AJAX function invoked to retrieve tasks
tr.addClass('shown');
$('div.slider', row.child()).slideDown("slow");
}
});
The getChildRow is as follows:
function getChildRow() {
var x = innerTaskTableTemplate(iTableCounter, taskTableTemplate());
return x;
}
The taskTableTemplate parameter is as follows:
function taskTableTemplate() {
return '<thead>'+
'<tr>'+
'<th>Select</th>'+
'<th>ID</th>'+
'<th>Task Title</th>'+
'<th>Desc</th>'+
'<th>Due Date/Time</th>'+
'<th>Allocated To</th>'+
'<th>Logged By</th>'+
'<th>Date Logged</th>'+
'</tr>'+
'</thead>'+
'<tbody></tbody>';
}
And the innerTaskTableTemplate function is as follows:
function innerTaskTableTemplate(tableID, html) {
var sOut = "<div class='slider'><table id='task_table_" + tableID + "'>";
sOut += html;
sOut += "</table></div>";
console.log(sOut);
return sOut;
}
IF I OMIT THIS LINE from my **loadStageTable ** function then the code successfully adds a child row and inserts the table html.
loadMyTaskTable('get case tasks', caseID);
However, if I include the line then the child row seems to disappear. If I inspect the DOM using firebug I can't find my child row (e.g. 'task_table_1'). See [here][2].
The loadMyTaskTable function is as follows:
function loadMyTaskTable (action, id) {
$.ajax ( {
url: './tasks/task_ajax.php',
method: 'GET',
data: {action: action, id:id}, // id could be taskID or caseID
dataType: 'json',
success: function (data) {
console.log(data);
var taskTable = $('#task_table_1')
$(taskTable).DataTable ( {
data:data,
select: {
style: 'os'
},
responsive: true,
columns: [
{ 'data': null },
{ 'data': 'task_id' },
{ 'data': 'task_title' },
{ 'data': 'task_desc' },
{ 'data': 'task_due_date' },
{ 'data': 'allocated_to' },
{ 'data': 'logged_by' },
{ 'data': 'start_date' }
],
"columnDefs": [ {
"targets": -8,
"data": null,
"defaultContent": "<button class='btn btn-xs btn-primary'>Select</button>"
}]
});
console.log("task table successfully loaded");
},
failure: function (data) {
console.log ("failed");
}
});
}
Please can you let me know where I am going wrong. i am confident that my AJAX is working fine as I've tried adding the task table html onto the main page and it loads properly this way, but not when I dynamically insert it as a child row in my datatable.
I have tried looking at similar other posts (e.g. [click here][3]) but I think that the code has since been superseded by the datatables new API.
Many thanks.
Additional Detail
I have debugged the script and found the following:
The script successfully inserts the child row with the task_table_1 html
The child row is subsequently removed from the DOM once it hits the *console.log("task table successfully loaded"); * line in my loadMyTaskTable function.
Am still not sure what I am doing wrong here.

Categories