DataTable Server-side processing ajax error - asp.net

I have a form/page in which do a search. That action returns datatabel type (this is a requirement) then the results I have to show in jquery datatable and the processing has to be done server-side.
I read the documentation and got some examples but I can't get it work.
$(document).ready(function () {
var table = $("#searchResultTable").DataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": "Report/CustomServerSideAction",
"type": "POST"
},
"columns":[
{"data": "ID"},
{"data": "Name"},
{"data": "Active"},
{"data": "OrderBy"},
{"data": "StoredProcedure"},
{"data": "SSRSFileName"},
{"data": "SSESStoredProcedure"}
]
//buttons: [
// "csv", "excel", "pdf", "print"
//]
});
});
#using System.Data
#model System.Data.DataTable
<div class="col-sm-12">
<div class="card-box table-responsive">
<table id="searchResultTable" class="testClass table table-striped table-colored table-teal">
<thead>
<tr>
#foreach (DataColumn col in Model.Columns)
{
<th>#col.ColumnName</th>
}
</tr>
</thead>
<tbody>
#foreach (DataRow item in Model.Rows)
{
<tr>
#foreach (DataColumn col in Model.Columns)
{
switch (col.DataType.ToString())
{
case "System.Decimal":
<td class="pull-right">#Convert.ToDecimal(item[col].ToString())</td>
break;
default:
<td>#item[col].ToString()</td>
break;
}
}
</tr>
}
</tbody>
</table>
</div>
</div>
[HttpPost]
public ActionResult CustomServerSideAction()
{
var table = Models.SearchResult.Results;
return Json(new { draw = 100, totalRecors = 30, dislayRecord = 10, data = table }, JsonRequestBehavior.AllowGet);
}
public static class SearchResult
{
public static DataTable Results { get; set; }
}
This gives an error
DataTables warning: table id=searchResultTable - Ajax error. For more
information about this error, please see http://datatables.net/tn/7

Related

ASP.NET Core View - creating dropdown filter for single column

I have ASP.NET CORE app.
In one of my views I have Status column among others which can have 2 possible values: Active or Deactivated.
How can I create filter on that column with simple drop-list that would allow me to filter whole table based on these 2 column values?
All I can find are lengthy tutorials that are not quite covering what I need.
Basically I need someone to give me few links or points me on how to implement this in most simple way.
EDIT
column definition in Model:
[Column(TypeName = "BIT")]
[Display(Name = "Status")]
public bool Status { get; set; }
So in my Index View I have:
<th>
#Html.DisplayNameFor(model => model.Status)
</th>
....
<td>
#(item.Status ? "Active" : "Deactivated")
</td>
How can I turn that header title into title with drop-down list?
Something like this:
Obviously in my case instead of "Company Name" column name would be "Status" and in drop-down values I would have only 2 items - "Active" and "Deactivated".
I made a test based on your needs, below is a working demo:
View:
#model IEnumerable<Product>
#{
List<SelectListItem> listItems = new List<SelectListItem>();
listItems.Add(new SelectListItem
{
Text = "Active",
Value = "Active"
});
listItems.Add(new SelectListItem
{
Text = "Deactivated",
Value = "Deactivated"
});
}
<table id="mytable" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0">
<thead>
<tr>
<td>
#Html.DisplayNameFor(model => model.Id)
</td>
<td>
#Html.DisplayNameFor(model => model.Name)
</td>
<td>
#Html.DropDownList("Status", listItems, "Status")
</td>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#(item.Status ? "Active" : "Deactivated")
</td>
</tr>
}
</tbody>
</table>
#section scripts{
<script>
$("#Status").on('change', function () {
var val = $("#Status option:selected").text();
$.ajax({
type: 'get',
url: '/Home/FilterByStatus',
data: { status: val },
success: function (result) {
$("#mytable tbody").empty();
$.each(result, function (i, value) {
$("#mytable tbody").append("<tr><td>" + value.id + "</td><td>" +
value.name + "</td><td>" + (value.status ? "Active" : "Deactivated") +"</td></tr>")
})
}
})
})
</script>
}
Controller:
public static List<Product> products = new List<Product>
{
new Product{ Id = 1, Name = "AA", Status = true},
new Product{ Id = 2, Name = "BB", Status = true},
new Product{ Id = 3, Name = "CC", Status = false},
new Product{ Id = 4, Name = "DD", Status = false}
};
public IActionResult Index()
{
return View(products);
}
public IActionResult FilterByStatus(string status)
{
var filterproducts = products.ToList();
if (status == "Active")
{
filterproducts = products.Where(p => p.Status == true).ToList();
return Json(filterproducts);
}
else if(status == "Deactivated")
{
filterproducts = products.Where(p => p.Status == false).ToList();
return Json(filterproducts);
}
return Json(filterproducts);
}
Result:

Symfony 4 x-editable - update

My mission is to use the x-editable library for bootstrap in Symfony 4.
After clicking on the field in the table appears "input" and the value from the field inside. I have a problem to make an update to the database. In the code below I am doing an update to the database with a fixed value of "Koralik". I would like the update with the value from "input" to go to the base.
<table id="tab1" class="table table-bordered table-striped table-hover">
<thead style="color:blue;">
<tr><th>ImiÄ™</th><th>Nazwisko</th></tr>
</thead>
<tbody id="myTable">
{%for kierowca_one in kierowca%}
<tr class="text-success">
<td>{{kierowca_one.Imie}}</td>
<td><span class="myElement" data-type="text" data-pk="
{{kierowca_one.id}}" data-url="{{path('app_update',
{id:kierowca_one.id})}}">{{kierowca_one.Nazwisko}}</span> </td>
</tr>
{%endfor%}
</tboody>
</table>
$('.myElement').editable({
type: "POST",
emptytext: 'Brak',
showbuttons: false,
mode: 'inline',
//dataType: 'json',
validate: function(value){
if($.trim(value) == '')
{
return 'This field is required';
}
}
});
/**
* #Route("/update/{id}", name="app_update", methods={"GET"})
* #IsGranted("ROLE_USER")
*/
public function updateMethod(EntityManagerInterface $em, $id)
{
$repository=$em->getRepository(Kierowcy::class);
$kierowca=$repository->find($id);
$kierowca->setNazwisko('Kowalik');
$em->persist($kierowca);
$em->flush();
return new Response();
}
here is my approach.
js file
$('#s').editable({
selector: '.js-editable',
url: urlUpdateTopic,
params:function(params){
params.pk = $(this).closest('tr').data('id');
return params;
},
success: function(value, response) {
if(response){
$(this).html(value);
}
},
error: function(response) {
if(response.status === 500) {
console.log('Service unavailable. Please try later.');
} else {
console.log(response.responseText);
}
},
type: 'text',
pk: 1,
mode: 'inline',
showbuttons: false,
toggle: 'dblclick',
onblur: "submit",
clear: false,
emptytext: ''
});
here is controller
public function updateTopicAction(Request $request)
{
$id = $request->request->get('pk');
$value = $request->request->get('value');
}
also you can see a good example here Submitting data via Ajax in X-Editable

Dynamically add/remove table rows in a wizard

I'm currently using this Wizard in my application.
In one of my steps, I need to add and remove items from a table. Add functions works fine. But I can't make the Delete function work. I've searched SO and other resources online, can't find a solution.
This is what I've so far:
Wizard Step 2 Table:
<table id="LibList" class="table table-responsive table-striped">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Step3.Liabilities[0].Types)
</th>
<th>
#Html.DisplayNameFor(model => model.Step3.Liabilities[0].Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Step3.Liabilities[0].Teams)
</th>
<th>
<label>Delete</label>
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Step3.Liabilities) {
Html.RenderPartial("_LibListItem", item);
}
</tbody>
</table>
Partial View:
<tr>
<td>
#Html.DropDownListFor(model => model.Type, Model.Types, new { #class = "selectpicker form-control", id = string.Format("{0}_{1}", "TYPE", Model.ID) })
</td>
<td>
#Html.TextBoxFor(model => model.Name, new { #class = "form-control", id = string.Format("{0}_{1}", "NAME", Model.ID) })
</td>
<td>
#Html.TextBoxFor(model => model.Teams, new { #class = "form-control", #type = "currency", id = string.Format("{0}_{1}", "TERMS", Model.ID) })
</td>
<td>
#Ajax.ActionLink("Delete", "Delete", "QuestionWizard", new { id = Model.ID },
new AjaxOptions() {
HttpMethod = "Delete",
Confirm = "Are you sure you want to delete this record?",
OnComplete = "function() { $(this).parent().parent().remove() }"
},
new { #class = "btn btn-primary" })
</td>
Add and Delete Action:
public ActionResult AddRow() {
LiabilityModel lib = new LiabilityModel();
try {
if (LiabilitySessionState.Count == 0) {
lib.ID = 1;
} else {
lib.ID = LiabilitySessionState.LastOrDefault().ID + 1;
}
LiabilitySessionState.Add(lib);
return PartialView("_LibListItem", lib);
} catch (Exception ex) {
System.Web.HttpContext.Current.Application.Add("LASTERROR", ex);
return RedirectToAction("Index", "Error");
}
}
public void Delete(int Id) {
try {
if (LiabilitySessionState.Count > 0) {
LiabilitySessionState.RemoveAll(item => item.ID == Id);
}
} catch (Exception ex) {
System.Web.HttpContext.Current.Application.Add("LASTERROR", ex);
RedirectToAction("Index", "Error");
}
}
public List<LiabilityModel> LiabilitySessionState {
get {
if (Session["LiabilityModel"] == null) {
return LiabilitySessionState = new List<LiabilityModel>();
} else {
return Session["LiabilityModel"] as List<LiabilityModel>;
}
}
set {
Session["LiabilityModel"] = value;
}
}
Script:
<script type="text/javascript">
$(document).ready(function () {
$('.add-button').click(function () {
var action = "/QuestionWizard/AddRow";
$.ajax({
url: action,
cache: false,
success: function (result) {
$("#LibList tbody").append($(result));
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
})
$(".remove-button").click(function () {
$(this).parents().parent().remove();
return false;
});
});
Right now, the Delete Action returns a blank page, because I'm not returning a view. But, I'm not sure what view to return.
Please help!
Thanks in advance.
Firstly your Delete() method is changing data so it needs to be a POST, not a GET (which #Ajax.ActionLink() is). Next, your 'delete link' does not have class="remove-button" so $(".remove-button").click(function () { wont do anything. Since you already using jquery ajax methods to add items (refer notes below), there seems no point using the Ajax helpers anyway (your just adding extra overhead by loading the jquery.unobtrusive-ajax.js file).
Change the last <td> element of the partial to
<td>
<button type="button" class="remove-button" data-id=#Model.ID>Delete</button>
</td>
Then in the main view, use the following script (note you need event delegation so you can remove dynamically added items)
var url = '#Url.Action("Delete", "YourControllerName")';
$('#LibList').on('click', .remove-button, function() {
var row = $(this).closest('tr');
var id = $(this).data('ID');
if (id) { // assumes property ID is nullable, otherwise may need to test if id != 0
$.post(url, {ID: id }, function(response) {
if(response) {
row.remove();
} else {
// Oops - display message?
}
});
} else {
// its a new row so it has not been saved yet - just delete the row
row.remove();
}
});
and the controller method should look like
[HttpPost]
public JsonResult Delete(int ID)
{
// delete the item
return Json(true); // or if an exception occurred, return(null) to indicate failure
}
Side notes:
Both your AddRow() and Delete() methods include a return
RedirectToAction() statement. You are making ajax calls which stay
on the same page so RedirectToAction() is pointless (it will never
be executed)
If you believe the "Add functions works fine", then you must have
some unnecessary hacks in order to make this work (your generating
duplicate name attributes for the controls (without indexers)
which will not bind to your collection of Liabilities). You need
to generate existing items in a for loop and include a hidden
input for an Index property, and use a client side template to
generate new items; or you need to use the BeginCollectionItem
helper if using a partial view. This
answer
shows how to use both techniques.
You don't appear (and you should not need) to access the id
attributes of the controls in your table. Instead of using id = string.Format("{0}_{1}", "NAME", Model.ID), just use id="" which
will render the element without and id attribute.

How to fetch data from parse.com and render it to table using AngularJs

I am trying to fetch data stored in parse.com collection. I am using Parse Javascript SDK to call the service asynchronously as following:
ctrl.factory('TLDs', function($q){
var query = new Parse.Query(Fahras)// Fahras is the Parse Object initialized earlier in code
query.equalTo("type", "Domain")
var myCollection = query.collection()
return {
fetchDomains: function(){
var defer = $q.defer();
myCollection.fetch({
success : function(results) {
defer.resolve(results.modles);
console.info(results.models)
},
error : function(aError) {
defer.reject(aError);
}
});
console.info(defer.promise)
return defer.promise;
}
}
}) // end of factory topDomains
I have a simple table to show the fetched data
<div id="showdomainshere"> {{domains}}</div>
<table id="domains_table" class="table table-hover">
<thead>
<tr>
<th>Domain</th>
<th>Code</th>
<th>Subjects</th>
<th>Instances</th>
</tr>
</thead>
<tbody id="table_body">
<form id="edit_row" class="form-inline">
<tr ng-repeat="item in domains">
<td><span>{{item.attributes.arTitle}}</span>
</td>
<td><span>{{item.attributes.domainCode}}</span>
</td>
<td><span>{{subclasses}}</span>
</td>
<td><span>{{instances}}</span>
</td>
</tr>
</form>
</tbody>
</table>
</div> <!-- end of main div -->
And hereunder the controller I ma using to render the view:
ctrl.controller('Home', ['$scope','TLDs',function($scope, TLDs) {
$scope.domains = TLDs.fetchDomains()
}])
Using console.info I can see that the result is fetched and I can go through the array of returned models as expected. Problem is that $scope.domains never been updated and as a result the table never been rendered
Fortunately I am able to figure it out.
The controller should be like:
ctrl.controller('Home', ['$scope','TLDs',function($scope, TLDs) {
TLDs.fetchDomains().then(function(data){
$scope.domains = data
})
}
While the factory itself should be like:
ctrl.factory('TLDs', function($q){
var query = new Parse.Query(Fahras)
query.equalTo("type", "Domain")
var myCollection = query.collection()
return {
fetchDomains: function(){
var defer = $q.defer();
myCollection.fetch({
success : function(results) {
defer.resolve(results.models)
return results.models
},
error : function(aError) {
defer.reject(aError)
}
})
return defer.promise;
}
} }) // end of factory

Table sorting causing duplication in meteor

In my meteor app I have a table of data with sorting for each coloumn. When I keep on clicking the coloumn for sorting, the table itself is getting multiplied.
This is the code for setting session variables.
'click #coloumn_name' : function()
{
var oldOrder = Session.get("sortOrder");
var sortField = 'coloumn1';
Session.set("sortField",sortField );
if(oldOrder == 1)
{
var newOrder = -1;
Session.set("sortOrder",newOrder );
}
else
{
var newOrder = 1;
Session.set("sortOrder",newOrder );
}
}
Here is the code for reading the session variables and fetching data from db.
Template.templatename.vname = function()
{
var filter = {sort: {}};
var sortField = Session.get('sortField');
var sortOrder = Session.get('sortOrder');
if(!sortField)
{
sortField = 'coloumn2';
}
if(!sortOrder)
{
sortOrder = 1;
}
filter.sort[sortField] = sortOrder;
return Groups.find({}, filter);
}
Here is my template
<template name="templatename">
<table>
<tr>
<th>Group Name</th>
<th>Status</th>
</tr>
{{#each vname }}
<tr>
<td> {{name}} </td>
<td> {{status}} </td>
</tr>
{{/each}}
</table>
</template>
This is the table before trying to sort.
This is the image after trying to sort
Does anyone have any idea why this happens ?

Resources