Yajra/Laravel-datatables setting alias for table header - javascript

I have list of products under some category and if I click on category sorting then it shows same category and product name. It is happening only with the category sorting. Other sorting are working perfectly. I am stuck here and unable to resolve this also I have no Idea why category.name is being used. If I changes this to category_name then category sorting stops working. I've tried everyhting.
How can I use Alias for category name?? And in which file do I need to make changes.
var table = $('#product-table').DataTable({
processing: true,
serverSide: true,
bStateSave: true,
ordering: true,
dom: 'Bfrtip',
buttons:[],
ajax: '{{ URL::to('/admin/products.data') }}',
order: [[1, 'asc']],
columnDefs: [
{ orderable: false, targets: 0 }
],
columns: [
{data: 'edit', name: '', searchable:false},
{data: 'name', name: 'name'},
{data: 'product_code', name: 'product_code'},
{data: 'category_name', name: 'category.name'},
{data: 'impa_code', name: 'impa_code'},
{data: 'issa_code', name: 'issa_code'},
{data: 'status', name: 'is_active'}
],
"deferRender": true
});
**This is my blade file**
`<div class="row clearfix">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 m-t-50">
<div class="card">
<div class="body">
<table class="table table-striped table-hover dataTable" id="product-table">
<thead>
<tr>
<th class="col-sm-1"></th>
<th>{{ Lang::get('views.name') }}</th>
<th>{{ Lang::get('views.shipskart_code') }}</th>
<th>{{ Lang::get('views.category_name') }}</th>
<th>{{ Lang::get('views.impa_code') }}</th>
<th>{{ Lang::get('views.issa_code') }}</th>
<th>{{ Lang::get('views.status') }}</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>`
This is Controller
` ->editColumn('product_code', function ($product) {
$productCode = $product['product_code'];
return $productCode;
})
->addColumn('category_name', function ($product) {
return empty($product->category) ? 'N/A' : $product->category->name ;
})
->editColumn('impa_code', function ($product) {
$impaCode = $product->impa_code;
return $impaCode;
})
->editColumn('issa_code', function ($product) {
$issaCode = $product->issa_code;
return $issaCode;`

I believe that is Laravel datatable
If it is a naming issue
and you want to change just the header name to be category.name or anything else .. in the blade view that is showing the table, you should find the headers and you can change it from there accordingly.
change this line
<th>{{ Lang::get('views.category_name') }}</th>
to
<th>{{ the new name }}</th>
or if you want it to reflect the language code also, you need to amend your language files.
Go to the Views, in the specific language that you want to change and update the category_name file
like for example, if you want to change the category_name to CAT title in en language .. go to /resources/lang/en or wherever you are saving your lang/en folder and amend the line
'category_name' => 'CAT title'
If it is a data issue
and it is not reflecting the data that you are expecting, always check the link that is producing this issue and in your case
/admin/products.data
from there you can know what exactly are coming through so you can show it in your table accordingly .. you can check the DataTable Manual
so if you are receiving product array which has a key called name .. that is going to be a product.name in the same way JavaScript is reading the the json.

Related

Create a function to transform an array of data into column headers for a table dynamically

What I'm trying to do is take a data array of objects and create a function where I can pass the data in and render the column headers and rows dynamically. Here is my sample data:
let revisions = [
{
car: {
id: 1000,
header: "Toyota"
},
revisionDate: {
header: "Revision Date",
newValue: "08/24/2021",
oldValue: "09/15/2020"
},
revisionType: {
header: "Revision Type",
newValue: "Tool Desc.",
oldValue: "Tool Number"
},
revisionNote: {
header: "Revision Note",
newValue: "Delete",
oldValue: "Delete"
},
workStation: {
header: "Garage",
newValue: "New garage",
oldValue: "Old garage"
}
}
For my function I have tried using 2 for loops, however I cannot seem to figure out how to get the properties in the array. What I've tried:
getHeaders(revisions) {
var prop;
var rowProp;
for (rowProp = 0; rowProp < revisions.length; rowProp++)
if (rowProp >= 0) {
gridData.push({ header: revisions.header });
}
for (prop = 0; prop < revisions.length; prop++) {
if (prop === "oldValue") {
gridData.push({ field: "revisionDate", header: revisions.header + " (Existing)" });
}
if (prop === "newValue") {
gridData.push({ field: "revisionDateNew", header: revisions.header + " (New)" });
}
else {
gridData.push(revisions);
}
}
return gridData;
}
Here is the html just in case:
<tr>
<th *ngFor="let col of columns">
{{col.header}}
</th>
</tr>
Thank you for the help.
If your objects stay built the same:
{
car:{...},
revisionDate:{...},
revisionType:{...},
revisionNote:{...},
workStation:{...}
}
Then you dont even need to build a function to display that data in a table here is a table layout you could do:
<table>
<th class="row" >
<div class="col-2">{{ revisions[0].car.header }}</div>
<div class="col-2">{{ revisions[0].revisionDate.header }}</div>
<div class="col-2">{{ revisions[0].revisionType.header }}</div>
<div class="col-2">{{ revisions[0].revisionNote.header }}</div>
<div class="col-2">{{ revisions[0].workStation.header }}</div>
</th>
<td class="row" *ngFor="let rev of revisions">
<div class="col-2">{{ rev.car.id }}</div>
<div class="col-2">{{ rev.revisionDate.newValue }}</div>
<div class="col-2">{{ rev.revisionType.newValue }}</div>
<div class="col-2">{{ rev.revisionNote.newValue }}</div>
<div class="col-2">{{ rev.workStation.newValue }}</div>
</td>
</table>
revisions[0] is used to just get the first object and access the headers for display. Then after that you use your *ngFor="" in order to loop through each object and display the data within those elements.

data sorting via primary key in jquery data table

I have displayed data in view page using data table. I want to display data in descending order according to
public ActionResult Index()
{
return View(db.BusinessRegModel.OrderByDescending(v => v.BusinessId).ToList());
}
BusinessId is primary key.
But in view page, data is not sorted via primary key. I am using jquery data table to display data.
<table id="tblBusinessData" class="table" width="100%" cellspacing="0">
<thead>
<tr>
<th>Edit/Print</th>
<th>
#Html.DisplayNameFor(model => model.RegNum)
</th>
<th>
#Html.DisplayNameFor(model => model.RegDate)
</th>
<th>
#Html.DisplayNameFor(model => model.NameOfFirm)
</th>
//code blocks
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td width="20%">
#Html.ActionLink("Edit", "Edit", new { id = item.BusinessId }, new { #class = "btn btn-warning" })
#Html.ActionLink("Print", "Details", new { id = item.BusinessId }, new { #class = "btn btn-danger" })
</td>
//code blocks
But the data is not sorted in descending order via BusinessId key. How can I do this? I need to display data in descending order by BusinessId.
jquery code
<script type="text/javascript">
$('#tblBusinessData').DataTable();
</script>
Add the column Id to the HTML and hide it via configuration:
$('#tblBusinessData').DataTable({
"columnDefs": [{
"targets": [0],
"visible": false
}],
"order": [
[0, "desc"]
]
});
If you are able to set the desired order in your data before you send it to DataTables, you can simply set order: [] to disable the initial sort while still being able to click on the column headers.
$('#tblBusinessData').DataTable({
order: []
});

php, Laravel 7 - Unable to receive data from AJAX request

I'm still a newbie and currently learning how to use Laravel 7.
My problem is, I tried to pass my data from the controller by using an AJAX request on
my child page. I noticed that when I tried to pass the data from my child page, the page won't
receive it but somehow it's working on a master page (where I didn't use any Blade directives).
I tried to dd() the data in the controller and it does show that there is data.
But it won't pass it to the child page. All the JS files and custom script that I push does
come out on the child page.
blade
code
index.blade.php (child page)
#extends('layouts.app')
#section('content')
<div class="container">
<div class="container mt-5">
<h2 class="mb-4">Laravel 7 Yajra Datatables Example</h2>
<table class="table table-bordered yajra-datatable">
<thead>
<tr>
<th class="text-center">#</th>
<th class="text-center">Name</th>
<th class="text-center">Batch</th>
<th class="text-center">Graduation Year</th>
<th class="text-center">Mobile</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
#endsection
#push('child-scripts')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap4.min.js"></script>
<script type="text/javascript">
$(function () {
var table = $('.yajra-datatable').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('alumni-list') }}",
columns: [
{data: 'DT_RowIndex', name: 'DT_RowIndex'},
{data: 'name', name: 'name'},
{data: 'batch_year', name: 'batch_year'},
{data: 'graduation_year', name: 'graduation_year'},
{data: 'contact_no', name: 'contact_no'},
{
data: 'action',
name: 'action',
orderable: true,
searchable: true
},
]
});
});
</script>
#endpush
AlumniController.php
class AlumniController extends Controller
{
public function index(Request $request)
{
// dd(Profile::latest()->get());
if ($request->ajax()) {
$data = Profile::latest()->get();
return Datatables::of($data)
->addIndexColumn()
->addColumn('action', function($row){
$btn = 'Edit Delete';
return $btn;
})
->rawColumns(['action'])
->make(true);
}
return view('admin.users.index');
}
}
Alumni Route
Route::get('alumni', [
'uses' => 'AlumniController#index',
'as' => 'alumni-list'
]);
Thank you for your time, sir.
Solved it after MORE googling done.
Make sure to add defer inside your DataTable CDN.
Example:
<script src = "http://cdn.datatables.net/1.10.18/js/jquery.dataTables.min.js" defer ></script>
Here's the link where I found the answer:
https://datatables.net/forums/discussion/50869/typeerror-datatable-is-not-a-function-datatable-laravel
For more understanding on why defer is added:
https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
use Yajra\DataTables\Contracts\DataTable;
use Yajra\DataTables\Facades\DataTables;
please use this two line in your controller

Angular *ngFor using PIPE not working when looping throw object

API data {
id: 1,
date: "21/may/2020",
name: "Server A",
geo: "Europa",
status: "online"
}
ngOnInit {
this.col = [
{field: 'name', header: 'Server Name'},
{field: 'geo', header: 'Geography'},
{field: 'status', header: 'Status'},
{field: 'date', header: 'Date'}
]
}
I'm testing angular PrimeNG and I have an data-table, where I set the values for each table row manually, it works fine.
template
<ng-template>
<td>
<tr>
<td>{{rowData.name}}</td>
<td>{{rowData.geo}}</td>
<td>{{rowData.status}}</td>
<td>{{rowData.date | date: 'dd/MMM/yyyy'}}</td>
</tr>
<td>
<ng-template>
I updated my template to dynamically loop through the object and set the data, how can I update my loop so I can insert the pipe when I render the "date" object.
<td *ngFor="let col of column">
{{rowData[col.field]}}
</td>
The above {{rowData[col.field]}} is working, but I not sure how to inside *ngFor="let col of columns " I can update only the col.date and add pipe into it.
This is what I trying but not successful, the baove is working but not the Pipe and also if I add keyvalue the tables data is not being displayed anymore.
<td *ngFor="let col of columns | keyvalue">
<ng-container *ngIf="rowData[col.field] !== 'date'"> {{rowData[col.field]}}</ng-container>
<ng-container *ngIf="rowData[col.field] === 'date'"> {{rowData[col.field] | date: 'dd/MMM/yyyy'}}</ng-container>
</td>
Any suggestion or example I can look into?
If i understand your question right, you want to apply pipe on the birthdate field, so you can do ,
<td *ngFor="let data of object">
{{data["birthdate"] | date: 'dd/MMM/yyyy' }}
</td>
Use key value pipe like
<td *ngFor="let data of object | keyvalue">
<ng-container *ngIf="data.key !== 'birthdate'"> {{data.value}}</ng-container>
<ng-container *ngIf="data.key === 'birthdate'"> {{data.value | date: 'dd/MMM/yyyy'}}</ng-container>
</td>

how to pass json data into query string and use that data in another page

Here table contains book details which contains book name, author, pric, ISBN and category. When user click on Book Name it should pass the data to another page using querystring
<script type="text/javascript" src="book.js">
<body ng-app="mymodule" >
<div ng-controller="myController" >
<table border=2>
<thead>
<tr>
<th>ISBN</th>
<th>NAME</th>
<th>AUTHOR</th>
<th>CATEGORY</th>
<th>PRICE</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="book in books">
<td>{{ book.ISBN }}</td>
<td >{{ book.Name }}</td>
<td>{{ book.Author }}</td>
<td>{{ book.Category }}</td>
<td>{{ book.price }}</td>
</tr>
</tbody>
</table>
books.js
var myapp = angular.module('mymodule', []);
myapp.controller("myController", function($scope, $http,$window) {
$http.get("https://api.myjson.com/bins/p4ujn").then(function(response) {
$scope.books = response.data;
$scope.getdetail=function(){
$scope.getbookdetail=this.book;
$window.location.href = "orderpage.html";
}
});
});
orderpage.html
<script type="text/javascript" src="book.js"></script>
<body ng-app="mymodule" >
<div ng-controller="myController" >
{{getbookdetail.Name}}<br>
{{getbookdetail.Author}}
{{getbookdetail.price }}<br>
</div>
</body
So you said this: 'When user click on Book Name it should pass the data to another page using querystring'
Querystring is not the best method to use for something like this. You're better off learning about ui-router and setting up routes that handle this. You have your initial state, then you can create another state to display each book. Something like this:
.state('initial', {
url: 'some/initial',
template: 'some/initial/template.html',
params: {
name: null,
price: null,
author: null,
isbn: null,
category: null
}
})
.state('read-book-details', {
parent: 'initial',
url: 'some/url',
template: 'some/template.html',
params: {
name: null,
price: null,
author: null,
isbn: null,
category: null
}
})
Then when you're transitioning from one 'state' to another, you do it like so passing along the parameters you want:
$state.go('read-book-details',
{ name: book.name, price: book.price, author: book.author });
On the 'other' page's controller (ie the controller for the 'read-book-details' state) you can inject $state and get the parameters that are passed in via $state.params (ie., $state.params.price)
A second option for you is to have a service that you can store the data in, then retrieve from anywhere else. This obviously becomes useful when you start to pass around larger amounts of data rather than simpler smaller pieces (like name, price).

Categories

Resources