Implement daterange filter with serverside processing in Yajra Laravel datatables - laravel

I have an invoices table, which uses the Yajra Laravel data table. I want to filter data using 'created_at' column, which does exists in invoices table in the database but not in the table view.
Here is my datatable image:
And the code which take start and end dates:
$(function() {
$('#invoices_daterange').daterangepicker({
opens: 'left'
}, function(start, end, label) {
console.log("A new date selection was made: " + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD'));
});
});
Here is my datatabe JS code
$(function () {
let invoicedatatable = $('#invoicesdatable-table').DataTable({
pageLength: 100,
processing: true,
serverSide: true,
ajax: '{{ route('invoices.datatable') }}',
columns: [
{data: 'invoice_number', name: 'invoice_number'},
{data: 'partner', name: 'partner.full_name'},
{data: 'start', name: 'start'},
{data: 'end', name: 'end'},
{data: 'due', name: 'due'},
{data: 'actual_invoice_amount', name: 'actual_invoice_amount'},
{data: 'action', name: 'action', sortable: false, searchable: false},
],
lengthMenu: [
[10, 50, 100, 250, 3000, 5000],
[10, 50, 100, 250, 3000, 5000]
],
buttons: [{
extend: 'colvis',
text: '<i class="icon-three-bars"></i>',
className: 'btn bg-blue btn-icon dropdown-toggle'
}]
});
});
I did search and read most of the topics about it, but couldn't find anything to implement this.
What I want to do:
is to filter data using the 'created_at' column which is not in the view, but exists in my invoices table in the database.
How to do it?

I am not familiar with your datepicker widget, so I cannot use that in my example. But I think you should be able to adapt the following to use your datepicker.
In my example, I have two separate date fields ("from" and "to") in a form, with a "submit" button:
<div>
<form id="filter-form">
From:<input type="date" id="min-date" name="min-date">
To:<input type="date" id="max-date" name="max-date">
<input type="submit" value="Submit">
</form>
</div>
You don't need to use a form (I used a form here, because it is a simple demo).
In the page's script (the same place where the DataTable is defined), I add a "submit" function:
var url = '{{ route('invoices.datatable') }}';
$( "#filter-form" ).submit(function( event ) {
event.preventDefault();
invoicedatatable.ajax.url( url ).load();
});
I don't actually need to submit the form, so I disable the default submission using event.preventDefault();.
The line invoicedatatable.ajax.url( url ).load(); is explained below.
In my DataTable I change the basic Ajax call from this:
ajax: '{{ route('invoices.datatable') }}',
to this:
ajax: {
url: url,
type: "POST", // or 'GET' if you prefer
data: function (data) {
data.mindate = $('#min-date').val();
data.maxdate = $('#max-date').val();
}
},
This uses a DataTables function to manipulate the data option. This is the data which we will send to the server, as part of our server-side request.
I simply append two new variables to the existing data - mindate and maxdate. These contain the date range you need to use in the server, for filtering.
Note that the data variable passed into the function already contains some data, provided by DataTables for server-side processing. So, I am adding these two extra fields to that existing data.
The request sent from the browser to the server now looks like this. You can see mindate and maxdate at the bottom of the list:
{
"draw": "2",
"columns[0][data]": "id",
"columns[0][name]": "",
"columns[0][searchable]": "true",
"columns[0][orderable]": "true",
"columns[0][search][value]": "",
"columns[0][search][regex]": "false",
"columns[1][data]": "name",
"columns[1][name]": "",
"columns[1][searchable]": "true",
"columns[1][orderable]": "true",
"columns[1][search][value]": "",
"columns[1][search][regex]": "false",
... not all details shown
"order[0][column]": "0",
"order[0][dir]": "asc",
"start": "0",
"length": "10",
"search[value]": "",
"search[regex]": "false",
"mindate": "2021-06-08", // <--- mindate
"maxdate": "2021-06-16" // <--- maxdate
}
In the form submission event, there was this line:
invoicedatatable.ajax.url( url ).load();
This line causes the ajax call in the DataTable to be re-executed, and the table to be re-drawn. This is the trigger which causes the dates to be sent to the server, as part of a standard request. It's the same action as when a user clicks on a column to sort the data, or moves from one page to another page in the DataTable.
The server can process this request and extract the two date fields from the request, in the usual way. It can then use these values to filter the data, before building its response, to send back to the DataTable.

Related

Unable to populate data in DataTable from Controller in Codeingiter

I am trying to list data with DataTable using server side processing through ajax. I am getting the expected response from the controller when the ajax hits. But the data is still not populated in the dataTable.
Controller
public function get_role_details() {
$this->load_generic_model(array('mst_role_model'));
$draw = intval($this->input->get("draw"));
$start = intval($this->input->get("start"));
$length = intval($this->input->get("length"));
$selected_rol = array('m_role_id','m_role_name');
$condition = array('m_role_status' => 'enable');
$other_configs = array('order_by' => 'm_role_id', 'order_dir' => 'DESC');
// $other_configs
$get_role = $this->mst_role_model->get_where_selected( $selected_rol, $condition, $other_configs);
if( (empty($get_role)) || !($get_role) )
{
echo json_encode(array('status' => 500, 'msg' => 'Server Error, Try again later'));
return false;
}
$data['role'] = $get_role;
$data['role_cnt'] = count($get_role);
$json_data = json_encode(array('status' => 200, 'data' => $data));
echo $json_data;
}
View
<section class="content">
<div class="box">
<div class="box-body">
<table id="logTable1" class="table" width="100%">
<thead>
<th>Role id</th>
<th>Role Name</th>
</thead>
</table>
</div>
</div>
</section>
<script type="text/javascript">
$(document).ready(function() {
$("#logTable1").DataTable({
'processing': false,
'serverSide': true,
'ajax': {
'url':'<?php echo base_url()."role/get_role_details"; ?>',
'type' : 'POST'
},
'columns' : [
{data : 'm_role_id'},
{data : 'm_role_name'}
]
});
});
</script>
I use something similar the following
$( document ).ready(function() { // when document is ready load
$.ajax({ // create an AJAX call...
type: $(this).attr('method'), // GET or POST
url: "<?php echo base_url("controller/function/"); ?>", // the file to call
success: function(response) { // on success..
var dts=JSON.parse(response) // becomes your array
var dataSet =dts.result;
// I specified the results in your case data to just call one filter then create the data table within the success call
$('#table_name').DataTable( {
data: dataSet,
fixedHeader: true,
dom: 'Bfrtip',
buttons: [
'copyHtml5',
'excelHtml5',
'csvHtml5',
'pdfHtml5',
],
columns: [
{ title: "Who",
data: "username",
defaultContent: ""
},
{
title: "Accepted",
data: "accepted_when",
render: function ( data, type, row ) {
var rowgpd = moment(data).format("Do MMM YYYY HH:mm:ss");
return rowgpd;
}},
{ title: "Status",
data: "status",
defaultContent: ""
},
]
} );
}
});
return false; // cancel original event to prevent form submitting
});
I believe it will do exactly as you want.
Its pretty straight forward I think .
So for me I had to parse the response to remove the json encoding and allow me to call the row and columns from the array. I also use moment js to parse the date and display in a better format.
Data array location DataTables requires an array of items to represent
the table's data, where each item in the array is a row. The item is
typically an object or an array (discussed in more detail below) - so
the first thing we need to do is tell DataTables where that array is
in the data source.
https://datatables.net/manual/ajax
Based on your screenshot, your JSON response appears to be this:
{
"data": {
"role": [{
"m_role_id": "47",
"m_role_name": "Aakash"
}, {
"m_role_id": "46",
"m_role_name": "Visiting Doctor"
}]
}
}
This is valid JSON, and it may be what you are expecting. But it is not what DataTables is expecting, when you are using DataTables with 'serverSide': true.
There are two problems:
You need to tell DataTables where the array (containing your row data) is located in your JSON - which in your case is data.role. Normally, you would do this using the dataSrc option:
'ajax': {
'url':'<?php echo base_url()."role/get_role_details"; ?>',
'type' : 'POST',
'dataSrc': 'data.role'
},
Because you are using server-side processing, your JSON response should use the structure shown in the server-side documentation:
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [{
"m_role_id": "47",
"m_role_name": "Aakash"
}, {
"m_role_id": "46",
"m_role_name": "Visiting Doctor"
}]
}
Note the following:
The JSON needs to include those extra fields such as recordsTotal, to ensure pagination controls and information are displayed correctly.
The [ ... ] array is now directly attached to data in your JSON. There is no intermediate role object.
You can still keep role if you want to, but then you do still need to use dataSrc, as described above.
I recommend you follow the structure in the documentation, for simplicity.

How to Pass initialPreview Data in bootstrap-fileinput

I have a page that allows users to edit a property listing they had previously submitted. I've been using bootstrap-fileinput to allow users to add images, and it will use the initialPreview attribute to show images that they've already uploaded. Users can remove the initialPreview images to remove images from the dropzone, but I can't find a way to pass this info to the server, that the user has removed these initialPreview images.
I've tried uploadExtraData: function() {}
But I can't get any information about the initialPreview images. Also, I am using the Laravel 5.7 PHP framework for my website.
<div class="form-group">
<label for="additional_info" class="col-lg-12 control-label">Add Photos to Attract Lender Interest</label>
<div class="col-lg-12">
<input type="file" name="image[]" id="image" multiple class="image" data-overwrite-initial="false"
data-min-file-count="0" value="{{ $mortgage->close_date}}">
</div>
</div>
{{-- Scripts for the pretty file input plugin called bootstrap-fileinput --}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.7/js/fileinput.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.5.2/themes/fas/theme.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" type="text/javascript"></script>
<script type="text/javascript">
$("#image").fileinput({
overwriteInitial: false,
initialPreview: [
// IMAGE DATA
"http://digitalbroker.test/storage/properties/847%20Queen%20Street%20West,%20Toronto,%20ON,%20Canada_1.JPG",
// IMAGE DATA
"http://digitalbroker.test/storage/properties/847%20Queen%20Street%20West,%20Toronto,%20ON,%20Canada_2.JPG",
],
initialPreviewAsData: true, // identify if you are sending preview data only and not the raw markup
initialPreviewFileType: 'image', // image is the default and can be overridden in config below
initialPreviewDownloadUrl: 'http://kartik-v.github.io/bootstrap-fileinput-samples/samples/{filename}', // includes the dynamic `filename` tag to be replaced for each config
showUpload: false,
theme: 'fas',
uploadUrl: "/submit-mortgage",
uploadExtraData: function () {
return {
_token: $("input[name='_token']").val(),
};
},
allowedFileExtensions: ['jpg', 'png', 'gif', 'jpeg'],
overwriteInitial: true,
showCaption: false,
showRemove: true,
maxFileSize: 5000,
maxFilesNum: 8,
fileActionSettings: {
showRemove: true,
showUpload: false,
showZoom: true,
showDrag: false,
},
slugCallback: function (filename) {
return filename.replace('(', '_').replace(']', '_');
}
});
</script>
Right now it just removes any old images upon submit and will save any newly uploaded ones. I'd like to both keep track of what initialPreview images were not removed, and which new images were uploaded.
I know this is an older question, but for those who stumble upon it here is a solution:
When a user clicks the remove button on the initialPreview frame you can pass information from that to the server by adding additional option to fileinput which will make an Ajax call each time the remove button is clicked.
Using the question above you would need to add:
initialPreviewConfig: [
{
// This is passed to the server in the request body as key: 0
key: 0,
// This is the url that you would send a POST request to that will handle the call.
url: 'http://www.example.com/image/remove',
// Any extra data that you would like to add to the POST request
extra: {
key: value
}
}
]
You would need to create an object for each item you have within your initialPreview array.
The OP's .fileinput would become:
$("#image").fileinput({
overwriteInitial: false,
initialPreview: [
// IMAGE DATA
"http://digitalbroker.test/storage/properties/847%20Queen%20Street%20West,%20Toronto,%20ON,%20Canada_1.JPG",
// IMAGE DATA
"http://digitalbroker.test/storage/properties/847%20Queen%20Street%20West,%20Toronto,%20ON,%20Canada_2.JPG",
],
initialPreviewConfig: [
{
key: 0,
url: '/image/remove', //custom URL
extra: {
image: '847 Queen Street West, Toronto, ON, Canada_1.JPG
}
},
{
key: 1,
url: '/image/remove', //custom URL
extra: {
image: 847 Queen Street West, Toronto, ON, Canada_2.JPG
}
},
],
initialPreviewAsData: true, // identify if you are sending preview data only and not the raw markup
initialPreviewFileType: 'image', // image is the default and can be overridden in config below
initialPreviewDownloadUrl: 'http://kartik-v.github.io/bootstrap-fileinput-samples/samples/{filename}', // includes the dynamic `filename` tag to be replaced for each config
showUpload: false,
theme: 'fas',
uploadUrl: "/submit-mortgage",
uploadExtraData: function () {
return {
_token: $("input[name='_token']").val(),
};
},
allowedFileExtensions: ['jpg', 'png', 'gif', 'jpeg'],
overwriteInitial: true,
showCaption: false,
showRemove: true,
maxFileSize: 5000,
maxFilesNum: 8,
fileActionSettings: {
showRemove: true,
showUpload: false,
showZoom: true,
showDrag: false,
},
slugCallback: function (filename) {
return filename.replace('(', '_').replace(']', '_');
}
});
I hope this helps anybody who comes across it.
FYI this is my first answer on SO (please be kind :P )

Kendo UI Grid, editable mode not working for local data

I am working with the Kendo UI Grid. This is my code:
<body>
<div id="myGrid"></div>
<script type="text/javascript">
$(function(){
var rows = [
{name: "name001", id: "001", group: "G1"},
{name: "name002", id: "002", group: "G1"},
{name: "name003", id: "003", group: "G2"},
{name: "name004", id: "004", group: "G2"},
];
var myDataSource =
new kendo.data.DataSource({
data: rows,
pageSize: 3,
});
myDataSource.read();
$("#myGrid").kendoGrid({
dataSource: myDataSource,
columns: [
{field:"name", title:"The Name"},
{field:"id", title:"The Id"},
{field:"group"},
{command:["edit", "destroy"]}
],
scrollable: false,
pageable: true,
sortable: true,
groupable: true,
filterable: true,
editable: "inline"
});
});
</Script>
</body>
But the edit is not working. Opening this grid in a browser gives me a grid that looks as expected with an Edit and a Delete button. I can delete rows with the Delete button. But clicking Edit changes the row into edit mode (with input fields in cells) but changing a value and pressing the Update button does nothing. The row remains in edit mode and the Update button doesn't switch back to "Edit" as it's supposed to.
Can you tell me what's missing? Do I have to configure my datasource somehow?
Yes you missed to configure your Grid's dataSource to know how to update the records. I assume that you want to edit the records only locally (on the client) - without sending them to the server. To actually close the Grid and apply the changes you can use the save event of the Grid and the refresh method.
Here is a jsbin with your case.
If you want to save these changes to the server I suggest you to start with the demos.

Kendo UI Grid - Hide/Unhide of column in MVC3

My case is a search window with around 20 properties, in which the user can choose to specify search criteria. Each property has a corresponding checkbox which toggles if the prop is included in the search result or not. The search result is then displayed in a kendo grid.
Simplified code which should illustrate the issue (kendo ui complete ver. 2012.2.710):
<input type="checkbox" onclick="fnShowHide(1);" name="showSearchColumn" id="checkShowField1" />
<div id="example" class="k-content">
<div id="kendoGridTest"></div>
</div>
<script>
function fnShowHide( iCol )
{
$('#kendoGridTest').data("kendoGrid").options.columns[iCol].hidden = false;
$('#kendoGridTest').data("kendoGrid").refresh();
}
</script>
The MVC3-controller method returns data from search is of type JsonResult (given as jsonResultSearchResult below):
$('#kendoGridTest').kendoGrid({
dataSource: jsonResultSearchResult,
schema: {
model: {
fields: {
FirstName: { type: "string" },
LastName: { type: "string" },
Address: { type: "string" }
}
}
},
sortable: true,
resizable: true,
columns: [{
field: "FirstName",
width: 90,
title: "First name"
},
{
field: "LastName",
width: 120,
hidden: true,
title: "Last name"
},
{
field: "Address",
width: 140,
title: "Adr"
}
]
});
After performing a search, the grid fills with the right data and LastName is indeed hidden. But if the user now checks the checkShowField1 control, I would like the grid to refresh with all three cols visible. It does not. fnShowHide() does not do the job.
I must admit I was looking for anything of a type of Columns collection in a QuickWatch window while debugging in VS. The collection in fnShowHide contains the right data from when the grid was initialized, and I'm able to manipulate the .hidden property, but the grid still does not display the column.
I'm still a bit confused whether dynamic hide/show of cols is supported but this accepted answer from a Telerik employee looked promising.
To hide a column on the client side with JavaScript you should use the hideColumn() and to show it you use the showColumn(). Both methods have several overloads - you either pass the index of the column or you pass the name of the field the column is bound to.
For example:
var grid = $('#GridID').data('kendoGrid');
grid.hideColumn(2);
//or show it
grid.showColumn("OrderDate") // lets say thats the field name of the same column
The post you linked shows how to Hide/Show column with the MVC Wrappers which is slightly different.

combobox is not displaying data from ext.data.arraystore

iam using Ext.form.combobox to perform an autocomplete search, my data is stored in array store :ext.data.arraystore, actually the data in the array store is loaded via an ajax request, here is my arraystore code:
var ds = new Ext.data.ArrayStore({
fields: ['description','lat','lng'],
data: xmlarray
});
where xmlarray is a data array which is loaded from php server using ajax request
here is my combobox code:
var timePanel = {
xtype: 'panel',
border: false,
width: 600,
bodyPadding: 10,
layout: 'anchor',
items: [{
xtype:'combo' ,
displayField:'displayValue',
valueField: 'id',
store: ds,
mode: 'local',
typeAhead: true,
triggerAction: 'all',
hideTrigger:false,
lazyRender: true,
emptyText: 'select a city',
forceSelection: false,
typeAhead: true,
selectOnFocus: true,
enableKeyEvents:true,
listConfig: {
loadingText: 'Searching...',
emptyText: 'No matching posts found.',
// Custom rendering template for each item
getInnerTpl: function() {
return '<div class="search-item">' +
'<h3><span>{[Ext.Date.format(values.lastPost, "M j, Y")]}<br />by {author}</span>{title}</h3>' +
'{excerpt}' +
'</div>';
}
},
pageSize: 10,
//listeners: {select: this.GeocoderRequest};
}
]
};
my main problem is that the combobox shows me the a set of empty selection rows, while each selection row should show a name from my data but its empty instead..is there any problem in my arrastore or in combobox configurations ?
fields: ['description','lat','lng'],
...
displayField:'displayValue',
valueField: 'id',
There is no field named displayValue in the store, therefore combobox can't find values it is looking for.
Same goes for valueField.

Resources