Related
I am using Datatables to display a table and I am pulling a list of datestimes from a MySQL database. These date times are not standard dates and look like this:
12/30/19 # 04:17 pm
How can I sort these accurately with Datatables?
Here is my code:
getRes(function (result) { // APPLIED CALLBACK
$('#resdatatable').DataTable({
data: result, // YOUR RESULT
order: [[ 0, "desc" ]],
autoWidth: false,
responsive: true,
columns: [
{ data: 'id', title: 'ID' },
{ data: 'bookingdatetime', title: 'Booking Date' },
{ data: 'name', title: 'Name' },
{ data: 'class', title: 'Class' },
{ data: 'pickupdatetime', title: 'Pick up' },
{ data: 'duration', title: 'Duration' },
{ data: 'dropdatetime', title: 'Drop off' },
{ data: 'age', title: 'Age' },
{ data: 'coverage', title: 'Coverage' },
{ data: 'quote', title: 'Quote' },
{
data: 'status',
title: 'Status',
render: function(data, type, row) {
let isKnown = statusList.filter(function(k) { return k.id === data; }).length > 0;
if (isKnown) {
return $('<select id="resstatus'+row.id+'" onchange="changeResStatus('+row.id+')" data-previousvalue="'+row.status+'">', {
id: 'resstatus-' + row.id, // custom id
value: data
}).append(statusList.map(function(knownStatus) {
let $option = $('<option>', {
text: knownStatus.text,
value: knownStatus.id
});
if (row.status === knownStatus.id) {
$option.attr('selected', 'selected');
}
return $option;
})).on('change', function() {
changeresstatus(row.id); // Call change with row ID
}).prop('outerHTML');
} else {
return data;
}
}
}
]
});
});
/**
* jQuery plugin to convert text in a cell to a dropdown
*/
(function($) {
$.fn.createDropDown = function(items) {
let oldTxt = this.text();
let isKnown = items.filter(function(k) { return k.id === oldTxt; }).length > 0;
if (isKnown) {
this.empty().append($('<select>').append(items.map(function(item) {
let $option = $('<option>', {
text: item.text,
value: item.id
});
if (item.id === oldTxt) {
$option.attr('selected', 'selected');
}
return $option;
})));
}
return this;
};
})(jQuery);
// If you remove the renderer above and change this to true,
// you can call this, but it will run once...
if (false) {
$('#resdatatable > tbody tr').each(function(i, tr) {
$(tr).find('td').last().createDropDown(statusList);
});
}
function getStatusList() {
return [{
id: 'Confirmed',
text: 'Confirmed'
}, {
id: 'Unconfirmed',
text: 'Unconfirmed'
}, {
id: 'Communicating',
text: 'Communicating'
}, {
id: 'Open',
text: 'Open'
}, {
id: 'Closed',
text: 'Closed'
}, {
id: 'Canceled',
text: 'Canceled'
}, {
id: 'Reallocated',
text: 'Reallocated'
}, {
id: 'No Show',
text: 'No Show'
}];
}
I need to sort bookingdatetime, pickupdatetime, dropdatetime accurately (they are currently being converted into MM/DD/YY in the PHP script)
Maybe you can prepend hidden <span> elements containing the respective unix timestamps in the cells that have dates (by manually parsing the dates). Then using such columns to sort alphabetically would practically sort time-wise.
I have some store, which is formed data. On panel it looks how "fieldName" and text field (in depension from invoked form). For example, on one form is displayed "name document" and field, on another: date of selling and date field. Data is formed dynamicly
Here is store:
tableTempStore = new Ext.data.JsonStore({
url: objectUrlAddress,
baseParams: {
'objectID': objectID
},
root: 'Fields',
fields: [{
name: 'Type',
type: 'int'
}, {
name: 'Value'
}, {
name: 'IsRequired',
type: 'bool'
}, {
name: 'Identifier'
}, {
name: 'Data'
}],
listeners: {
load: function(obj, records) {
Ext.each(records, function(rec) {
var item = null;
switch (rec.get('Type')) {
case 0:
item = new Ext.form.NumberField();
item.id = rec.get('Identifier');
item.fieldLabel = rec.get('Hint');
var isRequired = rec.get('IsRequired');
item.anchor = '100%';
item.allowBlank = !isRequired;
item.disabled = editDisabled;
item.value = rec.get('Data');
break;
case 1:
item = new Ext.form.NumberField();
item.id = rec.get('Identifier');
item.fieldLabel = rec.get('Hint');
var isRequired = rec.get('IsRequired');
item.anchor = '100%';
item.allowBlank = !isRequired;
item.allowDecimals = true;
item.disabled = editDisabled;
item.value = rec.get('Data');
break;
}
if (item != null) {
templateGrids.add(item);
columnsTable = item.__proto__.constructor.xtype;
source[item.fieldLabel] = '';
var s = null;
if (columnsTable == 'textfield')
{
s = 'textfield';
colm = {
xtype: s,
id: item.id,
allowBlank: item.allowBlank,
format: item.format,
value: item.value,
editable: true,
emptyText: item.emptyText,
disabled: item.disabled
};
}
else if (columnsTable == 'combo')
{
s = 'combo';
colm = {
xtype: s,
id: item.id,
allowBlank: item.allowBlank,
format: item.format,
value: item.value,
editable: true,
emptyText: item.emptyText,
disabled: item.disabled
};
}
else if (columnsTable == 'datefield')
{
s = 'datefield';
colm = {
xtype: s,
id: item.id,
allowBlank: item.allowBlank,
format: item.format,
value: item.value,
editable: true,
emptyText: item.emptyText,
disabled: item.disabled
};
}
});
for (var i = 0; i < templateGrids.getStore().data.length; i++) {
templateGrids.getColumnModel().setConfig([
{header: 'Name', id:'name', width:200},
{header:'Value', id:'val', dataIndex: rec.get('Value'), editable:true, width:200, editor: colm}]);
};
}
}
});
This code had worked in a form, but I need to use Grid (or Editor Grid). I know, how displayed field name ("document name" and etc.), but I don't understand, how displayed text field or etc. I try use loop, but on second column in xtype displayed last type in store. How i can resolve this problem?!
Here is a grid:
var templateGrids = new Ext.grid.EditorGridPanel({
id: 'tableId',
height:300,
width: '100%',
clicksToEdit:1,
frame: true,
store: tableTempStore,
columns: [
{header: 'Name'},
{header: 'Value'}]
});
I have some store, which is formed data. On panel, it looks how "fieldName" and text field (in depension from invoked form).
For example, on one form is displayed "name document" and field, on another: date of selling and date field. Data is formed dynamically.
Here is store:
tableTempStore = new Ext.data.JsonStore({
url: objectUrlAddress,
baseParams: {
'objectID': objectID
},
root: 'Fields',
fields: [{
name: 'Hint'
}, {
name: 'Type',
type: 'int'
}, {
name: 'Value'
}, {
name: 'Index',
type: 'int'
}, {
name: 'IsRequired',
type: 'bool'
}, {
name: 'Identifier'
}, {
name: 'EnumList'
}, {
name: 'Directory'
}, {
name: 'Data'
}],
listeners: {
load: function (obj, records) {
Ext.each(records, function (rec) {
var item = null;
switch (rec.get('Type')) {
case 0: // целое
item = new Ext.form.NumberField();
item.id = rec.get('Identifier');
item.fieldLabel = rec.get('Hint');
var isRequired = rec.get('IsRequired');
item.anchor = '100%';
item.allowBlank = !isRequired;
item.disabled = editDisabled;
item.value = rec.get('Data');
break;
case 1: // вещественное
item = new Ext.form.NumberField();
item.id = rec.get('Identifier');
item.fieldLabel = rec.get('Hint');
var isRequired = rec.get('IsRequired');
item.anchor = '100%';
item.allowBlank = !isRequired;
item.allowDecimals = true;
item.disabled = editDisabled;
item.value = rec.get('Data');
break;
case 5: // SQL-справочник
var dataValues = Ext.util.JSON.decode(rec.get('EnumList'));
var dataArray = Object.keys(dataValues).map(function (k) {
return [k, dataValues[k]]
});
item = new Ext.form.ComboBox({
typeAhead: true,
width: '100%',
triggerAction: 'all',
forceSelection: true,
editable: false,
hiddenName: rec.get('Identifier'),
mode: 'local',
store: new Ext.data.ArrayStore({
fields: [{
name: 'myId',
type: 'string'
}, {
name: 'displayText'
}],
data: dataArray
}),
valueField: 'myId',
displayField: 'displayText',
disabled: editDisabled
});
item.id = '_' + rec.get('Identifier');
item.anchor = '100%';
item.fieldLabel = rec.get('Hint');
var isRequired = rec.get('IsRequired');
item.allowBlank = !isRequired;
item.value = rec.get('Data');
break;
}
if (item != null) {
templateGrids.add(item);
columnsTable = item.__proto__.constructor.xtype;
var s = null;
else if (rec.get('Type') == 4) {
var dataValues = Ext.util.JSON.decode(rec.get('EnumList'));
var dataArray = Object.keys(dataValues).map(function (k) {
return [k, dataValues[k]]
});
combo = new Ext.grid.GridEditor(new Ext.form.ComboBox({
id: item.id,
allowBlank: item.allowBlank,
typeAhead: true,
lazyRender: true,
triggerAction: 'all',
forceSelection: true,
queryMode: 'local',
editable: false,
value: item.value,
hiddenName: rec.get('Identifier'),
mode: 'local',
store: new Ext.data.ArrayStore({
fields: [{
name: 'myId',
type: 'string'
}, {
name: 'displayText',
type: 'string'
}],
data: dataArray
}),
valueField: "myId",
displayField: "displayText",
disabled: editDisabled
}));
}
source[item.fieldLabel] = '';
grid.customEditors['Сохранить в'] = combo;
grid.getColumnModel().setConfig([{
header: "Поле"
}, {
header: "Значение",
dataIndex: '',
renderer: Ext.util.Format.comboRenderer(combo)
}]);
grid.setSource(source);
};
});
}
}
});
Here's my property grid:
grid = new Ext.grid.PropertyGrid({
url: objectUrlAddress,
id: 'propGrid',
autoFill: true,
autoHeight: true,
width: 200,
store: tableTempStore,
width: 600,
style: 'margin:0 auto;margin-top:10px;'
});
Problem with combo box. It show itemValue instead fieldValue on cell, and I don't know how to resolve this problem. How can I do? Thanks in advance.
For rendering I used function:
Ext.util.Format.comboRenderer = function (combo) {
return function (value) {
var record = combo.findRecord(combo.valueField, value);
return record ? record.get(combo.displayField) : combo.valueNotFoundText;
}
};
But it not worked.
I am trying to use multiselector from EXTJS 6.5.2
This is the code that I am using to create multiselector with the values that I need
{
xtype: 'multiselector',
title: 'I caktohet:',
name: 'Caktohen[]',
bind: '{userfullname.value}',
fieldName: 'userfullname',
viewConfig: {
deferEmptyText: false,
emptyText: 'Askush i zgjedhur'
},
search: {
field: 'userfullname',
model: 'InTenders.model.UserModel',
store: {
type: 'users',
sorters: 'userfullname',
// proxy: {
// type: 'rest',
// limitParam: null,
// url: 'api/User'
// }
}
}
}
When I call form = win.down('form') records I can get all values except the multiselector values, they show like this on console.
Anyone can help me or guide me how to get the values?
Thank you.
//Code that I'm trying to get multiselector items and save them
saveTenderForm: function (button, e, eOpts) {
var userMultiSelector = Ext.getCmp('AssignedUsers'); //save assigned users
var selectedUsers = userMultiSelector.getStore().getData(); //get store and put them in array
var me = this,
win = button.up('window'),
form = win.down('form'),
// formApplyUpload = this.getFormApplyUpload(),
// var ko = win.items.items[0].items.items[0].value;
recordtenderUsers = Ext.create('InTenders.model.TenderSaveModel');
// recordtenderUsers = form.getRecord();
// record = form.getRecord(),
values = form.getValues();
// appFile = this.getApplicationFile(),
// callbacks;
recordtenderUsers.set(values);
recordtenderUsers.set('tenderUsers',selectedUsers.items);
// // me.showMask();
// if (form.isValid()) {
recordtenderUsers.save({
success: function (recordtenderUsers, operation) {
win.close();
me.hideMask();
},
failure: function (recordtenderUsers, operation) {
me.hideMask();
}
});
You can get value using multiselector.down('grid') this will return you the grid. And grid have method getSelection().
In this FIDDLE, I have created a demo. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create({
xtype: 'form',
renderTo: Ext.getBody(),
items: [{
xtype: 'multiselector',
title: 'Multi selector example',
fieldName: 'text',
viewConfig: {
deferEmptyText: false,
emptyText: 'No value selected'
},
search: {
field: 'text',
store: {
fields: [{
name: 'text',
type: 'string'
}],
data: [{
text: 'ABC'
}, {
text: 'ABC 1'
}, {
text: 'ABC 2 '
}, {
text: 'ABC 3'
}, {
text: 'ABC 4'
}]
}
}
}, {
xtype: 'button',
text: 'Get Value',
margin:15,
handler: function (btn) {
var multiselector = btn.up('form').down('multiselector');
if (multiselector.down('grid')) {
multiselector.down('grid').getSelection().forEach(rec => {
console.log(rec.get('text'));
});
}
}
}]
});
}
});
continuing with my app whose aim is to be able to edit an aggregated field and store the result of a computation on the various components of that aggregate in another field...
I am now able to properly retrieve my fields using an extension of the UserStory model, but I still cannot save my changes.
I am trying to check what's done in Ext.grid.plugin.RowEditing's edit event, and I notice that when I reach it, e.store.data.items[rowIdx].data contains all my expected values, its dirty and editing flags are false, but e.store.data.items[rowIdx].raw does NOT reflect that (it contains the Rally's original values, unmodified) - even if I try to edit the value in raw, it does not work:
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 1,
listeners: {
'edit': function (editor, e) {
e.store.data.items[e.rowIdx].raw.BusinessValues =
e.store.data.items[e.rowIdx].data.BusinessValues;
e.store.commitChanges();
}
}
})
]
Whole code follows, but I'm wondering if I should add a listener at model level instead?
Rally.onReady(function() {
Ext.define('BVApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
Rally.data.ModelFactory.getModel({
type: 'UserStory',
success: function(model) {
var weights = new Array(5, 3, 1, 3, 4, 4, 2, 2);
var BvTitles = new Array("Customers Impact", "Critical Path", "Usability", "Functionality", "Security", "Performance", "Integration", "Integrity", "Business Value");
//var BvTitlesFrench = new Array("Parc Client", "Chemin Critique", "Ergonomie", "Fonctionnalité", "Sécurité", "Performance", "Intégration", "Intégrité", "Valeur Métier");
// Thanks to question http://stackoverflow.com/questions/12517383/sdk2-links-in-rally-grids-and-column-width I can now remove flex from FormattedID column...
var fixedIDwithLink = Rally.ui.grid.FieldColumnFactory.getColumnConfigFromField( model.getField( 'FormattedID' ) );
fixedIDwithLink.flex = false;
fixedIDwithLink.width = 70;
function getOneBV( record, pos, newValue ) {
var ls_BvFieldStart, ls_BvFieldEnd, ls_BvFromBvField;
if ( pos < 1 ) return newValue; // ERROR in fact...
if ( pos > 8 ) return newValue;
ls_BvFieldStart = record.data.BusinessValues.substring( 0, pos-1 );
ls_BvFromBvField = record.data.BusinessValues.substring( pos-1, pos );
ls_BvFieldEnd = record.data.BusinessValues.substring( pos, 8 );
if ( newValue ) {
ls_BvFromBvField = newValue;
record.data.BusinessValues = ls_BvFieldStart + ls_BvFromBvField + ls_BvFieldEnd;
}
return ls_BvFromBvField;
}
function getbv( as_bvHolder ) {
var li_bv1, li_bv2, li_bv3, li_bv4, li_bv5, li_bv6, li_bv7, li_bv8, li_bvtotal;
li_bv1 = as_bvHolder.substring( 0,1 );
li_bv2 = as_bvHolder.substring( 1,2 );
li_bv3 = as_bvHolder.substring( 2,3 );
li_bv4 = as_bvHolder.substring( 3,4 );
li_bv5 = as_bvHolder.substring( 4,5 );
li_bv6 = as_bvHolder.substring( 5,6 );
li_bv7 = as_bvHolder.substring( 7,8 );
li_bv8 = as_bvHolder.substring( 8,9 );
li_bvtotal =
li_bv1*weights[0] +
li_bv2*weights[1] +
li_bv3*weights[2] +
li_bv4*weights[3] +
li_bv5*weights[4] +
li_bv6*weights[5] +
li_bv7*weights[6] +
li_bv8*weights[7];
return li_bvtotal;
}
this.grid = this.add({
xtype: 'rallygrid',
model: Ext.define('BVModel', {
extend: model,
alias : 'BVModel',
fields: [
{name: 'Bv1', type: 'string', persist: false,
convert: function(v, record){ return getOneBV( record, 1, v ); }
},
{name: 'Bv2', type: 'string', persist: false,
convert: function(v, record){ return getOneBV( record, 2, v ); }
},
{name: 'Bv3', type: 'string', persist: false,
convert: function(v, record){ return getOneBV( record, 3, v ); }
},
{name: 'Bv4', type: 'string', persist: false,
convert: function(v, record){ return getOneBV( record, 4, v ); }
},
{name: 'Bv5', type: 'string', persist: false,
convert: function(v, record){ return getOneBV( record, 5, v ); }
},
{name: 'Bv6', type: 'string', persist: false,
convert: function(v, record){ return getOneBV( record, 6, v ); }
},
{name: 'Bv7', type: 'string', persist: false,
convert: function(v, record){ return getOneBV( record, 7, v ); }
},
{name: 'Bv8', type: 'string', persist: false,
convert: function(v, record){ return getOneBV( record, 8, v ); }
},
{name: 'BvTotal', type: 'string', persist: false,
convert: function( v, record ) {
var ls_scoreInfo = '';
if ( record.data.BusinessValues ) {
ls_scoreInfo = getbv( record.data.BusinessValues ) + ' ';
}
if ( record.data.Score ) {
ls_scoreInfo += '(previous: ' + record.data.Score + ')';
}
return ls_scoreInfo;
}
}
]
}),
storeConfig: {
pageSize: 30, autoLoad: true, filters: [
{
property: 'ScheduleState',
operator: '=',
value: 'Backlog'
}
//,{ property: 'FormattedID', value: 'US85792' } // US85792, US84529, US81387, US77032
],
context: this.getContext().getDataContext()
},
columnCfgs: [
fixedIDwithLink, // might want to add a select listener later to display details in a child pane ?
'Name',
'BusinessValues',
'AffectedCustomers',
{
text: BvTitles[0], dataIndex: 'Bv1', editor: { xtype: 'textfield' }, width: 70
},
{
text: BvTitles[1], dataIndex: 'Bv2', editor: { xtype: 'textfield' }, width: 70
},
{
text: BvTitles[2], dataIndex: 'Bv3', editor: { xtype: 'textfield' }, width: 70
},
{
text: BvTitles[3], dataIndex: 'Bv4', editor: { xtype: 'textfield' }, width: 70
},
{
text: BvTitles[4], dataIndex: 'Bv5', editor: { xtype: 'textfield' }, width: 70
},
{
text: BvTitles[5], dataIndex: 'Bv6', editor: { xtype: 'textfield' }, width: 70
},
{
text: BvTitles[6], dataIndex: 'Bv7', editor: { xtype: 'textfield' }, width: 70
},
{
text: BvTitles[7], dataIndex: 'Bv8', editor: { xtype: 'textfield' }, width: 70
},
{
text: BvTitles[8], dataIndex: 'BvTotal', editor: { xtype: 'textfield' }
}
],
selType: 'rowmodel',
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 1,
listeners: {
'edit': function (editor, e) {
e.store.data.items[e.rowIdx].raw.BusinessValues = e.store.data.items[e.rowIdx].data.BusinessValues;
e.store.commitChanges();
}
}
})
]
});
}, // end of getModel success
scope: this
});
}
});
Rally.launchApp('BVApp', {
name: 'Business Values App'
});
});
My suggestion would be to use the get & set functions of the record object to retrieve and change the data instead of digging into the "data" or "raw" fields. This way, the Ext library can manage the changes better to update the store/records properly.
So, when you want to get the value of the "BusinessValues" field, use record.get('BusinessValues'). Likewise, try record.set('BusinessValues', newValue) to set the new value in the getOneBV function. In doing this, you might be able to comment out the RowEditing plugin you added.