Adding Action into the DataTables JSON Specific Cell - javascript

I am successfully loading JSON data into datatables. But i want to add some processing into specific row. How can I accomplsih this?
I want to add a button
Use the button to send an row ID retrieved from the JSON object into another page for database processing
Here is my JS:
<script>
$.getJSON('../vendor/process/process_vendor.php', function(response) {
var vendButton = '<button>EDIT</button>';
$('#vendorlist').DataTable({
processing: true,
data: response,
columns: [
{data: "CLIENT_ID"},
{data: "CLIENT_NAME"},
{data: "CLIENT_ADDR"},
{data: "CLIENT_LOC"},
{data: "CLIENT_PROV"},
{data: "CLIENT_CONT_PERS"},
{data: "CLIENT_CONT_PH1"},
{data: "CLIENT_CONT_PH2"},
{data: "CLIENT_CONT_FAX"},
vendButton
]
});
window.someGlobalOrWhatever = response.balance;
});
</script>
So far the problem is i cant initialize the vendButton and I couldn't retrieve the specific row ID using CLIENT_ID:
This is the data from JSON response:
[
{
"CLIENT_ID" : "CL0000001",
"CLIENT_NAME" : "ABHIRAMA KRESNA",
"CLIENT_ENT_DATE" : "12-NOV-14",
"CLIENT_ENT_SIGN" : "chrishutagalung",
"CLIENT_CONT_PERS" : null,
"CLIENT_CONT_PH1" : null,
"CLIENT_CONT_PH2" : null,
"CLIENT_CONT_FAX" : null,
"CLIENT_ADDR" : "JL AMARTA BLOK G NO 10 GROGOL",
"CLIENT_LOC" : "SOLO",
"CLIENT_PROV" : null,
"CLIENT_INIT" : "ABK",
"CLIENT_NPWP" : null
}
]

columns is an object describing columns model. You try to simply add a string to it.
Probably, you need to iterate through all objects and add this button to every object.
<script>
$.getJSON('../vendor/process/process_vendor.php', function(response) {
$.each(response, function() {
this.vendButton = "<button data-id='" + this.CLIENT_ID + "'>EDIT</button>";
});
$('#vendorlist').DataTable({
processing: true,
data: response,
columns: [
{data: "CLIENT_ID"},
{data: "CLIENT_NAME"},
{data: "CLIENT_ADDR"},
{data: "CLIENT_LOC"},
{data: "CLIENT_PROV"},
{data: "CLIENT_CONT_PERS"},
{data: "CLIENT_CONT_PH1"},
{data: "CLIENT_CONT_PH2"},
{data: "CLIENT_CONT_FAX"},
{data: "vendButton"}
]
});
window.someGlobalOrWhatever = response.balance;
});
</script>
This will generate another one column with code like this:
<button data-id='123'>EDIT</button>
where 123 is CLIENT_ID for specific row.
Then, on click, you can simply access it like
.click(function()
{
var id = $(this).data('id');
});
You can also use DataTables API to draw this column programmatically.
Refer to an official DataTables example.

Related

refresh pagination laravel with axios and datatables

I'm creating a list user table on fw laravel by using datatable and axios (not use vuejs), i don't use datatable's pagination but laravel's one because datatables take a lot of time to respond upon retrieving a million records, I can't find a way to use serverside feature cause axios replace ajax feature in severside. The issue began from this:
I'm successful to use laravel's pagination with js but as it comes to 10 or more page, the pagination not update and change the positive upon i click number page, i only can change a page from 1 to 10, here is my pagination code:
display pagination
<div id="pagination">
{!! $axios->links() !!}
</div>
and here is js code
$(document).on('click', '.pagination a',function(e) {
e.preventDefault();
$('li').removeClass('active');
$(this).parent().addClass('active');
let pg = $(this).attr('href')
reloadData(pg)
window.history.pushState("", "",pg)
})
reloadData function:
function reloadData(value){
axios.get(url+'/data'+ value).then(handleResponse)
.catch(function (error) {
console.log(error);
})
function handleResponse(response) {
data = response.data.data;
$('#dataid').DataTable().clear().destroy()
$('#dataid').DataTable({
paging : false,
severSide: true,
processing: true,
deferRender: true,
order: [],
retrieve: true,
pagingType: 'full_numbers',
dom: 'lBfrtip',
columnDefs: [{
"defaultContent": "-",
"targets": "_all"
}],
data: data,
columns: [
{ data: 'name' },
{ data: 'email' },
{ data: 'phone' },
{ data: '' },
{ data: 'created_at' },
{ data: function(data){
return '<td class="pr-0 text-center">'+
'<a id="delete-btn" class="label label-inline label-light-default font-weight-bolder delete-btn" data-id="'+data.id+'" href="javascript:void(0)">Delete'+
'</a>'+ '/'+
'<a id="edit-btn" class="label label-inline label-light-default font-weight-bolder delete-btn" data-id="'+data.id+'" href=" javascript:void(0)">Edit'+
'</a>'+
'</td>'
}}
],
})
}
}
controller :
//display view and pagination
public function index(Request $request)
{
$axios = Apiato::call('User#GetAllUsersAction', [$request]);
$axios->withPath('');
return view('user::Axios.list',compact('axios'));
}
// i retrived the records from this
public function getData(Request $request)
{
//$user = $request->getContent();
//$user = json_decode($user,true);
$axios = Apiato::call('User#GetAllUsersAction', [$request]);
return $axios;
}
i expect something like this upon i click number page : [1],2,3,4,5,...,24,25 --> 1,2,...,[6],7,8,9,...25

how to pass data coming from laravel query as a json object to the function in javascript

i am actually using graphs in my project for which i am passing dynamic data from controller to blade and then in the js script. The js function in the blade accept the array of objects and i dont know how to assign the data from the controller to that js function.
$data['typesBasedProperties'] = DB::table('properties')
->join('property_types', 'properties.property_type', 'property_types.id')
->select('property_types.types as label', DB::Raw('COUNT(properties.id) as value'))
->whereIn('properties.id', $property_ids)
->groupBy('label')
->get()
->toJson();
and this is the js function
var donutChart = function(){
Morris.Donut({
element: 'morris_donught',
data: [
{
label: " Download Sales ",
value: 12,
}, {
label: " In-Store Sales ",
value: 30
}, {
label: " Mail-Order Sales ",
value: 20
}
],
resize: true,
redraw: true,
colors: ['#2b98d6', 'rgb(59, 76, 184)', '#37d159'],
//responsive:true,
});
}
I think you need to do something like this:
<script>
var typesBasedProperties = {!! $typesBasedProperties !!}
</script>
After this you have typesBasedProperties object available in all your js code.
Check out laravel documentation for more info.
You can use ajax request to fetch data from laravel controller to javascript or JQuery.
here's some example
controller
function bbq(Request $r){
$data = DB::select('CALL bukubesar('.$r->no.')');
$node = DB::select('CALL infonode('.$r->no.')');
return array(
'data' => $data,
'node' => $node
);
}
route (I'm using Group)
Route::controller(CPembukuan::class)->group(function () {
Route::get ('/pembukuan-besar', 'bukubesar');
Route::get ('/pembukuan-besar/query', 'bbq' );
Route::get ('/pembukuan-labarugi', 'labarugi' );
Route::get ('/pembukuan-labarugi/query', 'lrq' );
});
ajax (JQuery) on html or blade file
//a variable to pass to controller (optional)
val = $('#kode').val();
$.ajax({
type: "get",
url: "/pembukuan-besar/query",
data: {
'no': val // the data represented as 'no'
},
success: function(data) {
console.log(data); // to view the data in console
//do anything you want here
}
});

Select2 ajax preselection with custom data value

So I have a multiselection dropdown with select2 and I fetch the info from a database. The thing is that prepopulating the dropdown with many values works with the example from the docs, but I also want to include an extra data field. This is how I try to populate the dropdown:
var productSelect = $('#product_ids');
$.ajax({
type: 'GET',
url: '/ajaxOrdersData/' + orderID
}).then(function (datas) {
datas.forEach(data => {
var option = new Option(data.name, data.id, true, true);
option.dataset.price = data.price;
productSelect.append(option).trigger('change');
});
productSelect.trigger({
type: 'select2:select',
params: {
data: datas.map(function (item) {
return {
text: item.nfame,
id: item.id,
price: item.price,
}
})
}
});
});
The above code does create an option tag with a data-price value but then, retrieving that value like below, doesn't work:
var products = $('#product_ids').select2('data');
The products variable doesn't have the price data attribute.
What other ways there are for me to fetch the price data attribute of all products in multiselect when clicking on a button on the DOM?
This is a solution I came up with:
var products =$('#product_ids option:selected');
And then to retrieve the value:
$.each(products, function(index, value) {
actualTotals += Number(value.dataset.price);
});
An alternative solution is to keep the .select2('data'); way of fetching the selections but instead use jquery to retrieve each elements attributes from the resulting object:
var products =$('#product_ids').select2('data');
$.each(products, function(index, value) {
price = value.element.attributes['data-price'].value;
});

How to generate a table dynamically and group rows

I want to generate data in data table based on JSON response. Following is my JSON response:
{
"alertItems": [
{
"id": "PROD-115388",
"errors": [
"Original Estimate is null",
"id is null"
],
"warnings": [
"Original Estimate is above threshold",
"Story points are above threshold",
"These sub tasks are not defined."
]
},
{
"id": "PROD-112479",
"errors": [],
"warnings": [
"Original Estimate is above threshold",
"Story points are above threshold",
"Estimate is missing for these sub tasks : PROD-112329"
]
},
{
"id": "PROD-108461",
"errors": [],
"warnings": [
"Original Estimate is above threshold",
"Story points are above threshold",
"These sub tasks are not defined : Test Case, BA Documentation Task, QA Design and Execute Task, BA/QA/Dev, BA Testing Task, QA Documentation Task, Elaboration"
]
}
],
"numberOfErrors": 0,
"numberOfWarnings": 10
}
I want to generate Table like following:
I have array of warnings and errors. I want to generate a row for each warning/error against its Id. How can I do that in jQuery datatables?
You may use ajax.dataSrc option to specify callback function that will transform your data to desired format:
const transform = data =>
data.alertItems
.map(({id, errors, warnings}) =>
[...errors.map(error => ({id, type: 'error', reason: error})),
...warnings.map(warning => ({id, type: 'warning', reason:warning}))])
.flat();
In order to group your table rows by matching id's in the first column, you may use rowspan HTML attribute set from within drawCallback function (in order to do that, you'll need to ensure that your table rows sorting order is fixed, so that items with the same id will go sequentially regardless of the sorting/filtering).
So, the complete example (with ajax part commented out, since it's not available within live snippet) might look, like:
//original JSON
const srcJSON = {"alertItems":[{"id":"PROD-115388","errors":["Original Estimate is null","id is null"],"warnings":["Original Estimate is above threshold","Story points are above threshold","These sub tasks are not defined"]},{"id":"PROD-112479","errors":[],"warnings":["OriginalEstimateisabovethreshold","Storypointsareabovethreshold","Estimateismissingforthesesubtasks: PROD-112329"]},{"id":"PROD-108461","errors":[],"warnings":["OriginalEstimateisabovethreshold","Storypointsareabovethreshold","Thesesubtasksarenotdefined: TestCase, BADocumentationTask, QADesignandExecuteTask, BA/QA/Dev, BATestingTask, QADocumentationTask, Elaboration"]}],"numberOfErrors":0,"numberOfWarnings":10};
//proper JSON
const transform = data => data.alertItems.map(({id, errors, warnings}) => [...errors.map(error => ({id, type: 'error', reason: error})),...warnings.map(warning => ({id, type: 'warning', reason:warning}))]).flat();
//datatables init
$('table').DataTable({
/*
ajax: {
url: //url to API endpoint returning original JSON
method: //http method (GET, POST, etc)
dataSrc: transform(data)
}
*/
data: transform(srcJSON), //this one should be dropped once ajax section uncommented
paging: false,
orderFixed: [0,'asc'],
columns: [
{data: 'id', title: 'Story Id'},
{data: 'type', title: 'Type'},
{data: 'reason', title: 'Warning Reason'}
],
//group by first col, using rowspan attribute
drawCallback: function(){
//clean up the view
$('tbody td').attr('rowspan',1).show();
//grab datatable into variable
const table = this.api();
//grab visible, sorted table rows
const rows = table.rows({search:'applied',order:'current'}).nodes();
var groupIdTd = null;
//run through the table rows and set 'rowspan' attribute for matching id's
$.each(rows, function(idx){
const rowspan = Number($(groupIdTd).attr('rowspan') || 1);
idx > 0 && table.cell(groupIdTd).data() == table.cell(this,0).data() ?
($(groupIdTd).attr('rowspan', rowspan+1), $(table.cell(this,0).node()).hide()) :
(groupIdTd = table.cell(this,0).node(), $(groupIdTd).attr('rowspan',1));
});
}
})
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.18/rg-1.1.0/datatables.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/rowgroup/1.1.0/css/rowGroup.dataTables.min.css" />
<script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.18/rg-1.1.0/datatables.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/rowgroup/1.1.0/js/dataTables.rowGroup.min.js"></script>
<script src="test.js"></script>
</head>
<body>
<table></table>
</body>
</html>
Solution is to transform the data before passing it to DataTables using ajax.dataSrc option. Another component of the solution is third-party rowsGroup extension which allows to group rows with identical data.
var table = $('#example').DataTable({
'ajax': {
'url': 'https://api.myjson.com/bins/1b72lv',
'dataSrc': function ( data ) {
var resultData = [];
if(data.hasOwnProperty('alertItems')){
$.each(data.alertItems, function( index, record ) {
$.each(record.errors, function( index, message ) {
resultData.push([ record['id'], 'Error', message ]);
});
$.each(record.warnings, function( index, message ) {
resultData.push([ record['id'], 'Warning', message ]);
});
});
}
return resultData;
}
},
'rowsGroup': [0]
});
See this example for code and demonstration.
See jQuery DataTables: ROWSPAN in table body TBODY for more details on rowsGroup extension.

unique nested ng-repeat populated from database

i am trying to get unique values for a nested ng-repeat
there are the two scopes i am working with
$scope.AllGames = [
{ title: "Doom", productCode: "458544", id_product: "1" },
{ title: "Wolvenstein", productCode: "457104", id_product: "2" },
{ title: "Quake", productCode: "32542687", id_product: "3" }
];
$scope.AllPrices= [
{ id_productPrice: "1", id_product: "1", price : "599" },
{ id_productPrice: "2", id_product: "1", price : "699" },
{ id_productPrice: "3", id_product: "2", price : "249" }
];
this is the html
<div ng-repeat="game in AllGames">
<div>{{game.title}} | {{game.id_product}} | {{game.title}}</div>
<div ng-init="getPriceByGame(game.id_product)">
<div ng-repeat="item in AllPrices">
{{item.price}}
</div>
</div>
and this is the controller
$scope.getAllGames = function () {
var request = 'Games';
$http({
method: 'Get',
url: uri + request
})
.success(function (data) {
$scope.AllGames = data;
})
}
$scope.getPriceByGame = function (id_product) {
var request = AllPrices/' + id_product;
$http({
method: 'Get',
url: uri + request
})
.success(function (data) {
$scope.AllPrices = data;
})
};
So the idea is that i send the id_product to the database and i get a list of prices back for that id, i would like to connect these prices for each unique product. what happens now is that the ng-init works fine and the request gets send with the id, i receive the prices for that id. In the console log i see all the prices coming in by product_id (all different arrays) but i can't seem to connect them in the html so i actually see the prices.
The last request overwrites of course all the prices for each game in the ng-repeat. How do i keep this unique? So that each product gets the prices for that id.
You could place another ng repeat to loop through the all Prices array. Every time you get new data, you push it to the array.
Don't forget to make an edit in the nested ng repeat of all prices, it should loop only through the current index

Categories

Resources