How to persist Data Table selected items after data is updated/refreshed (Quasar-Framework) - javascript

I'm using Quasar Framework with VueJS. I have a Data Table component that allows single item selection. The Data Table data is automatically updated every 5 seconds through websockets events. If I have an item selected, every time the Data Table data is updated, that item gets deselected, and I would like to persist the item selection after the data is updated.
Is there a way to accomplish this? I was thinking in two different approachs, but I have no idea how to do it, at least not from the documentation:
access directly the Data Table selected item
handle an event fired when an item is selected
In both cases the main idea would be to save the selection in a store, an restore the selection when the Data Table items update is done.
<template>
<q-layout>
<!-- Main block start-->
<div class="scroll" style="width: 100%">
<div class="layout-padding">
<div class="row" style="margin-top: 30px;">
<q-data-table :data="dataTableData" :config="config" :columns="columns" #refresh="refresh">
</q-data-table>
</div>
</div>
</div>
<!-- Man block end-->
</q-layout>
</template>
<script>
export default {
sockets:{
connect: function(){
console.log('socket connected')
},
info: function(data){
console.log('sockets: info',data)
//This is where I should get the current selected item if exists
this.dataTableData = data;
//This is where I should restore the selected item
}
},
methods: {
getInfo: function(val){
this.$socket.emit('getInfo', val);
},
refresh (done) {
this.$socket.emit('getInfo');
done();
}
},
created: function(){
this.getInfo()
},
data: function () {
return {
dataTableData: [],
config: {
title: 'My Data Table',
refresh: true,
columnPicker: false,
leftStickyColumns: 0,
rightStickyColumns: 0,
rowHeight: '50px',
responsive: true,
selection: 'single',
messages: {
noData: '<i>warning</i> No data available to show.'
}
},
columns: [
{ label: 'Name', field: 'name', width: '200px', sort: true },
{ label: 'Size', field: 'size', width: '50px', sort: true },
{ label: 'Status', field: 'status', width: '50px', sort: true },
{ label: 'Progress', field: 'progress', width: '150px', sort: false },
{ label: 'Speed', field: 'speed', width: '50px', sort: false },
{ label: 'ETA', field: 'eta', width: '50px', sort: false }
],
pagination: false,
rowHeight: 50,
bodyHeightProp: 'auto',
bodyHeight: 'auto'
}
},
watch: {
}
}
</script>
UPDATE
As far as I can see, they're already working in this enenhancement for the Quasar-Framework v0.14 =)

Related

Enable jquery-jtable hidden fields if a certain condition is met using jtable events

My aim is to only show bank related field if selected category is bank.
$('#EditDataTableDaybooks').jtable({
title: 'Accounts Daybook',
paging: true, //Enable paging
pageSize: 25, //Set page size (default: 10)
sorting: true, //Enable sorting
defaultSorting: 'DaybookCode DSC',
actions: {
listAction: '/adminaccounts/get_daybook_list',
updateAction: '/adminaccounts/update_daybook_entry',
},
fields: {
Daybook_key: {
title: 'Daybook_key',
key : true ,
width: '3%',
edit: false,
visibility: 'hidden'
},
DaybookCode: {
title: 'Sr.No.',
create: true,
edit: false,
width: '5%',
key: true,
sorting: true,
},
DaybookGroup: {
title: 'Daybook Group',
width: '5%',
},
GroupName: {
title: 'Group Name',
width: '5%',
},
DaybookName: {
title: 'Daybook Name',
width: '10%',
},
ShortForm: {
edit: false,
title: 'Short Form',
width: '8%',
},
DaybookType: {
// edit: false,
title: 'Type',
width: '8%',
type: 'radiobutton',
visibility : 'show',
options: {'CA':'Cash',
'BN':'Bank',
'JV':'Journal Voucher',
'BJ':'Bill Journal',
'AB':'Adjustment Bill',
'DN':'Debit Note',
'CN':'Credit Note'},
},
These fields are kept hidden for initializing
account_name: {
type: 'hidden',
title: 'Account Name',
width: '10%',
},
account_number: {
type: 'hidden',
title: 'Account Number',
width: '10%',
},
ifsc_code: {
type: 'hidden',
title: 'Ifsc code',
width: '10%',
},
},
recordUpdated: function(event,data) {
console.log(data.serverResponse.error_message)
error_message = data.serverResponse.error_message
if (error_message != ''){
alert("Zoho Book Error: " + error_message)
}
console.log(event)
$.ajax({type:'POST',
url: '/adminaccounts/get_daybook_list',
success: function(responseText){
console.log(responseText)
$('#EditDataTableDaybooks').jtable('load');
},
});
},
formCreated: function(event, data) {
console.log(event);
console.log(data);
console.log(data.record.DaybookType);
if (data.record.DaybookType == 'BN'){
console.log('logic to enable hidden fields');
}
Blockquote
}
});
There are no built in methods for your requirements, but you have correctly identified that the formCreated event handler is the correct place to add some code.
It is worth understanding the DOM structure of the add/edit form created by jTable.
Any jTable field defined as hidden, is simply created as an input field of type hidden with no styling or styling structure applied.
All non-hidden fields are created with a <div class="jtable-input-field-container">. This div contains two further divs, one for the field label/title <div class="jtable-input-label"> and a second to contain the input element <div class="jtable-input jtable-text-input"> for example.
Furthermore if the inputClass is defined in the jTable field definition, that class appears in the input field itself.
Therefore following your original plan, you will need to delete the hidden fields , and create a structure of divs and inputs that will look like the rest of the jTable form.
Reversing your thinking and fully defining each field, you can use the formCreated function, to remove, hide or disable the field that you want to suppress.
The simplest is to give all the "hidden" fields inputClass: "hideableInput", then all that is needed in the formCreated function is data.form.find('.hideableInput').attr('disabled', true); to disable the fields.
data.form.find('.hideableInput').closest('div.jtable-input-field-container').remove(); will completely remove the field containers from the form, so there is nothing for the user to see, and no parameters will be sent to the server.

AngularJs Kendo Grid Detail Template: Updating based on selected row in detail template

I am playing around with the KendoUI AngularJS Grid detail template.
I would like to be able to update a panel based on a selected row in the detail template grid.
I have correctly wired up the on change event to select a value from the detail template grid. But when I try to update a variable on the $scope object the value remains the same (the default value).
What is causing the variable on the #scope object not to update?
<div id="example">
<div ng-controller="MyCtrl">
<kendo-grid options="mainGridOptions">
<div k-detail-template>
<kendo-tabstrip>
<ul>
<li class="k-state-active">Orders</li>
<li>Contact information</li>
</ul>
<div>
<div kendo-grid k-options="detailGridOptions(dataItem)"></div>
</div>
<div>
<ul class="contact-info-form">
<li><label>Country:</label> <input class="k-textbox" ng-model="dataItem.Country" /></li>
<li><label>City:</label> <input class="k-textbox" ng-model="dataItem.City" /></li>
<li><label>Address:</label> {{dataItem.Address}}</li>
<li><label>Home phone:</label> {{dataItem.HomePhone}}</li>
</ul>
</div>
</kendo-tabstrip>
</div>
</kendo-grid>
<div class="panel panel-default">
<div class="panel-heading">Content</div>
<div class="panel-body">
{{content}}
</div>
</div>
</div>
<script>
angular.module("app", [ "kendo.directives" ])
.controller("MyCtrl", function ($scope) {
$scope.content = 'test';
$scope.mainGridOptions = {
dataSource: {
type: "odata",
transport: {
read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Employees"
},
pageSize: 5,
serverPaging: true,
serverSorting: true
},
sortable: true,
selectable: true,
pageable: true,
dataBound: function() {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [{
field: "FirstName",
title: "First Name",
width: "120px"
},{
field: "LastName",
title: "Last Name",
width: "120px"
},{
field: "Country",
width: "120px"
},{
field: "City",
width: "120px"
},{
field: "Title"
}]
};
$scope.detailGridOptions = function(dataItem) {
return {
dataSource: {
type: "odata",
transport: {
read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
schema: {
model: {
id: "OrderID"
}
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 5,
filter: { field: "EmployeeID", operator: "eq", value: dataItem.EmployeeID }
},
scrollable: false,
sortable: true,
selectable: true,
change: onChange,
pageable: true,
columns: [
{ field: "OrderID", title:"ID", width: "56px" },
{ field: "ShipCountry", title:"Ship Country", width: "110px" },
{ field: "ShipAddress", title:"Ship Address" },
{ field: "ShipName", title: "Ship Name", width: "190px" }
]
};
};
function onChange(arg) {
console.log("The selected product id: [" + this.dataItem($(this.select()[0]).closest("tr")).id + "]");
$scope.content = this.dataItem($(this.select()[0]).closest("tr")).id;
}
})
I have tried using an inline Kendo provided on change function like this:
<div kendo-grid k-options="detailGridOptions(dataItem)" k-on-change="handleChange(data, dataItem, columns)"></div>
But it doesn't work correctly as the skope of data etc is the parent grid.
I figured out how to fix the issue
I changed selectable: true to selectable: "row".
I also added k-on-change="handleChange(data) to the child and parent grid and handle the change event with the following function on $scope:
$scope.handleChange = function (data) {
$scope.data = data;
};
It is much cleaner then the original approach I took and allows me to access the OrderID like this: {{data.OrderID}}

dynamically hide ExtJS 4 grid column when grouping on column

I have an ExtJS 4 gridPanel as below:
var grid = Ext.create('Ext.grid.Panel', {
store: store,
title: 'grid',
columns: [
{text: 'column 1', sortable: true, width: 70, dataIndex: 'column1'},
{text: 'column 2', sortable: true, width: 70, dataIndex: 'column2'},
{text: 'column 3', sortable: true, width: 70, dataIndex: 'column3'},
{text: 'column 4', sortable: true, width: 70, dataIndex: 'column4'},
],
renderTo: Ext.get('gridDiv'),
width: 800,
height: 600,
listeners: {
},
features: [{
ftype: 'grouping'
}]
});
I'm required to dynamically hide the column that the grid is being grouped by whenever the grid is grouped, and show all other columns - reshowing any previously hidden columns.
I understand that this would be a listener handler that catches the grouping changing, which would then fire column.hide().
Some pseudo-code:
...
listeners: {
groupchange: function(store, groupers, eOpts) {
groupers.forEach(function(group) {
grid.columns.forEach(function(column) {
if(column==group)
column.hide();
if(column==group)
column.show();
}
}
}
},
...
I'm not sure from the API documentation whether groupchange is an event that can be caught by the grid, rather than the store, how to access the contents of groupers, and what comparators are available to determine if a column is in groupers.
How should this listener event be structured? What are the correct events/methods/properties to use?
Found that the hiding is done on a store listener, despite the grid panel API making it look as though it can be done as a grid listener. I've worked off the first keys array value within the groupers, although you could just as easily use items[0].property value.
var store = Ext.create('Ext.data.Store', {
...
listeners:
{
groupchange: function(store, groupers, eOpts){
var column = groupers.keys[0];
productionItemGrid.columns.forEach(function(entry){
if(entry.dataIndex == column)
{
entry.setVisible(false);
}
else
{
entry.setVisible(true);
}
});
}
}
...
});

Show Row Details as a Popup/ToopTip form on Mouse Hover for each row in KendoUI Grid

I have a grid populated with data and
i want to show only 3 or 2 columns and hide rest of columns cause the grid goes very wide.
when the mouse is hovered over a row i want to show all the columns of that row as as popup /tooltip form.
Please help me with this. I searched a lot and only found out Editable popup and with button click not with hover.
function PopulateGrid() {
$("#recentNews").kendoGrid({
columns: [
{ field: 'Date', title: 'Date', width: 80,
template: '#=kendo.toString(toDate(NewsDate), "yyyy/MMM/dd") #'
},
{ field: 'TradeTime', title: 'Time', width: 60,
template: '#=kendo.toString(toDate(NewsTime), "hh:mm:ss") #'
},
{ field: 'Title', title: 'Description', width: 200 },
{ field: 'Country', title: 'Country', width: 40 },
{ field: 'Economy', title: 'Economoy', width: 40 }
],
dataSource: {
transport: {
read: {
url: 'Home/GetNews',
dataType: "json",
type: "POST"
}
},
schema: {
data: function (data) {
return data.data;
},
total: function (data) {
return data.total;
}
},
pageSize: 100
},
// change: onChange,
// dataBound: onDataBound,
dataBound: HoverOnGrid,
pageable: true,
sortable: true,
scrollable: true,
height: 565,
width: 2000
});
}
There are two separate questions about what you are trying to implement:
Bind hover to the Grid rows (easy).
Generate a popup / tooltip that shows the rest of the columns (easy but requires some amount of coding).
Since it seems that you have already defined a function called HoverOnGrid lets write it as:
function HoverOnGrid() {
$("tr", "#recentNews").on("mouseover", function (ev) {
// Invoke display tooltip / edit row
var rowData = grid.dataItem(this);
if (rowData) {
showTooltip(rowData);
}
});
}
where grid is:
var grid = $("#recentNews").kendoGrid({
...
}).data("kendoGrid";
Now, the tricky question, how to show a tooltip / popup... There is no predefined way of doing it, you should do it by yourself. The closes that you can get is defining HoverOnGrid as:
function HoverOnGrid() {
$("tr", "#recentNews").on("click", function (ev) {
grid.editRow(this);
})
}
and the Grid initialization say:
editable: "popup",
But this opens a popup but with fields on edit mode (something that you can hack defining in the dataSource.schema.model that all fields are not editable:
model: {
fields: {
Date: { editable: false },
TradeTime: { editable: false },
Title: { editable: false },
Country: { editable: false },
Economy: { editable: false }
}
}
But it still shows update and cancel buttons in the popup.
So, my recommendation is writing a piece of code that creates that tooltip.
EDIT: For hiding the tooltip you should first intercept the mouseout event:
$("tr", "#recentNews").on("mouseout", function (ev) {
// Hide Tooltip
hideTooltip();
});
where hideTooltip might be something as simple as:
var tooltipWin = $("#tooltip_window_id").data("kendoWindow");
tooltipWin.close()
assuming that you are always using the same id for the tooltip (in this example, tooltip_window_id).

Kendo UI duplicated grid inside Kendo UI window with Knockout JS bindings

I'm working with Kendo UI and Knockout JS libraries and have a strange problem.
I'm trying to display kendo grid within kendo window, but the rows inside the grid get duplicated.
Here's a piece of code:
JS:
$(document).ready(function () {
var clients = { FilteredClients: [{ ClientName: '1', ClientCode: 'Value 1' }, { ClientName: '2', ClientCode: 'Value 2'}], Header: 'TEST' };
var viewModel = ko.mapping.fromJS(clients);
ko.applyBindings(viewModel);
var showClientLookupWindow = function () {
var window = $("#clientLookupWindow").data("kendoWindow");
window.center();
window.open();
}
$('#btnClientLookup').bind('click', showClientLookupWindow);
});
HTML:
<div>
<a id="btnClientLookup" href="#" class="k-button k-button-icontext k-grid-search"><span
class="k-icon k-search"></span>Client Lookup</a>
<span data-bind="text: Header"></span>
<div id="clientLookupWindow" data-bind="kendoWindow: { isOpen: false, visible: false, width: '600px', height: '230px', modal: true, resizable: false, title: 'Client Lookup'}">
<div id="gridClients" data-bind="kendoGrid: { data: FilteredClients, columns: [ { field: 'ClientName', title : 'Client Name' }, { field: 'ClientCode', title: 'Client Code' } ], scrollable: false, sortable: true, pageable: false }">
</div>
</div>
<div id="gridClientsOutside" data-bind="kendoGrid: { data: FilteredClients, columns: [ { field: 'ClientName', title : 'Client Name' }, { field: 'ClientCode', title: 'Client Code' } ], scrollable: false, sortable: true, pageable: false }">
</div>
</div>
Running it in the browser, we see that there are 2 rows in gridClientsOutside, but after clicking btnClientLookup, the window pops up with the gridClients, which consists of 4 rows.
Did anyone encounter this issue or have a workaround for this?
Thanks in advance,
Ihor
At a quick glance, it looks like the bindings inside the kendoWindow section are getting bound twice, which is causing the issue.
There bindings can run in an async mode and that is probably how kendoWindow should be set in the knockout-kendo library.
For the moment, you can do this:
<div id="clientLookupWindow" data-bind="kendoWindow: { async: true, isOpen: false, visible: false, width: '600px', height: '230px', modal: true, resizable: false, title: 'Client Lookup'}">
This adds async: true in the kendoWindow binding options. Otherwise, you could do ko.bindingHandlers.kendoWindow.options.async = true; to set it globally, before calling applyBindings.
Here is a sample: http://jsfiddle.net/rniemeyer/2MexC/

Categories

Resources