How to allow models with belongsToMany relationship to be searchable using datatables? - javascript

I have the following model that has a belongsToMany relationship:
class Sale extends Model
{
public function items()
{
return $this->belongsToMany(Item::class)->select(
[DB::raw("COUNT(*) as quantity"),
DB::raw("CONCAT('(', GROUP_CONCAT(serial_number SEPARATOR ', '), ')') AS serial_number"),
'items.name',
'items.upc',
'items.id',
'items.with_serial_number',
'items.selling_price',
'item_sale.sold_price',
'item_sale.item_purchase_id'])
->join('item_purchase', 'item_sale.item_purchase_id', '=', 'item_purchase.id')
->orderBy('item_sale.id', 'ASC')
->groupBy('item_sale.item_id', 'item_sale.sale_id');
}
and on my controller
public function demo(Request $request)
{
if ($request->ajax()) {
$data = Sale::with(['branch', 'items', 'customer', 'user'])->select(['*']);
return Datatables::of($data)
->addIndexColumn()
->make(true);
}
}
and on my jquery
$('#search_sale_list').DataTable({
"processing": true,
"serverSide": true,
"ajax": "{{ route('rma.demo') }}",
"columns": [
{data: 'created_at'},
{data: 'branch.address'},
{data: 'sale_number'},
{data: 'items'}
]
});
My problem is i cant seem to search for the 'items' in my view when i use the searchbox of datatables, it gives out an error. is this even possible to do using datatables?

Related

Ajax datatables.net table will not load

v1.10 Datatables.net table will not load using ajax - examples at datatables.net did not help, nor did the documentation. The table displays, but says "No data available in table". I don't think it matters, but this is for an old MVC5 app that I'm doing a little maintenance on. I'm hoping someone can spot what's wrong?
HTML Table definition:
<table id="bob">
<thead>
<tr>
<th>License Type</th>
<th>Active</th>
<th>Pending</th>
<th>Other</th>
</tr>
</thead>
<tfoot>
<tr>
<th>License Type</th>
<th>Active</th>
<th>Pending</th>
<th>Other</th>
</tr>
</tfoot>
</table>
JavaScript Init:
$(function () {
var url = '#Url.Action("LicenseCountsReport", "Letters")';
$('#bob').DataTable({
ajax: {
dataSrc: '',
url: url,
columns: [
{ data: 'licensetype' },
{ data: 'activecount' },
{ data: 'pendingcount' },
{ data: 'othercount' }
]
}
});
});
Data Method & Associated Classes:
public class LicenseCountReportItem
{
public string licensetype { get; set; }
public string activecount { get; set; }
public string pendingcount { get; set; }
public string othercount { get; set; }
}
private class JsonDataResult
{
public List<LicenseCountReportItem> data { get; set; }
}
[HttpGet]
public JsonResult LicenseCountsReport()
{
JsonDataResult reportData = new JsonDataResult
{
data = new List<LicenseCountReportItem>()
};
try
{
List<LicenseCountReportItem> items = _lr.GetLicenseCountsReport();
if (items != null && items.Count > 0)
{
reportData = new JsonDataResult
{
data = items
};
return Json(reportData, JsonRequestBehavior.AllowGet);
}
return Json(reportData, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
Logger.Log(ex, LogLevel.ERROR);
return Json(reportData, JsonRequestBehavior.AllowGet);
}
}
JSON Response (formatted), an array of objects:
{
"data":[
{
"licensetype":"Commercial Apprentice Applicators",
"activecount":"130",
"pendingcount":"22",
"othercount":"99"
},
{
"licensetype":"Professional Applicators",
"activecount":"4239",
"pendingcount":"3314",
"othercount":"55147"
}
]
}
There are 2 problems I can see:
1 - The first problem: You have used the DataTables ajax option: dataSrc: ''. Instead, you should remove this option (or use its default value of data, as follows: dataSrc: 'data').
If you use dataSrc: '', you are telling DataTables that your JSON is an unnamed array - something like this:
[
{
"licensetype": "Commercial Apprentice Applicators",
"activecount": "130",
"pendingcount": "22",
"othercount": "99"
},
{
"licensetype": "Professional Applicators",
"activecount": "4239",
"pendingcount": "3314",
"othercount": "55147"
}
]
But that is not how your JSON is structured. Your array is nested inside a JSON object: { "data": [ ... ] }.
2 - The second problem: You have placed your columns option inside the ajax option. But the columns option needs to be at the same level as the ajax option:
$('#bob').DataTable({
ajax: {
url: url,
},
columns: [
{ data: 'licensetype' },
{ data: 'activecount' },
{ data: 'pendingcount' },
{ data: 'othercount' }
]
});
The columns option is independent of the ajax option.

Global Search not working with laravel

Hi guys im trying to get an specific search for my proyect but it doesnt want to work, I'm using relationships this is my code
Php:
public function todos_productos($empresa_id, Request $request)
{
$empresa = Empresa::find($empresa_id);
$productos = $empresa->productos()->with('producto_nombre', 'producto_nombre.seccion', 'producto_nombre.linea');
return Datatables::of($productos)
->filter(function ($query) use ($request) {
if ($request->has('codigo')) {
$query->where('producto_nombre.codigo', 'like', "%{$request->get('codigo')}%");
}
})
->make(true);
}
My js
$(document).ready(function () {
empresa = $('#empresa_id').val()
tablaBusqueda = $('#postTable').DataTable({
processing: true,
serverSide: true,
ajax: {
url: 'api/productos/todos/' + empresa,
data: function (d) {
d.codigo = $('input[name=consulta_producto_codigo]').val()
d.linea = $('select[name=consulta_producto_linea]').val()
d.seccion = $('select[name=consulta_producto_seccion]').val()
}
},
columns: [
{data: 'codigo', name: 'producto_nombre.codigo'},
{data: 'descripcion', name: 'producto_nombre.descripcion'},
{data: 'existencias', name: 'existencias'},
{data: 'precio', name: 'precio'},
{data: 'stock_minimo', name: 'stock_minimo'},
{data: 'stock_maximo', name: 'stock_maximo'},
{data: 'producto_nombre.linea.nombre', name: 'producto_nombre.linea.nombre'},
{data: 'producto_nombre.seccion.nombre', name: 'producto_nombre.seccion.nombre'}
],
'language':
{
'url':
'../plugins/dataTables.spanish.lang'
}
})
})
The problem is that when im trying to search by codigo(code) it says that there isn't the column producto_nombre.codigo, I've replaced it with only codigo but also not working, anyone know why?
$empresa is a single Empresa model instance.
$productos is an Eloquent collection of (assuming) Producto models with the two eager loaded relationships producto_nombre and producto_nombre.seccion. Any queries will there will be run on the (assuming) productos table instead of your relationship table.
Here's how to constrain eager loads: https://laravel.com/docs/5.6/eloquent-relationships#constraining-eager-loads

class properties to jquery datatables asp.net MVC

After seeing a lot of code samples, I cant make a simple datatable using Jquery Datatables and MVC.
I got the error
My controller is this
public class DataTableController : Controller
{
// GET: DataTable
public ActionResult Index()
{
return View();
}
public ActionResult GetData()
{
var registros = new List<PruebaClass>();
var pruebaClass1 = new PruebaClass
{
Race = "Aliens",
Year = 1990,
Total = 50
};
var pruebaClass2 = new PruebaClass
{
Race = "MArcianos",
Year = 200,
Total = 20
};
registros.Add(pruebaClass1);
registros.Add(pruebaClass2);
var resultado = Json(new { aaData = registros.ToList() }, JsonRequestBehavior.AllowGet);
return resultado;
}
public class PruebaClass
{
public string Race { get; set; }
public int Year { get; set; }
public int Total { get; set; }
}
}
My view is this
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<table id="miTable">
<thead>
<tr>
<th>Race</th>
<th>Year</th>
<th>Total</th>
</tr>
</thead>
</table>
#section Scripts{
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables_themeroller.css">
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="~/Scripts/MyDataTablejs.js"></script>
}
And my javascript file is this
$(document).ready(function () {
$('#miTable').DataTable(
{
"sAjaxSource": "../DataTable/GetData",
"columns": [
{ "Data": "Race", "autoWidth": true },
{ "Data": "Year", "autoWidth": true },
{ "Data": "Total", "autoWidth": true }
]
});
});
I can reach the ActionResult, and my view shows two rows but the content of each cell is null. And I got the awfull error Datatables warning (table id= 'miTable')Requested unknown parameter '0' from the datasource '0' .
Im pretty sure that the problem is the source (maybe the JSON format) and the column name mapping, but I cant figure out what is.
Any help?
Shame on me. Finally I matched the columns definition with apropiate options in the jquery file. I knew that I was missing something. All I need to do was to use the "aocolumns" and "mDataProp"
this code solves all
$(document).ready(function () {
$('#miTable').DataTable(
{
"sAjaxSource": "../DataTable/GetData",
"aoColumns": [
{ "mDataProp": "Race", "autoWidth": true },
{ "mDataProp": "Year", "autoWidth": true },
{ "mDataProp": "Total", "autoWidth": true }
]
});
});

Kendo UI KendoTreeView HierarchicalDataSource not showing nodes

My Kendo UI TreeView is not getting the returned JSON objects added to the treeview.
I can see from the controller method that gets called that the Json being given to the DataSource looks like this (but with more files and folders)
{"NodeID":-842352767,
"Name":"/",
"Folders":[{"NodeID":1804712307,"Name":"/$Recycle.Bin","Folders":null,"Files":null},{"NodeID":-582712839,"Name":"/Windows","Folders":null,"Files":null}],
"Files":["/.rnd","/msdia80.dll"]}
My view is as follows:
#model ProjName.Models.BrowseNode
<div id ="wrapper">
<h1>Browser</h1>
<div id="treeview" style="float:left;margin: 40px;">
</div>
</div>
<script>
function populateTreeView() {
var remoteDataSource = new kendo.data.HierarchicalDataSource({
type: "json",
transport: {
read: "FileBrowser/GetHierarchy"
},
schema: {
model: {
id: "NodeID",
text: "Name",
expanded: false,
children: "Folders",
},
}
});
$("#treeview").kendoTreeView({
dataSource: remoteDataSource,
dataTextField: "Name"
});
}
$(document).ready(function () {
populateTreeView();
});
With BrowseNode defined as:
public class BrowseNode
{
public int NodeID {
get
{
if (null == Name)
return default(int);
return Name.GetHashCode();
}
}
public string Name { get; set; }
public List<BrowseNode> Folders { get; set; }
public List<string> Files { get; set; }
}
Anything obviously wrong or any tips for debugging this sort of thing?
It turned out my JSON wasn't what the DataSource wanted. It should have been an array returned at the top level, so the JSON is surrounded by [ ] brackets as follows:
[{"NodeID":-842352767, "Name":"/", "Folders":[{"NodeID":1804712307,"Name":"/$Recycle.Bin","Folders":null,"Files":null},{"NodeID":-582712839,"Name":"/Windows","Folders":null,"Files":null}], "Files":["/.rnd","/msdia80.dll"]}]

How to get the row ID from a Kendo Grid with a double click

I'm currently testing the Kendo UI MVC Extensions Beta.
I'm trying to implement a double click - edit but I don't know how I can get the rowId.
JavaScript:
$('#GridPedidos table tr').live('dblclick', function () {
alert(' grid dbl clicked');
});
View:
#(Html.Kendo().Grid(Model) _
.Name("GridPedidos") _
.Columns(Sub(column)
column.Bound(Function(item) item.idPedidoDocumentacao).Width("5%")
column.Bound(Function(item) item.descEstadoPedidoDoc).Width("25%")
column.Bound(Function(item) item.descTipoPedidoDoc).Width("25%")
column.Bound(Function(item) item.data).Width("25%").Format("{0:dd-MM-yyyy}")
column.Command(Function(item) item.Destroy()).Width("10%")
End Sub) _
.DataSource(Sub(ds)
ds.Ajax().ServerOperation(False).Read(Sub(s)
s.Action("GetListaGrid", "listaPedidos")
End Sub).Create(Sub(s)
s.Action("detalhePedido", "Pedidos")
End Sub).Model(Sub(m)
m.Id(Function(p) p.idPedidoDocumentacao)
End Sub).Destroy(Sub(d)
d.Action("apagaPedido", "listaPedidos")
End Sub)
End Sub) _
.Selectable()
)
I can detect the double click with this function, but how do I get the id?
I've done this example with client side api and an equivalent with the MVC extensions.
Create a grid div, to create a grid at run time.
<div id="grid" style="width: 400px;"></div>
Created a row template so that I could give the element an id tag.
<script id="rowTemplate" type="text/x-kendo-tmpl">
<tr>
<td id="EmployeeId">
${ EmployeeID }
</td>
<td>
${ FirstName }
</td>
<td>
${ LastName }
</td>
</tr>
</script>
Initialize the grid and bind data.
<script>
$(document).ready(function () {
$("#grid").kendoGrid({
columns: [
"EmployeeID"
,{
field: "FirstName",
title: "First Name"
},{
field: "LastName",
title: "Last Name"
}
],
dataSource: {
data: [
{
EmployeeID: 0,
FirstName: "Joe",
LastName: "Smith"
}, {
EmployeeID: 1,
FirstName: "Jane",
LastName: "Smith"
}
],
schema: {
model: {
id: "EmployeeID",
fields: {
EmployeeID: {type: "number" },
FirstName: { type: "string" },
LastName: { type: "string" }
}
}
},
pageSize: 10
},
scrollable: {
virtual: true
},
sortable: true,
pageable: true,
rowTemplate: kendo.template($("#rowTemplate").html())
});
//Add a double click event that will return the text in the EmployeeId column.
$('#grid table tr').dblclick(function () {
alert($(this).find("td[id=EmployeeId]")[0].innerText);
});
});
</script>
--EDIT--
I've also gone ahead and created an MVC extensions example, the approach is the same via the template route.
Model class:
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
}
View code:
<script type="text/javascript">
function OnDataBound() {
$('#OtherGrid table tr').dblclick(function () {
alert($(this).find("span[id=EmployeeId]")[0].innerText);
});
}
</script>
#(Html.Kendo().Grid<Employee>()
.Name("OtherGrid")
.Columns(columns =>
{
columns.Bound(p => p.EmployeeId).ClientTemplate("<span id=\"EmployeeId\">#: EmployeeId #</span>");
columns.Bound(p => p.Name);
})
.DataSource(dataSource => dataSource
.Ajax() // Specify that the data source is of ajax type
.Read(read => read.Action("GetEmployees", "Home")) // Specify the action method and controller name
)
.Events(e => e.DataBound("OnDataBound"))
)
Controller:
public ActionResult GetEmployees([DataSourceRequest]DataSourceRequest request)
{
List<Employee> list = new List<Employee>();
Employee employee = new Employee() { EmployeeId = 1, Name = "John Smith" };
list.Add(employee);
employee = new Employee() { EmployeeId = 2, Name = "Ted Teller" };
list.Add(employee);
return Json(list.ToDataSourceResult(request));
}
Hope this helps!
I achieved what i was looking for with this js
$('#GridPedidos table tr').live('dblclick', function () {
var grid = $("#GridPedidos").data("kendoGrid");
var dItem = grid.dataItem($(this));
if (dItem != null) {
detalhePedido(dItem.id);
}
});
To open edit mode with double click you need to register the double click event with the grid like this:
var grid = $("#grid").data("kendoGrid");
grid.element.delegate("tbody>tr", "dblclick", function () {
grid.editRow($(this));
});

Categories