How to pass values from form to datatables - ajax

I am playing with laravel and datatables.
Here is the table with filtering option in the form I want to understand.
Basically configured routes and controllers as in the example but cannot dynamically get values from a drop down list below via ajax.
<select class="form-control" id="asortment" name="asortment">
<option value="68">A</option>
<option value="5">B</option>
...
Javascript responsible for ajax communication:
<script type="text/javascript" charset="utf8" src="//cdn.datatables.net/1.10.16/js/jquery.dataTables.js"></script>
<script>
$(document).ready( function () {
$('#datatable').DataTable({
"processing": true,
"serverSide": true,
"ajax": {
url: "{{ route('api.products.index') }}",
data: function (d) {
d.product = $('input[name=product]').val();
d.fromDate = $('input[name=fromDate]').val();
d.toDate = $('input[name=toDate]').val();
d.asortment = $('input[name=asortment]').val();
},
},
"columns": [
{ "data": "Name", },
{ "data": "Type" },
{ "data": "Asortment" },
{ "data": "Margin" }
]
});
});
$('#search-form').on('submit', function(e) {
oTable.draw();
e.preventDefault();
});
</script>
My API controller looks like this:
class APIController extends Controller
{
public function getProducts(Request $request)
{
$product = $request->input('product');
$fromDate = $request->input('fromDate');
$toDate = $request->input('toDate');
$asortment = $request->input('asortment');
$query = DB::select('exec test.dbo.Products #startDate = ?, #endDate = ?, #asortment = ?, #produkt = ?', [$fromDate, $toDate, $asortment, $product]);
return datatables($query)->make(true);
}
}
Problem: Ajax takes 3 values (product, fromDate, toDate) but doesn't accept asortment, which is in select form.
I need a little help on why...:)

Instead of Using $('input[name=asortment]').val(); change it to $("#asortment").val(); (Pure jQuery way!).
$('input[name=YOUT_NAME]').val(); doesn't work with Radio Button/Select/Checbox.
val() allows you to pass an array of element values. This is useful
when working on a jQuery object containing elements like , , and s inside of a
. In this case, the inputs and the options having a value that
matches one of the elements of the array will be checked or selected
while those having a value that doesn't match one of the elements of
the array will be unchecked or unselected, depending on the type. In
the case of s that are part of a radio group and
s, any previously selected element will be deselected.
Setting values using this method (or using the native value property)
does not cause the dispatch of the change event. For this reason, the
relevant event handlers will not be executed. If you want to execute
them, you should call .trigger( "change" ) after setting the value.
This is mentioned in jQuery's documentation.

Related

Django / Ajax / Datatable

I am trying to use following code in order to make a GET request to my django-based local server & render the obtained JSON-formatted data as a table:
$(document).ready(function (){
var rows_selected = [];
var table = $('#example').DataTable({
'ajax': $("#active_subscriptions_url").attr("data-ajax-target"),
'cache': true,
'columnDefs': [{
'targets': 0,
'searchable':false,
'orderable':false,
'width':'1%',
'className': 'dt-body-center',
'render': function (data, type, full, meta){
return '<input type="checkbox">';
}
}],
'order': [1, 'asc'],
'cache': true,
'rowCallback': function(row, data, dataIndex){
// Get row ID
var rowId = data[0];
// If row ID is in the list of selected row IDs
if($.inArray(rowId, rows_selected) !== -1){
$(row).find('input[type="checkbox"]').prop('checked', true);
$(row).addClass('selected');
}
}
});
Unfortunately, it can not properly refer to the data, because each time this AJAX function adds a timestamp ad the end of a url:
http://127.0.0.1:8000/accounts/?_=1530637137189
I can not get rid of it - I have tried using 'cache' paremeter in Ajax, but it does not work.
Moreover, I ve tried to extend my urls.py with following position:
url(r'^accounts/(?P<timestamp>\?_=[0-9]*)/$', ShowSubscriptions.as_view(), name='show_subscriptions'),
But it does not match the coming request at all.

Vue.js Retrieving Remote Data for Options in Select2

I'm working on a project that is using Vue.js and Vue Router as the frontend javascript framework that will need to use a select box of users many places throughout the app. I would like to use select2 for the select box. To try to make my code the cleanest I can, I've implemented a custom filter to format the data the way select2 will accept it, and then I've implemented a custom directive similar to the one found on the Vue.js website.
When the app starts up, it queries the api for the list of users and then stores the list for later use. I can then reference the users list throughout the rest of the application and from any route without querying the backend again. I can successfully retrieve the list of users, pass it through the user list filter to format it the way that select2 wants, and then create a select2 with the list of users set as the options.
But this works only if the route that has the select2 is not the first page to load with the app. For example, if I got to the Home page (without any select2 list of users) and then go to the Users page (with a select2), it works great. But if I go directly to the Users page, the select2 will not have any options. I imagine this is because as Vue is loading up, it sends a GET request back to the server for the list of users and before it gets a response back, it will continues with its async execution and creates the select2 without any options, but then once the list of users comes back from the server, Vue doesn't know how to update the select2 with the list of options.
Here is my question: How can I retrieve the options from an AJAX call (which should be made only once for the entire app, no matter how many times a user select box is shown) and then load them into the select2 even if the one goes directly to the page with the select2 on it?
Thank you in advance! If you notice anything else I should be doing, please tell me as I would like this code to use best practices.
Here is what I have so far:
Simplified app.js
var App = Vue.extend({
ready: function() {
this.fetchUsers();
},
data: function() {
return {
globals: {
users: {
data: []
},
}
};
},
methods: {
fetchUsers: function() {
this.$http.get('./api/v1/users/list', function(data, status, response) {
this.globals.users = data;
});
},
}
});
Sample response from API
{
"data": [
{
"id": 1,
"first_name": "John",
"last_name": "Smith",
"active": 1
},
{
"id": 2,
"first_name": "Emily",
"last_name": "Johnson",
"active": 1
}
]
}
User List Filter
Vue.filter('userList', function (users) {
if (users.length == 0) {
return [];
}
var userList = [
{
text : "Active Users",
children : [
// { id : 0, text : "Item One" }, // example
]
},
{
text : "Inactive Users",
children : []
}
];
$.each( users, function( key, user ) {
var option = { id : user.id, text : user.first_name + ' ' + user.last_name };
if (user.active == 1) {
userList[0].children.push(option);
}
else {
userList[1].children.push(option);
}
});
return userList;
});
Custom Select2 Directive (Similar to this)
Vue.directive('select', {
twoWay: true,
bind: function () {
},
update: function (value) {
var optionsData
// retrive the value of the options attribute
var optionsExpression = this.el.getAttribute('options')
if (optionsExpression) {
// if the value is present, evaluate the dynamic data
// using vm.$eval here so that it supports filters too
optionsData = this.vm.$eval(optionsExpression)
}
var self = this
var select2 = $(this.el)
.select2({
data: optionsData
})
.on('change', function () {
// sync the data to the vm on change.
// `self` is the directive instance
// `this` points to the <select> element
self.set(select2.val());
console.log('emitting "select2-change"');
self.vm.$emit('select2-change');
})
// sync vm data change to select2
$(this.el).val(value).trigger('change')
},
unbind: function () {
// don't forget to teardown listeners and stuff.
$(this.el).off().select2('destroy')
}
})
Sample Implementation of Select2 From Template
<select
multiple="multiple"
style="width: 100%"
v-select="criteria.user_ids"
options="globals.users.data | userList"
>
</select>
I may have found something that works alright, although I'm not sure it's the best way to go about it. Here is my updated code:
Implementation of Select2 From Template
<select
multiple="multiple"
style="width: 100%"
v-select="criteria.reporting_type_ids"
options="globals.types.data | typeList 'reporttoauthorities'"
class="select2-users"
>
</select>
Excerpt from app.js
fetchUsers: function() {
this.$http.get('./api/v1/users/list', function(data, status, response) {
this.globals.users = data;
this.$nextTick(function () {
var optionsData = this.$eval('globals.users.data | userList');
console.log('optionsData', optionsData);
$('.select2-users').select2({
data: optionsData
});
});
});
},
This way works for me, but it still kinda feels hackish. If anybody has any other advice on how to do this, I would greatly appreciate it!
Thanks but I'm working on company legacy project, due to low version of select2, I encountered this issue. And I am not sure about the v-select syntax is from vue standard or not(maybe from the vue-select libaray?). So here's my implementation based on yours. Using input tag instead of select tag, and v-model for v-select. It works like a charm, thanks again #bakerstreetsystems
<input type="text"
multiple="multiple"
style="width: 300px"
v-model="supplier_id"
options="suppliers"
id="select2-suppliers"
>
</input>
<script>
$('#app').ready(function() {
var app = new Vue({
el: "#app",
data: {
supplier_id: '<%= #supplier_id %>', // We are using server rendering(ruby on rails)
suppliers: [],
},
ready: function() {
this.fetchSuppliers();
},
methods: {
fetchSuppliers: function() {
var self = this;
$.ajax({
url: '/admin_sales/suppliers',
method: 'GET',
success: function(res) {
self.suppliers = res.data;
self.$nextTick(function () {
var optionsData = self.suppliers;
$('#select2-suppliers').select2({
placeholder: "Select a supplier",
allowClear: true,
data: optionsData,
});
});
}
});
},
},
});
})
</script>

ajax call does not work in angular js

I have the scenario as follow:
I have a text box and button and whenever I add sth in textbox I want to add the text in the table my code is as follow:
var app = angular.module('app', []);
app.factory('Service', function() {
var typesHash = [ {
id :1,
name : 'lemon',
price : 100,
unit : 2.5
}, {
id : 2,
name : 'meat',
price : 200,
unit : 3.3
} ];
var localId = 3;
var service = {
addTable : addTable,
getData : getData,
};
return service;
function addTable(name) {
typesHash.push({id:localId++, name:name, price:100,unit:1});
}
function getData() {
return typesHash;
}
});
app.controller('table', function(Service) {
//get the return data from getData funtion in factory
this.typesHash = Service.getData();
//get the addtable function from factory
this.addTable = Service.addTable;
});
and the plnkr is as follow:
plnkr
Now as you can see I add whatever inside the text in the table and everything works fine but now I want to add whatever inside the textbox and also I want to get some information from the servlet and add those to the table as well. so for that I use ajax call as follow:
function addTable(name) {
typesHash.push({id:localId++, name:name, price:100,unit:1});
var responsePromise = $http.get("http://localhost:8080/purchase/AddInfo");
responsePromise.success(function(data, status, headers, config) {
typesHash.push( {id:data.id,name : data.name, price : data.price,unit:2.5 });
});
}
but when I use that I get he following error:
ReferenceError: $http is not defined
can anyone help? (just a quick note: this code is smaller version of my real code and I purposely used factory since I need it)
inside of your controller attr your should insert an $http argument:
app.controller('CTRL1', function($scope, $http){
//Now your can use $http methods
})
or insert $http argument in your service decleration if you are using $http request methods from inside of your service

Prepopulate select option with JSON

I'm trying to pre-populate a form made with angularJS with previously inserted data using JSON
Everything is working fine except for the select option items that are not populated.
A JSON example I'm using is:
{
"date": "2014-09-14",
"enumerator": "a",
"monthreport": {
"value": "March"
},
"weekreport": {
"value": "2nd week"
},
"Maize": 23,
"Wheat": 41,
"Sorghum": 71,
"q14": "Yes"
}
monthreport and weekreport are select option and they are not filled in when the form is loaded.
q14 is a radiobutton, and it works fine as all the other input text field, both text and numeric.
The JSON is the one produced exactly by angularJS, when I fill in the data in the form and then save it.
the select element is specified in this way in the HTML:
<select ng-model="currForm.weekreport" ng-options="o.value for o in options16" name="r_weekreport" required ></select>
and the options are set in the controller:
...
$scope.options16= [{value:"1st week"},{value:"2nd week"},{value:"3rd week"},{value:"4th week"},{value:"5th week"}];
...
To load JSON I use the usual function inside the app.controller:
...
$http({
method: 'GET',
url: 'http://samplesite.com/formJSON.txt'
}).success(function(data, status) {
console.log('works!!! ' + data);
$scope.currForm = data; }).error(function(data, status) {
// Some error occurred
console.log(status);
})
...
it seems everything right... where I'm wrong??
You can try:
<select ng-model="currForm.weekreport.value" ng-options="o.value as o.value for o in options16" name="r_weekreport" required ></select>
This happens because angular compares objects in your example and they are not equal. You need to compare primitives.

how to select all records in the grid in order to export the data

I am trying to select all the data present in the jqgrid table in order to export in to an excel file. But the data present in the first page of the grid is only getting exported. i.e., if a total of 25 records are present in the grid and 5 records are present in the first page, then only first 5 records are getting exported.
The following code is responsible for displaying records 'only' in the first page of the grid..
var gridData = $("#list").jqGrid('getRowData');
The following code is responsible for displaying records present in all the pages in the grid..
var gridData1 =jQuery("#list").jqGrid('getGridParam','data');
how to use the above code such that I can select all the records present in the grid. also, I am trying to apply filter on the records present in the grid. In such a case, how to get the filtered number of records in order to export them..?
Thanks,
You can do it server side.
<script type="text/javascript">
$(document).ready(function () {
$('#list').jqGrid({
caption: "test",
// ...
}).navGrid(
// ...
}).jqGrid('navButtonAdd', '#pager', {
caption: "", buttonicon: "ui-icon-print", title: "export",
onClickButton: function () {
$("#list").jqGrid('excelExport', { url: 'path......' });
}
});
});
</script>
excelExport method, sends the current page number, sort field, filtering, etc to the specified url. now you have time to process these parameters and create a new output.
You may want to try below script and function:
<script type='text/javascript'>
var tableToExcel = (function () {
var uri = 'data:application/vnd.ms-excel;base64,'
, template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>'
, base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) }
return function (table, name) {
if (!table.nodeType) table = document.getElementById(table)
var ctx = { worksheet: name || 'Worksheet', table: table.outerHTML }
window.location.href = uri + base64(format(template, ctx))
}
})();
$(document).ready(function () {
...declare & setup the jqGrid with 'big row page', e.g. ...
rowNum: 9999,
rowList: [50, 100, 200, 9999],
.........then add below navigation button after setup the grid...
$("#list").jqGrid('navButtonAdd', pgrid1, {caption:"Download",title:"Download report contents", buttonicon :'ui-icon-circle-arrow-s',
onClickButton:function(){
tableToExcel('list', 'export data')
}
});
}
</script>
Alternatively, another way to exporting can refer to related question:
How to enable jQgrid to Export data into PDF/Excel

Resources