How to put confimation box in extjs - extjs

In my UI, I have 3 buttons which are 'add','save' and 'cancel' and an Editor Grid Panel. Now if the user add or edit a record and try to save but accidentally clicked the cancel button, automatically all the records that supposed to be change and saved will remain the same.
My problem is that how can I put a confirmation box at the cancel button that it will only show if there are changes made in the records?
This is what I've tried so far:
var grid = new Ext.grid.EditorGridPanel({
id: 'maingrid',
store: store,
cm: cm,
width: 785.5,
anchor: '100%',
height: 700,
frame: true,
loadMask: true,
waitMsg: 'Loading...',
clicksToEdit: 2,
tbar: [
'->',
{
text: 'Add',
iconCls: 'add',
id: 'b_add',
disabled: true,
handler : function(){
var Put = grid.getStore().recordType;
var p = new Put({
action_take: 'add',
is_active: '',
allowBlank: false
});
Ext.getCmp('b_save').enable();
Ext.getCmp('b_cancel').enable();
grid.stopEditing();
store.insert(0, p);
grid.startEditing(0, 1);
}
},'-',{
text: 'Save',
iconCls: 'save',
id: 'b_save',
disabled: true,
handler : function(){
var objectStore = Ext.getCmp("maingrid").getStore();
var objectModified = objectStore.getModifiedRecords();
// console.log(objectModified);
var customer_id = Ext.getCmp("maingrid").getStore().baseParams['customer_id'];
var objectData = new Array();
var dont_include;
if(objectModified.length > 0)
{
for(var i = 0; i < objectModified.length; i++)
{
dont_include = false;
//all fields are null, then prompt that it should be filled-in (for edit)
if(objectModified[i].data.id
&&
(
(objectModified[i].data.firstname == undefined || objectModified[i].data.firstname == null|| objectModified[i].data.firstname == '')
||
(objectModified[i].data.lastname == undefined || objectModified[i].data.lastname == null|| objectModified[i].data.lastname == '')
||
(objectModified[i].data.email_address == undefined || objectModified[i].data.email_address == null|| objectModified[i].data.email_address == '')
)
)
{
Ext.Msg.show({
title: 'Warning',
msg: "Input value required.",
icon: Ext.Msg.WARNING,
buttons: Ext.Msg.OK
});
return;
}
else//no id, means new record
{
//all fields are not filled-in, just do nothing
if((objectModified[i].data.firstname == undefined || objectModified[i].data.firstname == null|| objectModified[i].data.firstname == '')&&
(objectModified[i].data.lastname == undefined || objectModified[i].data.lastname == null|| objectModified[i].data.lastname == '')&&
(objectModified[i].data.email_address == undefined || objectModified[i].data.email_address == null|| objectModified[i].data.email_address == ''))
{
//boolean flag to determine whether to include this in submission
dont_include = true;
}
//either one field is not filled-in prompt to fill in all fields
else if((objectModified[i].data.firstname == undefined || objectModified[i].data.firstname == null|| objectModified[i].data.firstname == '')||
(objectModified[i].data.lastname == undefined || objectModified[i].data.lastname == null|| objectModified[i].data.lastname == '')||
(objectModified[i].data.email_address == undefined || objectModified[i].data.email_address == null|| objectModified[i].data.email_address == ''))
{
Ext.Msg.show({
title: 'Warning',
msg: "Input value required.",
icon: Ext.Msg.WARNING,
buttons: Ext.Msg.OK
});
return;
}
}
//the data for submission
if(!dont_include)
{
objectData.push({
firstname: objectModified[i].data.firstname,
lastname: objectModified[i].data.lastname,
email_address: objectModified[i].data.email_address,
id: objectModified[i].data.id,
customer_id: customer_id
});
}
}
// console.log(objectData)
// return;
//check if data to submit is not empty
if(objectData.length < 1)//empty
{
Ext.Msg.show({
title: 'Warning',
msg: "No record to save",
icon: Ext.Msg.WARNING,
buttons: Ext.Msg.OK
});
Ext.getCmp('maingrid').getStore().reload();
return;
}
// return;
Ext.Msg.wait('Saving Records...');
Ext.Ajax.request({
timeout:900000,
params: {objdata: Ext.encode(objectData)},
url: '/index.php/saveContent',
success: function(resp){
var response = Ext.decode(resp.responseText);
Ext.Msg.hide();
if(response.success == true){
Ext.Msg.show({
title: "Information",
msg: response.msg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO,
fn: function(btn){
Ext.getCmp('maingrid').getStore().reload();
Ext.getCmp('b_save').disable();
Ext.getCmp('b_cancel').disable();
}
});
}else{
Ext.Msg.show({
title: "Warning",
msg: response.msg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
},
failure: function(resp){
Ext.Msg.hide();
Ext.Msg.show({
title: "Warning1",
msg: response.msg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
}
});
}
else{
Ext.Msg.show({
title: 'Warning',
msg: "No changes made.",
icon: Ext.Msg.WARNING,
buttons: Ext.Msg.OK
});
}
}
},'-',
{
text: 'Cancel',
iconCls: 'cancel',
id: 'b_cancel',
disabled: true,
handler : function(){
Ext.getCmp('maingrid').getStore().reload();
Ext.getCmp('b_save').disable();
Ext.getCmp('b_cancel').disable();
}
}
],
bbar: pager
});

You can use Ext.data.Store getModifiedRecords() and getRemovedRecords() methods to detect if grid store contains changes. For displaying confirmation dialog you can use Ext.MessageBox.confirm() method and then reload store only if user click on "yes" button.
var store = Ext.getCmp('maingrid').getStore();
var modified = store.getModifiedRecords();
var removed = store.getRemovedRecords();
if (modified.length || removed.length) {
Ext.MessageBox.confirm('Cancel', 'Do you want cancel changes?', function(btnId) {
if (btnId == 'yes') {
store.reload();
Ext.getCmp('b_save').disable();
Ext.getCmp('b_cancel').disable();
}
});
}

Related

ExtJS 6. Pickerfield with treepanel

I do not know the right way of creating a treepanel pickerfield. Now I do it like so:
{
xtype:'pickerfield',
width:'34%',
emptyText: 'Choose layer',
createPicker: function(){
return Ext.create('Ext.tree.Panel',{
hidden: true,
floating: true,
minHeight: 300,
pickerField: this,
root: {
text: 'Root',
expanded: true,
children:[{
text: 'Standard',
expanded: true,
children: [{
text: 'Open Street Map',
checked: true,
leaf: true,
itemId: 'OMS'
},{
text: 'MapQuest',
leaf: false,
children:[{
text: 'Road',
leaf:true,
checked: false,
itemId: 'MapQuest',
val: 'osm'
},{
text: 'Satellite',
leaf:true,
checked: false,
itemId: 'MapQuest',
val: 'sat'
},{
text: 'Hybride',
leaf:true,
checked: false,
itemId: 'MapQuest',
val: 'hyb'
}]
}]
}]
}
});
}
}
It works partially. When I first hit the picker, it shows me a treepanel, but when I expand some nodes (leaf=false), then it gets closed. The same happens, when I check a tree leaf - I do not want that, because, the user is allowed to check multiple nodes. Beside, even when I check some leaves, the value of the picker stays unchanged (it keeps showing emptyText value). So, how to fix all this?
You can use following sample:
Ext.define('Ext.ux.TreeCombo',
{
extend: 'Ext.form.field.Picker',
alias: 'widget.treecombo',
tree: false,
constructor: function(config)
{
this.addEvents(
{
"itemclick" : true
});
this.listeners = config.listeners;
this.callParent(arguments);
},
records: [],
recursiveRecords: [],
ids: [],
selectChildren: true,
canSelectFolders: true,
multiselect: false,
displayField: 'text',
valueField: 'id',
treeWidth: 300,
matchFieldWidth: false,
treeHeight: 400,
masN: 0,
recursivePush: function(node, setIds)
{
var me = this;
me.addRecRecord(node);
if(setIds) me.addIds(node);
node.eachChild(function(nodesingle)
{
if(nodesingle.hasChildNodes() == true)
{
me.recursivePush(nodesingle, setIds);
}
else
{
me.addRecRecord(nodesingle);
if(setIds) me.addIds(nodesingle);
}
});
},
recursiveUnPush: function(node)
{
var me = this;
me.removeIds(node);
node.eachChild(function(nodesingle)
{
if(nodesingle.hasChildNodes() == true)
{
me.recursiveUnPush(nodesingle);
}
else me.removeIds(nodesingle);
});
},
addRecRecord: function(record)
{
var me = this;
for(var i=0,j=me.recursiveRecords.length;i<j;i++)
{
var item = me.recursiveRecords[i];
if(item)
{
if(item.getId() == record.getId()) return;
}
}
me.recursiveRecords.push(record);
},
afterLoadSetValue: false,
setValue: function(valueInit)
{
if(typeof valueInit == 'undefined') return;
var me = this,
tree = this.tree,
values = (valueInit == '') ? [] : valueInit.split(','),
valueFin = [];
inputEl = me.inputEl;
if(tree.store.isLoading())
{
me.afterLoadSetValue = valueInit;
}
if(inputEl && me.emptyText && !Ext.isEmpty(values))
{
inputEl.removeCls(me.emptyCls);
}
if(tree == false) return false;
var node = tree.getRootNode();
if(node == null) return false;
me.recursiveRecords = [];
me.recursivePush(node, false);
me.records = [];
Ext.each(me.recursiveRecords, function(record)
{
var id = record.get(me.valueField),
index = values.indexOf(''+id);
if(me.multiselect == true) record.set('checked', false);
if(index != -1)
{
valueFin.push(record.get(me.displayField));
if(me.multiselect == true) record.set('checked', true);
me.addRecord(record);
}
});
me.value = valueInit;
me.setRawValue(valueFin.join(', '));
me.checkChange();
me.applyEmptyText();
return me;
},
getValue: function()
{
return this.value;
},
getSubmitValue: function()
{
return this.value;
},
checkParentNodes: function(node)
{
if(node == null) return;
var me = this,
checkedAll = true;
node.eachChild(function(nodesingle)
{
var id = nodesingle.getId(),
index = me.ids.indexOf(''+id);
if(index == -1) checkedAll = false;
});
if(checkedAll == true)
{
me.addIds(node);
me.checkParentNodes(node.parentNode);
}
else
{
me.removeIds(node);
me.checkParentNodes(node.parentNode);
}
},
initComponent: function()
{
var me = this;
me.tree = Ext.create('Ext.tree.Panel',
{
alias: 'widget.assetstree',
hidden: true,
minHeight: 300,
rootVisible: (typeof me.rootVisible != 'undefined') ? me.rootVisible : true,
floating: true,
useArrows: true,
width: me.treeWidth,
autoScroll: true,
height: me.treeHeight,
store: me.store,
listeners:
{
load: function(store, records)
{
if(me.afterLoadSetValue != false)
{
me.setValue(me.afterLoadSetValue);
}
},
itemclick: function(view, record, item, index, e, eOpts)
{
me.itemTreeClick(view, record, item, index, e, eOpts, me)
}
}
});
if(me.tree.getRootNode().get('checked') != null) me.multiselect = true;
this.createPicker = function()
{
var me = this;
return me.tree;
};
this.callParent(arguments);
},
addIds: function(record)
{
var me = this;
if(me.ids.indexOf(''+record.getId()) == -1) me.ids.push(''+record.get(me.valueField));
},
removeIds: function(record)
{
var me = this,
index = me.ids.indexOf(''+record.getId());
if(index != -1)
{
me.ids.splice(index, 1);
}
},
addRecord: function(record)
{
var me = this;
for(var i=0,j=me.records.length;i<j;i++)
{
var item = me.records[i];
if(item)
{
if(item.getId() == record.getId()) return;
}
}
me.records.push(record);
},
removeRecord: function(record)
{
var me = this;
for(var i=0,j=me.records.length;i<j;i++)
{
var item = me.records[i];
if(item && item.getId() == record.getId()) delete(me.records[i]);
}
},
itemTreeClick: function(view, record, item, index, e, eOpts, treeCombo)
{
var me = treeCombo,
checked = !record.get('checked');//it is still not checked if will be checked in this event
if(me.multiselect == true) record.set('checked', checked);//check record
var node = me.tree.getRootNode().findChild(me.valueField, record.get(me.valueField), true);
if(node == null)
{
if(me.tree.getRootNode().get(me.valueField) == record.get(me.valueField)) node = me.tree.getRootNode();
else return false;
}
if(me.multiselect == false) me.ids = [];
//if it can't select folders and it is a folder check existing values and return false
if(me.canSelectFolders == false && record.get('leaf') == false)
{
me.setRecordsValue(view, record, item, index, e, eOpts, treeCombo);
return false;
}
//if record is leaf
if(record.get('leaf') == true)
{
if(checked == true)
{
me.addIds(record);
}
else
{
me.removeIds(record);
}
}
else //it's a directory
{
me.recursiveRecords = [];
if(checked == true)
{
if(me.multiselect == false)
{
if(me.canSelectFolders == true) me.addIds(record);
}
else
{
if(me.canSelectFolders == true)
{
me.recursivePush(node, true);
}
}
}
else
{
if(me.multiselect == false)
{
if(me.canSelectFolders == true) me.recursiveUnPush(node);
else me.removeIds(record);
}
else me.recursiveUnPush(node);
}
}
//this will check every parent node that has his all children selected
if(me.canSelectFolders == true && me.multiselect == true) me.checkParentNodes(node.parentNode);
me.setRecordsValue(view, record, item, index, e, eOpts, treeCombo);
},
fixIds: function()
{
var me = this;
for(var i=0,j=me.ids.length;i<j;i++)
{
if(me.ids[i] == 'NaN') me.ids.splice(i, 1);
}
},
setRecordsValue: function(view, record, item, index, e, eOpts, treeCombo)
{
var me = treeCombo;
me.fixIds();
me.setValue(me.ids.join(','));
me.fireEvent('itemclick', me, record, item, index, e, eOpts, me.records, me.ids);
if(me.multiselect == false) me.onTriggerClick();
}
});
var storeMenu = Ext.create('Ext.data.TreeStore',
{
root:
{
text: 'Root',
id: '0',
expanded: true,
children:
[
{id: '1', text: 'First node', leaf: false, children:
[
{id: '3', text: 'First child node', leaf: true},
{id: '4', text: 'Second child node', leaf: true}
]
},
{id: '2', text: 'Second node', leaf: true}
]
},
folderSort: false
});
Ext.onReady(function() {
Ext.create('Ext.ux.TreeCombo', {
margin:10,
width:120,
height: 10,
treeHeight: 10,
treeWidth: 240,
renderTo: 'treecombo3',
store: storeMenu,
selectChildren: false,
canSelectFolders: true
,itemTreeClick: function(view, record, item, index, e, eOpts, treeCombo)
{
var id = record.data.id;
}
});
});

Whats config like renderer in extjs picker?

I'm developing a web application using Extjs-6. I want to extend a class from Ext.form.field.Picker. I do it as follow:
...
extend: 'Ext.form.field.Picker',
createPicker: function(){
return new Ext.panel.Panel({
items: [{
xtype: 'textfield',
name: 'text',
fielLabel: 'text label'
}, {
xtype: 'colorfield',
name: 'color',
fielLabel: 'color field'
},
...
]
});
}
...
my value in this class is an object as follow:
{
text: 'value of textfield',
color: 'value of colorfield'
}
but when I set this object to value of class it shown in picker as [object object].
How Can I d?
Have the picker a confis like renderer to get the value of picker and then return correct string?
There is more to it than just template.
Below is example picker implementation for textfield + datefield, just adjust it to have colorfield instead.
// component has picker with both textfield and datefield;
// when picker is collapsed, data is displayed as "{text}, {date}"
Ext.define('ColorPicker', {
extend: 'Ext.form.field.Picker',
// picker template
config: {
popup: {
lazy: true,
$value: {
xtype: 'window',
closeAction: 'hide',
referenceHolder: true,
minWidth: 540,
minHeight: 60,
layout: 'form',
header: false,
resizable: true,
items: [
{
xtype: 'textfield',
name: 'text',
fielLabel: 'text label',
anchor: '100%',
reference: 'text'
},
{
xtype: 'datefield',
name: 'color',
fielLabel: 'color field',
anchor: '100%',
format: 'd.m.Y',
reference: 'date'
}
],
fbar: [
{ text: 'OK', reference: 'okBtn' },
{ text: 'Cancel', reference: 'cancelBtn' }
]
}
}
},
dateFormat: 'd.m.Y',
createPicker: function(){
var me = this,
popup = me.getPopup();
// the window will actually be shown and will house the picker
me.pickerWindow = popup = Ext.create(popup);
popup.lookupReference('okBtn').on('click', 'onPickerOk', me);
popup.lookupReference('cancelBtn').on('click', 'onPickerCancel', me);
popup.on({
close: 'onPickerCancel',
scope: me
});
me.updateValue(me.getValue());
return popup;
},
// ok picker button handler
onPickerOk: function () {
var me = this,
popup = me.pickerWindow,
textField = popup.lookupReference('text'),
dateField = popup.lookupReference('date'),
value = {
text: textField.getValue(),
date: dateField.getValue()
};
popup.hide();
me.setValue(value);
},
// cancel picker button handler
onPickerCancel: function () {
var me = this,
popup = me.pickerWindow;
popup.hide();
me.updateValue(me.getValue());
},
// override set value to support both string ("{text}, {date}")
// and object ({ text: "{text}", date: "{date}" })
setValue: function(value) {
var me = this,
text,
date,
v;
if (Ext.isObject(value)) {
value = value.text + ", " + Ext.Date.format(value.date, me.dateFormat);
}
me.callParent([ value ]);
// always update in case opacity changes, even if value doesn't have it
// to handle "hex6" non-opacity type of format
me.updateValue(value);
},
// update values in picker fields
updateValue: function (value) {
var me = this,
popup = me.pickerWindow,
textField,
dateField,
text = value.text,
date = value.date;
if (!popup || !popup.isComponent) {
return;
}
if (Ext.isString(value)) {
value = value.split(',');
text = (value[0] || '').trim();
date = Ext.Date.parse((value[1] || '').trim(), me.dateFormat);
} else if (Ext.isObject(value)) {
text = value.text || '';
date = value.date || '';
}
textField = popup.lookupReference('text');
dateField = popup.lookupReference('date');
if (!me.syncing) {
me.syncing = true;
textField.setValue(text);
dateField.setValue(date);
me.syncing = false;
}
}
});
Fiddle: https://fiddle.sencha.com/#fiddle/14kg

Show icon for dynamic grid page in Angularjs

I am new to angularjs, I want to create grid with status icons.
Constant Code:
segment: {
type: 'segment',
name: 'segment',
contextKey: '',
innerLists: [],
foreignKey: 'segmentId',
title: 'name',
metaData: [{
key: 'id',
text: 'ID'
}, {
key: 'name',
text: 'Name'
}, {
key: 'segmentType',
text: 'Segment Type',
isSortable: false
}, {
key: 'status',
text: 'Status',
isSortable: false
}]
}
Controller Code:
function dataManipulator(data) {
//add property for the central display
data.forEach(function(entity) {
if (entity.segment != null) {
// status
var active = entity.segment.active;
if (active != null) {
if (active == true)
entity.status = 'Active';
else if (active == false)
entity.status = 'InActive';
}
entity.segmentType = angular.element('<img src="http://i.imgur.com/945LPEw.png" />');
});
}
Problem: I am getting the following error
"Error: [$parse:isecdom] Referencing DOM nodes in Angular expressions is disallowed! Expression: getInnerField(item, col)"
I need solution for this issue, without using ng-grid. Appreciate your inputs.

ExtJS Two and more separators on numberfields

Tell me, please, how you can use two types of separator digital input field? You can use only one standard methods, but at a different keyboard layout, there is a need to use another, keeping the data in one format, that is the '.'
Input: 10,789 or 10.789
Save: 10.789
I use Ext.form.NumberField for editing integral field.
Part of my code:
var editor = new Ext.ux.grid.RowEditor({
saveText: LANG['update'],
listeners: {
afteredit: function(object, changes, r, rowIndex) {
Ext.MessageBox.alert(LANG['alert_info'], LANG['memory']); }
}
}
});
var userGrid = new Ext.grid.GridPanel({
id: 'status-form',
region:'center',
margins: '5 5 5 5',
store: Gstore,
iconCls: 'icon-grid',
plugins: [editor, summary],
cm: new Ext.grid.ColumnModel([
{header: "ID", width: 30, sortable: true, dataIndex: 'idb', renderer: formatID},
{xtype: 'datecolumn', header: LANG['date'], width: 70, sortable: true, dataIndex: 'date',
groupRenderer: Ext.util.Format.dateRenderer('M Y'),
format: 'd/m/Y',
editor: new Ext.form.DateField({
value: (new Date()).format('d/m/Y'),
//format: 'd/m/Y',
minValue: '01/01/2010',
//minText: 'Please Check Correct Data',
maxValue: (new Date()).format('d/m/Y'),
editable: false
})
},
{header: LANG['title'], width: 150, sortable: true, dataIndex: 'title',
editor: new Ext.form.TextField({}),
summaryType: 'count',
summaryRenderer: function(v, params, data){
return ((v === 0 || v > 1) ? LANG['Tasks']+ ': '+ v: '1 '+LANG['Task']);
}
},
{header: LANG['lenght'], width: 60, sortable: true, dataIndex: 'lenght', renderer: formatKM, align: 'center',
summaryType: 'sum',
summaryRenderer: Ext.util.Format.cifres2,
editor: new Ext.form.NumberField({
allowNegative: false,
decimalPrecision: 2,
//decimalSeparator: ',',
maxValue: 1000
//allowBlank: false
})
},
{header: LANG['time'], width: 30, sortable: true, dataIndex: 'time', align: 'center',
renderer: formatTimeStr,
summaryType: 'sum22',
editor: new Ext.form.NumberField({
//format: 'H:i',
allowNegative: false,
decimalPrecision: 2,
decimalSeparator: ':'
})
},
{header: LANG['vsr'], width: 50, sortable: true, dataIndex: 'vsr', renderer: formatKM, align: 'center',
summaryType: 'average',
summaryRenderer: Ext.util.Format.cifres2,
editor: new Ext.form.NumberField({
allowNegative: false,
decimalPrecision: 2,
maxValue: 100
})
},
{header: LANG['vmax'], width: 50, sortable: true, dataIndex: 'vmax', renderer: formatKM, align: 'center',
summaryType: 'max',
summaryRenderer: Ext.util.Format.cifres2,
editor: new Ext.form.NumberField({
allowNegative: false,
decimalPrecision: 2,
maxValue: 100
})
}, ............
I implemented this with easy way. My method is enable key events of number field and check if pressed key is ',' than add a '.' to value. That is the implementation;
Ext.create('Ext.form.Panel', {
title: 'On The Wall',
width: 300,
bodyPadding: 10,
renderTo: Ext.getBody(),
items: [{
xtype: 'numberfield',
anchor: '100%',
name: 'bottles',
fieldLabel: 'Bottles of Beer',
enableKeyEvents : true,
value: 99,
maxValue: 99,
minValue: 0,
listeners : {
keypress : function(view, e){
if(e.getKey() == 44)
view.setRawValue(view.getRawValue() +'.');
}
}
}]
});
I used this in my project but I don't know it's fit your request.
First, checking the value where it's number and has "." then put proper value based on this condition. If it's not has "." in the value then calling the replace function.
value.match(/^[0-9]+\.?[0-9]*$/) ? Number(value) : Number((value.replace(',', '.')));
The solution is found here: http://habrahabr.ru/post/137966/ (russian lang)
Since there is seen a solution for version> 4.0, and I have worth less had to change the code, replacing the standard JS functions.Vykladyvayu it here, maybe someone will need:
To begin at the header of the page to connect сursor.js
// Author: Diego Perini <dperini#nwbox.com>
var sb = new Array(
'leftbox', 'rightbox', 'scrollLeft', 'scrollRight',
'caretPos', 'maxLength', 'textLength', 'availLength',
'beforeCaret', 'afterCaret', 'selectedText'
)
var leftbox = {};
var rightbox = {};
var scrollLeft = {};
var scrollRight = {};
var caretPos = {};
var maxLength = {};
var textLength = {};
var availLength = {};
var beforeCaret = {};
var afterCaret = {};
var selectedText = {};
/*
for (var i in sb) {
var v = '"var '+sb[i]+' = {}"';
eval(v);
}
*/
var os = 0
var oe = 0
function update(o) {
var t = o.value, s = getSelectionStart(o), e = getSelectionEnd(o)
if (s == os && e == oe) return
caretPos.firstChild.nodeValue = s
maxLength.firstChild.nodeValue = o.getAttribute('maxLength')
textLength.firstChild.nodeValue = t.length
availLength.firstChild.nodeValue = o.getAttribute('maxLength') - t.length
afterCaret.firstChild.nodeValue = t.substring(s).replace(/ /g, '\xa0') || '\xa0'
beforeCaret.firstChild.nodeValue = t.substring(0, s).replace(/ /g, '\xa0') || '\xa0'
selectedText.firstChild.nodeValue = t.substring(s, e).replace(/ /g, '\xa0') || '\xa0'
rightbox.value = scrollRight.firstChild.nodeValue = t.substring(s).replace(/ /g, '\xa0') || '\xa0'
leftbox.value = scrollLeft.firstChild.nodeValue = t.substring(0, s).replace(/ /g, '\xa0') || '\xa0'
os = s
oe = e
return true
}
function setup() {
for (var i in sb) eval(sb[i] + ' = document.getElementById(sb[i])')
update(document.getElementById('textbox'))
}
function getSelectionStart(o) {
if (o.createTextRange) {
var r = document.selection.createRange().duplicate()
r.moveEnd('character', o.value.length)
if (r.text == '') return o.value.length
return o.value.lastIndexOf(r.text)
} else return o.selectionStart
}
function getSelectionEnd(o) {
if (o.createTextRange) {
var r = document.selection.createRange().duplicate()
r.moveStart('character', -o.value.length)
return r.text.length
} else return o.selectionEnd
}
and connect the plugin:
Ext.ns('Ext.ux.form');
/**
* #class Ext.ux.form.NumberInputFilter
* #extends Ext.form.NumberField
* Plugin (ptype = 'numberinputfilter')
* #param allowedDecimalSeparators: ',.:-' and other
* #ptype numberinputfilter
*/
Ext.ux.form.NumberInputFilter = Ext.extend(Ext.form.NumberField, {
initComponent: function(){
Ext.ux.form.NumberInputFilter.superclass.initComponent.call(this);
},
init : function(field) {
if (!(field && field.isXType('numberfield'))) {
return;
}
Ext.apply(field, {
allowedDecimalSeparators : this.allowedDecimalSeparators,
checkValue : function(newChar) {
var raw = this.getRawValue();
var el = Ext.get(this.id).dom;
// functions taken from here http://javascript.nwbox.com/cursor_position/
// and connected to a separate file cursor.js
var start = getSelectionStart(el);
var end = getSelectionEnd(el);
if (start != end) {
// delete the selected text from the expected values
raw = raw.substring(0, start) + raw.substring(end);
}
if (Ext.isEmpty(raw)) {
return (newChar == this.decimalSeparator || (this.minValue < 0) && newChar == '-') || newChar.search('/^\d$/');
}
if (raw.length == this.maxLength) {
return false;
}
if (newChar == this.decimalSeparator && (!this.allowDecimals || raw.indexOf(this.decimalSeparator) != -1)) {
return false;
}
// form the intended meaning
raw = raw.substring(0, start) + newChar + raw.substring(start);
raw = raw.split(new RegExp(this.decimalSeparator.replace("/([-.*+?^${}()|[\]\/\\])/g", "\\$1")));
return (!raw[0] || this.intRe.search(raw[0])) && (!raw[1] || this.decRe.search(raw[1]));
},
filterKeys : function(e){
if (e.ctrlKey && !e.altKey) {
return;
}
var key = e.getKey(),
charCode = String.fromCharCode(e.getCharCode());
if(Ext.isGecko && (e.isNavKeyPress() || key === e.BACKSPACE || (key === e.DELETE && e.button === -1))){
return;
}
if(!Ext.isGecko && e.isSpecialKey() && !charCode){
return;
}
// begin hack
if (charCode != this.decimalSeparator && this.allowedDecimalSeparators.indexOf(charCode) != -1) {
// if the input character is not a decimal point,
                    // But it is one of the alternatives,
                    // Replace it with a decimal point
charCode = this.decimalSeparator;
if (Ext.isIE) {
// in the IE code of the pressed key can be substituted directly
e.browserEvent.keyCode = charCode.charCodeAt(0);
} else if (Ext.isGecko) {
// for gecko-engine slowing Event
e.stopEvent();
// create a new event with the modified code of the pressed key
var newEvent = document.createEvent('KeyEvents');
// Mandatory event must be cancelable
                        // As it can be reversed, if the decimal
                        // Delimiter is entered in the field
newEvent.initKeyEvent(
e.browserEvent.type,
e.browserEvent.bubbles,
true, //cancellable
e.browserEvent.view,
e.browserEvent.ctrlKey,
e.browserEvent.altKey,
e.browserEvent.shiftKey,
e.browserEvent.metaKey,
0, // keyCode
charCode.charCodeAt(0) // charCode
);
e.getTarget().dispatchEvent(newEvent);
// event generated, nothing doing.
return;
} else if (Ext.isWebKit) {
// stopped event
e.stopEvent();
// into webkit initKeyboardEvent dont work, use TextEvent
if (this.checkValue(charCode)) {
var newEvent = document.createEvent('TextEvent');
newEvent.initTextEvent(
'textInput',
e.browserEvent.bubbles,
true,
e.browserEvent.view,
charCode
);
e.getTarget().dispatchEvent(newEvent);
}
return;
}
}
if (!this.checkValue(charCode)) {
e.stopEvent();
}
// end hack
},
updateDecimalPrecision : function(prec, force) {
if (prec == this.decimalPrecision && force !== true) {
return;
}
if (!Ext.isNumber(prec) || prec < 1) {
this.allowDecimals = false;
} else {
this.decimalPrecision = prec;
}
var intRe = '^';
if (this.minValue < 0) {
intRe += '-?';
}
intRe += '\\d' + (Ext.isNumber(this.integerPrecision) ? '{1,' + this.integerPrecision + '}' : '+') + '$';
this.intRe = new RegExp(intRe);
if (this.allowDecimals) {
this.decRe = new RegExp('^\\d{1,' + this.decimalPrecision + '}$');
} else {
delete this.decRe;
}
},
fixPrecision : function(value) {
// support decimalSeparators
if (Ext.isString(value)) {
value = value.replace(new RegExp('[' + (this.allowedDecimalSeparators + this.decimalSeparator).replace("/([-.*+?^${}()|[\]\/\\])/g", "\\$1") + ']'), '.');
}
// end hack
var me = this,
nan = isNaN(value),
precision = me.decimalPrecision;
if (nan || !value) {
return nan ? '' : value;
} else if (!me.allowDecimals || precision <= 0) {
precision = 0;
}
console.info(parseFloat(parseFloat(value).toFixed(precision)));
return parseFloat(parseFloat(value).toFixed(precision));
}
});
field.updateDecimalPrecision(field.decimalPrecision, true);
}
});
Ext.preg('numberinputfilter', Ext.ux.form.NumberInputFilter);
Use any separator, what we like in a digital field, just listing them:
.....
{header: LANG['lenght'], width: 60, sortable: true, dataIndex: 'lenght', renderer: formatKM, align: 'center',
summaryType: 'sum',
summaryRenderer: Ext.util.Format.cifres2,
editor: new Ext.form.NumberField({
allowNegative: false,
decimalPrecision: 2,
plugins: new Ext.ux.form.NumberInputFilter({
allowedDecimalSeparators : ',.-'
}),
maxValue: 1000,
allowBlank: false
})
},
.....

Have a button that submits data without AJAX while other buttons submit through AJAX in EXT-JS

i have an EXT.formPanel in which i'd like to have this beahaviour: two buttons should submit through ajax and one shouldn't. How to do this?
This is my code:
form = new Ext.FormPanel({
frame:true,
width:Ext.crl.styles.formWidth,
title: 'Ricerca Atti',
bodyStyle:'padding:5px 5px 0',
defaultType: 'textfield',
formId:'search-form',
keys: [
{ key: [Ext.EventObject.ENTER], handler: function(){
ds.baseParams = form.getForm().getValues();
form.getForm().submit({url:urlRicerca,
waitMsg:'Ricerca in corso…', submitEmptyText: false, method:'GET',params: { start: 0, limit: PAGE_SIZE},
success:function(form,action) {Ext.crl.utils.searchOnSuccess(ds, action, grid); }
});
}
}
],
items: [
ricercaSemplice,
ricercaAvanzata,
{ //This button should submit NOT submit through AJAX!!!
text: 'Esporta Elenco',
disabled:false,
style: 'float:right;',
xtype: 'button',
handler: function() {
ds.baseParams = form.getForm().getValues();
form.getForm().submit({url:urlRicerca+".xls",
waitMsg:'Ricerca in corso…', submitEmptyText: false, method:'GET',params: { enableCsvFilter: "yes", start: 0, limit: PAGE_SIZE},
success:function(form,action) {console.log(action); }
});
}
},{
text: 'Reimposta',
xtype: 'button',
style: 'float:right;margin-right:10px',
disabled: false,
handler: function() {
form.getForm().reset();
//window.location.href = window.location.href;
}
},{
id: 'bottoreCercaRicerca',
name: 'bottoreCercaRicerca',
text: 'Cerca',
xtype: 'button',
style: 'float:right;margin-right:10px',
disabled: false,
handler: function() {
ds.baseParams = form.getForm().getValues();
form.getForm().submit({url:urlRicerca,
waitMsg:'Ricerca in corso…', submitEmptyText: false, method:'GET',params: { start: 0, limit: PAGE_SIZE},
success:function(form,action) {Ext.crl.utils.searchOnSuccess(ds, action, grid); }
});
}
},{
name: 'buttonSwitchRicerca',
xtype: 'button',
style: 'margin-bottom:10px',
text: 'Ricerca Avanzata',
handler: function() {
if(ricercaAvanzata.hidden) {
this.setText('Ricerca Standard');
ricercaAvanzata.show();
}
else {
this.setText('Ricerca Avanzata');
ricercaAvanzata.hide();
}
}
},
DEFAULT_SPACER,
Ext.crl.modalitaLavoro.comboModalitalavoro
]
});
I'v written a comment on where the button should NOT use ajax.
EDIT - i've found a solution, this is an handler that works for not submitting through ajax (actually the fact that opens in a new window is something i want) what i need. Are there any other options?
handler: function() {
query = form.getForm().getValues(true);
query += "&enableCsvFilter=yes";
var url = urlRicerca + ".xls?" + query;
window.open(url);
}
Here is an example :
var ajaxButton1 = new Ext.Button({text:'ajaxButton1 ', handler:ajaxButton1Function});
var ajaxButton2 = new Ext.Button({text:'ajaxButton2 ', handler:ajaxButton2Function});
var noAjaxButton = new Ext.Button({text:'noAjaxButton ', handler:noAjaxButtonFunction});
function ajaxButton1Function(){
Ext.Ajax.Request({
url: 'your url', // you can fix a parameter like this : url?action=anAction1
method: 'POST',
params: {
myField1: myField1.getValue()
// all your params....
},
success: function (result, request){
alert('Succesfully added ' + result.responseText);
},
failure: function (result, request){
alert('Error in server' + result.responseText);
}
});
}
function ajaxButton2Function(){
Ext.Ajax.Request({
url: 'your url', // you can fix a parameter like this : url?action=anAction2
method: 'POST',
params: {
myField1: myField1.getValue()
// all your params....
}
success: function (result, request){
alert('Succesfully added ' + result.responseText);
},
failure: function (result, request){
alert('Error in server' + result.responseText);
}
});
}
function noAjaxButtonFunction(){
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
}
});
}

Resources