Custom rowCount for jquery bootgrid? - jquery-plugins

Hi I use in my project bootgrid I did custom lenght dropdown, evrithing is working apart the table pagination Is there a whay this to be fixed? Here is my code:
var $table = $("#data-table");
$table.bootgrid({
ajax: true,
url : 'myfancyurl',
columnSelection : false,
templates: {
//header: "" //Removes default bootgrid header
},
css : {
icon: 'md icon',
iconColumns: 'md-view-module',
iconDown: 'md-expand-more',
iconRefresh: 'md-refresh',
iconUp: 'md-expand-less'
},
labels :{
all:'',
loading:''
},
requestHandler: function (request) {
request.searchPhrase = $("#search-phrase").val();
request.rowCount = parseInt($('#row-count li.active').text());
return request;
}
}
});
$('#row-count li').on('click', function(e){
$('#row-count li').removeClass('active');
$(this).addClass('active');
$('.row-count').text( $(this).text() );
$table.bootgrid("reload");
});
So when I change lenght on backend side works fine, but the bootgrid doesn't recalc pagination when I pass the rowCount from request. Thanks in advance if someone can help.

I don't understand your question correctly.
You can add custom rowCount using the rowCount property
var $table = $("#data-table");
$table.bootgrid({
ajax: true,
url : 'myfancyurl',
columnSelection : false,
**rowCount: [10, 25, 33, 50, 66, 100],**
templates: {
//header: "" //Removes default bootgrid header
},...
and then in the backend you can use the request param
rowCount= request.args.get('rowCount', 33)

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>

Zend Framework 2: Populate ajax table (DataTable)

Below is snippet of table-ajax.js file from DataTable module.
My question is what will be Ajax url instead of table_ajax.php if I use IndexAction{} in my Controller. I want to display data from database.
var handleRecords = function () {
var grid = new Datatable();
grid.init({
src: $("#datatable_ajax"),
onSuccess: function (grid) {
},
onError: function (grid) {
},
onDataLoad: function(grid) {
},
loadingMessage: 'Loading...',
dataTable: {
"bStateSave": true, // save datatable state(pagination, sort, etc) in cookie.
"lengthMenu": [
[10, 20, 50, 100, 150, -1],
[10, 20, 50, 100, 150, "All"] // change per page values here
],
"pageLength": 10, // default record count per page
"ajax": {
"url": "table_ajax.php", // ajax source
},
"order": [
[1, "asc"]
]// set first column as a default sort by asc
}
});
Firstly you'll need to add a strategy to your viewmanager so you can return json. This is done within your module.config like so:
'view_manager' => array(
...
'strategies' => array(
'ViewJsonStrategy'
),
...
),
I'll just assume you have this DataTableModule imported via your Autoloader. So you can extend or implement the "table_ajax.php" within your controller and override/add a return value as a zf2 JsonModel.
In your Action within your Controller that extends/implements ajax_table.php
...
return new JsonModel($whateverTheResultIs);
...
Now that you have a controller that returns your JSON you'll require to set up a route. This is pretty straight forward it only links to your controller action and since you defined a strategy in your Viewmanager ZF2 does the rest of the pesky ajax stuff for you.
Edit: Rather then extending the table_ajax.php in your controller it probably is a good idea to write a Service which retrieves the information from table_ajax.php.

ExtJs 3 TreePanel Sorting not working

I am using Ext.ux.tree.TreeGrid for tree grid panel. All is working fine except sort.
I have 3 level of hierarchy in it like - parent - child - grand child. I want to make sorting based on text of parent only. But I am getting random result every time. :(
This is my code -
var tree_grid = new Ext.ux.tree.TreeGrid({
title : 'Requirements',
height : 415,
enableDD : true,
enableHdMenu : true,
id : 'req_tree',
columns : [ {
header : 'Entity',
dataIndex : 'text',
width : 200,
sortable: true,
sortType : 'asText'
}, {
header : 'Text',
width : 50,
dataIndex : 'temp',
align : 'center',
// sortType : 'asFloat',
sortable: false
}],
dataUrl : 'my_page.php'
});
For sorting I have tried this -
1) var myTreeSorter = new Ext.tree.TreeSorter(tree_grid, {});
myTreeSorter.doSort(tree_grid.getRootNode());
2) new Ext.ux.tree.TreeGridSorter(tree_grid, {
folderSort: true,
dir: "desc",
sortType: function(node) {
// sort by a custom, typed attribute:
return parseInt(node.id, 10);
}
});
3) Used Attributes like - sortType, sortable, sortInfo.
None of the above helped me however. Please help.
var mySortStore = Ext.create("Ext.data.Store", {
model: "MyTreeStore",
data: []
});
Then when you go to add the node to the tree, use this function instead:
function addNodeSorted(node, childToBeAdded){
//clear the store from previous additions
mySortStore.removeAll();
//remove old sorters if they are dynamically changing
mySortStore.sort();
//add the node into the tree
node.appendChild(childToBeAdded);
var cn = node.childNodes,
n;
//remove all nodes from their parent and add them to the store
while ((n = cn[0])) {
mySortStore.add(node.removeChild(n));
}
//then sort the store like you would normally do in extjs, what kind of sorting you want is up to you
mySortStore.sort('height', 'ASC');//this is just an example
//now add them back into the tree in correct order
mySortStore.each(function(record){
node.appendChild(record);
});
}
Did you tried to use the config folderSort on the store:
TreeGrid Example: sencha TreeGrid
var store = Ext.create('Ext.data.TreeStore', {
model: 'Task',
proxy: {
type: 'ajax',
//the store will get the content from the .json file
url: 'treegrid.json'
},
**folderSort: true**
});
--
Other solution, can be used a sort filter on the store:
Store Sort: sencha sort
//sort by a single field
myStore.sort('myField', 'DESC');
//sorting by multiple fields
myStore.sort([
{
property : 'age',
direction: 'ASC'
},
{
property : 'name',
direction: 'DESC'
}
]);

Issues with knockout observable array validation

I have an issue with a validation rule that I put on observablearray elements. I'm using a custom message template to display the errors, the issue is that it doesn't get displayed on when the errors are there, however, I can see the '*' against the relevant field. Following is my model:
function ViewModel(item) {
var parse = JSON.parse(item.d);
var self = this;
this.ID = ko.observable(parse.ID).extend({ required: { params: true, message: "ID is required" }});
this.Name = ko.observable(parse.Name);
this.WeeklyData = ko.observableArray([]);
var records = $.map(parse.WeeklyData, function (data) { return new Data(data) });
this.WeeklyData(records);
}
var Data = function (data) {
this.Val = ko.observable(data).extend({
min: { params: 0, message: "Invalid Minimum Value" },
max: { params: 168, message: "Invalid Maximum Value" }
});
Here is the validation configuration I'm using:
// enable validation
ko.validation.configure({
registerExtenders: true,
messagesOnModified: false,
insertMessages: true,
parseInputAttributes: false,
messageTemplate: "customMessageTemplate",
grouping: { deep: true }
});
ko.validation.init();
Any my custom message template goes like this:
<script id="customMessageTemplate" type="text/html">
<em class="errorMsg" data-bind='visible: !field.isValid()'>*</em>
</script>
<ul data-bind="foreach: Errors">
<li class="errorMsg" data-bind="text: $data"></li>
</ul>
With this implementation, I don't see the validation messages in the custom template. But if I remove the configuration deep: true, it doesn't validate the observable array elements, but the other observable(ID) and then the message is displayed properly.
I'm very confused with this and a bit stuck, so appreciate if someone can help/
Thanks in advance.
What i understand from your question is that you are trying to validate your observableArray entries, so that if any entry in your WeeklyData observableArray fails the following condition:
arrayEntry % 15 === 0
you want to show error message. If this is the case, than the following custom validator can do the job for you :
var fminIncrements = function (valueArray) {
var check = true;
ko.utils.arrayFirst(valueArray, function(value){
if(parseInt(value, 10) % 15 !== 0)
{
check = false;
return true;
}
});
return check;
};
And you have to apply this validator on the observableArray (no need to set validation on individual entries of the array). This validator takes array as input and validate its each entry, if any one entry fails the validation it will retrun false and than you will see the error message.
Your viewmodel looks like :
function viewModel() {
var self = this;
self.WeeklyData = ko.observableArray([
15,
40
]).extend({
validation: {
validator: fminIncrements,
message: "use 15 min increments"
}
});
self.errors = ko.validation.group(self);
}
And here is the working fiddle.
the individual item is not showing the message - it's only in the summary - how do you specify the message on the individual textbox ?

Resources