Datatables with laravel how to render hasMany relationship - laravel

i have the following response from my controller
[
{
"id": 1,
"place_id": 1,
"name": "Test",
"type": 5,
"created_at": "2018-06-04 15:29:02",
"updated_at": "2018-06-04 15:29:02",
"time": [
{
"id": 1,
"stadium_id": 1,
"day": "Saturday",
"from_hour": 7,
"to_hour": 12,
"created_at": "2018-06-04 15:29:42",
"updated_at": "2018-06-04 15:29:42"
},
{
"id": 2,
"stadium_id": 1,
"day": "Sunday",
"from_hour": 7,
"to_hour": 12,
"created_at": "2018-06-04 15:54:03",
"updated_at": "2018-06-04 15:54:03"
}
]
}
]
i want to access the day attribute in each time object
i tried the code below but of course it just loads the first result
is there a solution
columns: [
{ data: 'name' },
{ data: 'type' },
{ data: 'time.0.day' },
{ data: 'time.0.from_hour' },
{ data: 'time.0.to_hour' },
],

You can actually access time array by using the render property:
columns: [{
data: 'name'
},
{
data: 'type'
},
{
data: 'time',
render: function(data, type, row) {
var txt = '';
data.forEach(function(item) {
if (txt.length > 0) {
txt += '</br> '
}
txt += item.day;
});
return txt;
}
},
...
This would just add a line break for every objects in time. Here's a Fiddle for you to examine.

Related

Combining two observable sources filtering by one first observable property

Having an observable emitting a list of users with the next content:
[
{
"id": 1,
"name": "John",
"status": "Active"
},
{
"id": 2,
"name": "Mary",
"status": "Inactive"
},
{
"id": 3,
"name": "Peter",
"status": "Inactive"
},
{
"id": 4,
"name": "Susan",
"status": "Active"
}
]
And I have another observable returning the extended user data:
{
"id": 1,
"authorizations: 20
}
I use the detail of each user in an specific details page, but I would like to combine part of the detail in the users list and obtain the next result and only filter by the status Active:
[
{
"id": 1,
"name": "John",
"status": "Active",
"authorizations": 20
},
{
"id": 4,
"name": "Susan",
"status": "Active",
"authorizations": 10
}
]
It is possible to use some filtering operator and combine those results without use two subscriptions?
Tried the following code but, would be a better or simplified way to do it?
import { of, Observable, combineLatest } from 'rxjs';
import { filter, map, mergeAll, mergeMap } from 'rxjs/operators';
type State = 'Active' | 'Inactive';
type User = { id: number; name: string; status: State };
type UserDetail = { id: number; authorizations: number };
type UserWithAuthorizations = User & UserDetail
const users: User[] = [
{
"id": 1,
"name": "John",
"status": "Active"
},
{
"id": 2,
"name": "Mary",
"status": "Inactive"
},
{
"id": 3,
"name": "Peter",
"status": "Inactive"
},
{
"id": 4,
"name": "Susan",
"status": "Active"
}
]
const authorizations: UserDetail[] = [
{ id: 1, authorizations: 20 },
{ id: 2, authorizations: 5 },
{ id: 3, authorizations: 30 },
{ id: 4, authorizations: 10 },
];
const getAuthorizationsByUser= (userId: number): Observable<Partial<UserWithAuthorizations>> => {
const users$ = of(users)
const authorizations$ = of(authorizations)
return combineLatest([users$, authorizations$]).pipe(
map(res => {
const user = res[0].find(u => u.id === userId)
const { authorizations } = res[1].find(a => a.id === userId)
return {
...user,
authorizations
}
}))
};
const fetchUsersWithAuthorizations = () => of(users);
fetchUsersWithAuthorizations()
.pipe(
mergeAll<User>(),
filter((user) => user.status === "Active"),
mergeMap((user) => getAuthorizationsByUser(user.id))
)
.subscribe(console.log);
Why not do it all in a single combine latest?
const { of, map, combineLatest } = rxjs;
const users = [
{
"id": 1,
"name": "John",
"status": "Active"
},
{
"id": 2,
"name": "Mary",
"status": "Inactive"
},
{
"id": 3,
"name": "Peter",
"status": "Inactive"
},
{
"id": 4,
"name": "Susan",
"status": "Active"
}
]
const authorizations = [
{ id: 1, authorizations: 20 },
{ id: 2, authorizations: 5 },
{ id: 3, authorizations: 30 },
{ id: 4, authorizations: 10 },
];
const users$ = of(users)
const authorizations$ = of(authorizations)
const activeUsersWithAuthorizations$ = combineLatest([users$, authorizations$]).pipe(
map(([users, authorizations]) =>
users
.filter((user) => user.status === 'Active')
.map((user) => ({
...user,
authorizations: authorizations.find((a) => a.id === user.id)?.authorizations,
}))
)
);
activeUsersWithAuthorizations$.subscribe(activeUsersWithAuthorizations => {
console.log(activeUsersWithAuthorizations);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.0/rxjs.umd.min.js" integrity="sha512-v0/YVjBcbjLN6scjmmJN+h86koeB7JhY4/2YeyA5l+rTdtKLv0VbDBNJ32rxJpsaW1QGMd1Z16lsLOSGI38Rbg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

SearchPanes options are empty on the serverSide yajra dataTable

I tried to use the SearchPanes on the serverSide datatable, but It doesn't work; the SearchPanes options are empty.
public function getSalesReturnsData()
{
$sales = Sale::query()
->select(DB::raw("Bestelldatum, kLieferscheinPos ,cBestellNr,
Verkaufsplattform, SKU, GTIN, HAN, Hersteller, Lieferant, cName,
Menge, VKPreis, UVP, Farbe, Groesse, Warengruppe, Transaktion,
Anmerkung, Lieferland, Versandart, Zahlungsart, VersandkostenBrutto,
GutscheinBestellungBrutto"))
->where('Bestelldatum', '>', now()->subDays(30)->endOfDay());
$returns = ProductReturn::query()
->select(DB::raw("Retourendatum, kRMRetoure,cBestellNr, Verkaufsplattform,
SKU, GTIN, HAN, Hersteller, Lieferant, cName, Menge, VKPreis, UVP, Farbe,
Groesse, Warengruppe, Transaktion, Anmerkung, Lieferland, Versandart,
Zahlungsart, VersandkostenBrutto, GutscheinBestellungBrutto"));
$results = $sales->unionAll($returns);
return DataTables::of($results)
->addColumn('Bestelldatum', function ($row) {
$bestelldatum = date("d.m.Y", strtotime($row->Bestelldatum));
return $bestelldatum;
})->make(true);
}
JavaScript
$(document).ready(function () {
load_data();
function load_data() {
$('#datatable').DataTable({
processing: true,
serverSide: false,
ajax: {
url: "{{ route('getSalesReturnsData') }}"
},
"columns": [{
"data": "Bestelldatum"
},
{
"data": "kLieferscheinPos"
},
{
"data": "cBestellNr"
},
{
"data": "Verkaufsplattform"
},
{
"data": "SKU"
},
{
"data": "GTIN"
},
{
"data": "HAN"
},
{
"data": "Hersteller"
},
{
"data": "Lieferant"
},
{
"data": "cName"
},
{
"data": "Menge"
},
{
"data": "VKPreis"
},
{
"data": "UVP"
},
{
"data": "Farbe"
},
{
"data": "Groesse"
},
{
"data": "Warengruppe"
},
{
"data": "Transaktion"
},
{
"data": "Anmerkung"
},
{
"data": "Lieferland"
},
{
"data": "Versandart"
},
{
"data": "Zahlungsart"
},
{
"data": "VersandkostenBrutto"
},
{
"data": "GutscheinBestellungBrutto"
},
],
dom: 'PBfrtip',
stateSave: true,
searchPanes: {
initCollapsed: true,
cascadePanes: true,
dtOpts: {
paging: 'flase',
pagingType: 'simple',
select: {
style: 'multi'
}
},
columns: [3, 5, 8, 6, 7, 9, 11, 16]
}
});
}
});

JSGRID - Excel-like keyboard navigation

I have a jsgrid gride and I want to activate edit mode in next line after hit enter key (or arrow down key) in "inline edition" and focus on the same column but next line, as Excel -like keyboard navigation.
The only achievement is to fire update with enter key but how to activate edition in the next line in the same column?
var clients = [
{ "Name": "Otto Clay", "Age": 25, "Country": 1, "Address": "Ap #897-1459 Quam Avenue", "Married": false },
{ "Name": "Connor Johnston", "Age": 45, "Country": 2, "Address": "Ap #370-4647 Dis Av.", "Married": true },
{ "Name": "Lacey Hess", "Age": 29, "Country": 3, "Address": "Ap #365-8835 Integer St.", "Married": false },
{ "Name": "Timothy Henson", "Age": 56, "Country": 1, "Address": "911-5143 Luctus Ave", "Married": true },
{ "Name": "Ramona Benton", "Age": 32, "Country": 3, "Address": "Ap #614-689 Vehicula Street", "Married": false }
];
var countries = [
{ Name: "", Id: 0 },
{ Name: "United States", Id: 1 },
{ Name: "Canada", Id: 2 },
{ Name: "United Kingdom", Id: 3 }
];
$("#jsGrid").jsGrid({
width: "100%",
height: "400px",
inserting: false,
editing: true,
sorting: true,
paging: true,
data: clients,
fields: [
{ name: "Name", type: "text", width: 150, validate: "required" },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: countries, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married", sorting: false },
{ type: "control" }
],
onError: function (args) {
console.log("ERR");
console.log(args);
},
});
$('#jsGrid').off().on('keydown', 'input[type=text], input[type=number]', (event) => {
if (event.which === 13) { // Detect enter keypress
$('#jsGrid').jsGrid("updateItem"); // Update the row
}
});
UPDATE: I developed an alternative that use Enter (or arrow down key) con updateitem, activate the edit mode in the next row and focus on the same previous column control. But I think there is an easy way.
var LastIndexInputs = -1;
var LastIndexSelect = -1;
function ActivateEditNextLine(NewIndex) {
var gridBody = $("#jsGrid").find('.jsgrid-grid-body');
gridBody.find('.jsgrid-table tr').each(function (index, tr) {
if (index == NewIndex) {
$(tr).trigger('click');
RowTarget = gridBody.find(".jsgrid-edit-row");
if (LastIndexInputs != -1) {
RowTarget.find('.Campo')[LastIndexInputs].focus();
RowTarget.find('.Campo')[LastIndexInputs].select();
}
else {
if (LastIndexSelect != -1) {
RowTarget.find('select')[LastIndexSelect].focus();
}
}
}
});
};
var clients = [
{ "Name": "Otto Clay", "Age": 25, "Country": 1, "Address": "Ap #897-1459 Quam Avenue", "Married": false },
{ "Name": "Connor Johnston", "Age": 45, "Country": 2, "Address": "Ap #370-4647 Dis Av.", "Married": true },
{ "Name": "Lacey Hess", "Age": 29, "Country": 3, "Address": "Ap #365-8835 Integer St.", "Married": false },
{ "Name": "Timothy Henson", "Age": 56, "Country": 1, "Address": "911-5143 Luctus Ave", "Married": true },
{ "Name": "Ramona Benton", "Age": 32, "Country": 3, "Address": "Ap #614-689 Vehicula Street", "Married": false }
];
var countries = [
{ Name: "", Id: 0 },
{ Name: "United States", Id: 1 },
{ Name: "Canada", Id: 2 },
{ Name: "United Kingdom", Id: 3 }
];
$("#jsGrid").jsGrid({
width: "100%",
height: "400px",
inserting: false,
editing: true,
sorting: true,
paging: true,
data: clients,
fields: [
{ name: "Name", type: "text", width: 150, validate: "required" },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: countries, valueField: "Id", textField: "Name" },
{ name: "Age", type: "text", width: 50 },
{ name: "Married", type: "checkbox", title: "Is Married", sorting: false },
{ type: "control" },
],
onItemUpdating: function (args) {
console.log("confirm edition");
// pointer to last control index for jump to the same colum
var gridBody = $("#jsGrid").find('.jsgrid-grid-body');
Registro = gridBody.find(".jsgrid-edit-row");
var inputs = Registro.find('.Campo');
LastIndexInputs = inputs.index(inputs.filter(':focus'))
var selects = Registro.find('select');
LastIndexSelect = selects.index(selects.filter(':focus'))
},
onItemUpdated: function (args) {
if (args.grid.data.length != (args.itemIndex + 1)) {
ActivateEditNextLine(args.itemIndex + 1);
}
},
editItem: function (item) {
console.log("Enter in edition mode")
var $row = this.rowByItem(item);
if ($row.length) {
//console.log('$row: ' + JSON.stringify($row));
this._editRow($row);
}
},
onError: function (args) {
console.log("ERR");
console.log(args);
},
});
$('#jsGrid').off().on('keydown', 'input[type!=hidden], select', (event) => {
if (event.which === 13) { // Detect enter keypress
$('#jsGrid').jsGrid("updateItem"); // Update the row
}
if (event.which === 40) { // arrow down keypress
$('#jsGrid').jsGrid("updateItem"); // Update the row
}
});

kendo Treelist keeps telling no records to Display

I´m intending to use some kendo controls from telerik and I started playing with the Treelist control. I´m doing this with Visual Studio 2013 VB or C#.
The plan is to create a webservice that sends some (serialized) data and the user has to manually press a button which is linked to a $Ajax request that POSTS for the data. That data should be passed to the treelist.
But whatever I try it keeps telling me: No Records to Display
Questions:
1 Why is the sample I provided not working. I copied almost literally one of the demo´s.
2 Do you need a seprate datasource or can you put the data direct in the treelist as well?
Thanks in advance.
Rick (NL)
Sample:
`<script type="text/javascript">
$(document).ready(function () {
var dataSource = new kendo.data.TreeListDataSource({
data: [
{ "Item": "Item0", "id": 0, "ParentId": null },
{ "Item": "Item1", "id": 1, "ParentId": 0 },
{ "Item": "Item2", "id": 2, "ParentId": 1 },
{ "Item": "Item3", "id": 3, "ParentId": 1 },
{ "Item": "Item4", "id": 4, "ParentId": null },
{ "Item": "Item5", "id": 5, "ParentId": null },
{ "Item": "Item6", "id": 6, "ParentId": 5 },
{ "Item": "Item7", "id": 7, "ParentId": 5 },
{ "Item": "Item8", "id": 8, "ParentId": 7 },
{ "Item": "Item9", "id": 9, "ParentId": 7 }
],
schema: {
model: {
id: "id",
expanded: true
}
}
});
$("#treelist").kendoTreeList({
dataSource: dataSource,
height: 540,
columns: [
{ field: "Item" },
{ field: "id" },
{ field: "ParentId" }
]
});
});
</script>
parentId also needs to be null if it's the top-level record. That really tripped me up.
#user4659712 yes, you can define the schema. parentId can be anything as long as you tell through the schema:
vm.treeListDataSource = new kendo.data.TreeListDataSource({
data: organizations,
schema: {
model: {
id: "Id",
fields: {
Id: { type: "number", nullable: false },
parentId: { field: "OverliggendeId", nullable: true }
},
expanded: true
}
},
pageSize: 20
});
This is down to a simple typo the "ParentId" needs to be parentId (note lowercase p).
see this dojo for a working version.
http://dojo.telerik.com/uWaSO
I've fallen foul of this before.
Lets not forget the 'parentId' field on the model definition. We don't have to change the JSON properties that way (ParentId needs describing in fields as well though):
var dataSource = new kendo.data.TreeListDataSource({
data: [
{ Id: 1, Name: "test", ParentId: null },
{ Id: 2, Name: "test 2", ParentId: 1 }
],
schema: {
model: {
id: "Id",
parentId: "ParentId",
fields: {
Name: { field: "Name", type: "string" },
StoreCount: { field: "StoreCount", type: "number" },
ParentId: { field: "ParentId", nullable: true }
},
expanded: true
}
}
});
Does anyone know if you can specify a database column with a different name to be the parentid? For example, my table has node_id and parent_node_id.

preloading external json into select box then after search getting specific results

so i am looking into loading external data in an select2 box where there is prepopulate results from the json
i have two issue - getting the data in and then only loading the first few but when a user searches it passes the request to the rest and then the specific json is returned
so the HTML is a simple as
<input type="hidden" id="e21" style="width:300px;"/>
the inital js is
$(document).ready(function () {
$('#e21').select2({
query: function (query){
var data = {results: []};
console.log(data);
$.each(preload_data, function(){
if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
data.results.push({id: this.id, text: this.text });
}
});
query.callback(data);
}
});
$('#e21').select2('data', preload_data );
});
what that does is load in preload_data so that could be
var preload_data = [
{ id: 'user0', text: 'Disabled User'},
{ id: 'user1', text: 'Jane Doe'},
{ id: 'user2', text: 'John Doe', locked: true },
{ id: 'user3', text: 'Robert Paulson', locked: true },
{ id: 'user5', text: 'Spongebob Squarepants'},
{ id: 'user6', text: 'Planet Bob' },
{ id: 'user7', text: 'Inigo Montoya' }
];
an example is here
http://jsfiddle.net/dwhitmarsh/MfJ4B/10/
but instead of preload_data i want to load in load in a ajax call and pass the results
so i could use
var preload_data = $.ajax({
url: 'data/more.json',
method: 'get',
dataType: 'json'
});
but need to wait for the json to load and only want to load in the first 10.
then when a user actually searches i want to pass extra variables like
string: term, //search term
page_limit: 10, // page size
page: page // page number
page is part of the select 2
can anyone help?
btw the more.json looks like
{
"total": 8,
"result": [{
"id": "1",
"label": "Type",
"safeName":"type",
"jsonFile": "type.json"
},{
"id": "2",
"label": "Primary Applicant Name",
"safeName":"primaryApplicantName",
"jsonFile": "primary.json"
},{
"id": "3",
"label": "Address",
"safeName":"address",
"jsonFile": "address.json"
},{
"id": "4",
"label": "Product",
"safeName":"product",
"jsonFile": "product.json"
},{
"id": "5",
"label": "Verification",
"safeName": "verification",
"jsonFile": "verification.json"
},{
"id": "6",
"label": "Documents",
"safeName": "documents",
"jsonFile": "documents.json"
},{
"id": "7",
"label": "Suburb",
"safeName": "suburb",
"jsonFile": "suburb.json"
},{
"id": "8",
"label": "State",
"safeName": "state",
"jsonFile": "state.json"
}]
}

Resources