As the title says, I need to capture the change event of a tab and show to the user a confirm message box. I achieved this but using the confirm JS native function. I'd like to perform this using ExtJS's Ext.Msg.show(), but the program flow does not stop with this way, as it does with confirm function. See below the two ways:
'Ext.Msg.show()' way:
onBeforeTabChange: function(panel, nextTab, oldTab)
{
var bReturn = true;
if (null != oldTab)
{
if(AppGlobals.isEditing=='si')
{
Ext.Msg.show(
{
title: 'Warning',
msg: 'Leave without saving changes?',
buttons: Ext.Msg.YESNO,
icon: Ext.Msg.WARNING,
closable: false,
buttonText:
{
yes : 'Yes, sure',
no : 'No, will save changes first'
},
fn: function (buttonId)
{
if(buttonId=="yes")
{
AppGlobals.isEditing = 'no';
bReturn = true;
}
else
{
bReturn = false;
}
}
});
}
else
{
bReturn = true;
}
}
return bReturn;
}
As I said before, the code above does not stop the program flow. The alert appears but the tab changes anyway.
'confirm' way:
onBeforeTabChange: function(panel, nextTab, oldTab)
{
var bReturn = true;
if (null != oldTab)
{
if(AppGlobals.isEditing=='si')
{
bReturn = confirm('Leave without saving changes?');
if(bReturn==true)
{
AppGlobals.isEditing = 'no';
}
}
else
{
bReturn = true;
}
}
return bReturn;
}
The code above do work, and the tab does not change until user clicks on "Yes".
Any help? Thanks in advance.
Ext.Msg.show() is asynchronous and doesn't stop execution of the rest of program. The solution would be always return false from beforetabchange listener and programmatically change the tab when user press Yes.
A Sample Code: Here i have used allowChange as flag to prevent showing of message box when tab is changed programmatically. You can use you own flag here which i suppose is AppGlobals.isEditing
Ext.application({
launch: function() {
var allowChange = false;
Ext.create('Ext.tab.Panel', {
width: 300,
height: 200,
activeTab: 0,
items: [{
title: 'Tab 1',
bodyPadding: 10,
html: 'A simple tab'
},
{
title: 'Tab 2',
html: 'Another one'
}
],
renderTo: Ext.getBody(),
listeners: {
beforetabchange: function(tabPanel, nextTab, oldTab) {
var bReturn = true;
if (null != oldTab && !allowChange) {
bReturn = false;
Ext.Msg.show({
title: 'Warning',
msg: 'Leave without saving changes?',
buttons: Ext.Msg.YESNO,
icon: Ext.Msg.WARNING,
closable: false,
buttonText: {
yes: 'Yes, sure',
no: 'No, will save changes first'
},
fn: function(buttonId) {
if (buttonId == "yes") {
allowChange = true; // to stop showing the message box again when tab is changed programmaticaly
tabPanel.setActiveTab(nextTab);
}
}
});
}
allowChange = false;
return bReturn; // always return false
}
}
});
}
});
<link rel="stylesheet" href="https://cdn.sencha.com/ext/gpl/4.1.1/resources/css/ext-all.css">
<script type="text/javascript" src="https://cdn.sencha.com/ext/gpl/4.1.1/ext-all-debug.js"></script>
Related
I have a pivot grid which display if the users have create,read,update,delete" permissions, the users are agrouped in this way departaments > estabilishments > sectors > users and i want the user to be able to edit this fields.
I already tried using with a renderer:
aggregate: [{
renderer: function(value, record, dataIndex, cell, column) {
var id = Ext.id();
Ext.defer(function() {
Ext.widget('checkbox', {
renderTo: id,
checked: value,
listeners: {
change: {
fn: function(event, target) {
//some function here
}
}
}
});
}, 100);
return Ext.String.format('<div id="{0}"></div>', id);
},
aggregator: 'aggCheckBoxR',
dataIndex: 'Incluir',
header: 'Incluir'
}]
and with a widget column:
aggregate: [{
aggregator: 'aggCheckBoxR',
column: {
xtype: 'widgetcolumn',
widget: {
xtype: 'checkbox',
listeners: {
change: function(cb) {
//some function here
}
}
}
},
dataIndex: 'Incluir',
header: 'Incluir'
}]
My Aggregator:
aggCheckBoxR: function(records, measure, matrix, rowGroupKey, colGroupKey) {
if (records.length > 1) {
let checkAllTrue = true;
for (var i = 0; i < records.length; i++) {
if (records[i].get('Incluir') === false || records[i].get('Incluir') === 0) {
checkAllTrue = false;
}
}
return checkAllTrue;
} else {
return records[0].get('Incluir');
}
}
The checkbox apears on the grid but my problem is the data "dont persist", whenever i expand or collapse a left axis on the pivot grid the value of the checkbox returns to its original value, how can i persist this data?
Already tried update the record manualy
change: function(cb) {
var nomeCmp = cb.getWidgetRecord().data._compactview_;
Ext.getStore('acesso.ColabStore').findRecord('Nome', nomeCmp).data.Incluir = true;
}
But still, it doestn't work.
EDIT: Had to change the column object event listener to:
{
xtype: 'widgetcolumn',
widget: {
xtype: 'checkbox',
listeners: {
afterrender: function(component, eOpts) {
console.log('after,render');
component.getEl().on('change', function(e, el) {
console.log('change func here');
})
}
}
}
}
With this, the change event is only fired when the users check a checkbox, and finally, I could use
norbeq's answer
You can update the record manually using:
record.set('Incluir',true);
and if you dont wan't to send changes to server:
record.commit();
I have the code below to create a text field in the form.
buildForm : function() {
this.time = new Ext.form.TextField({
name : 'estimate',
allowBlank : false,
fieldLabel : 'Estimate',
onBlur : function(field) {
return this.setValue(this.getValue().replace('.', ','));
}
});
}
It works correctly.
Now, when I render this form, and in this field is value="abc", I need to set disabled to this field.
I tried:
disabled : function() { return this.getValue() == 'abc' ? true : false;}
disabled : function(field) { return this.getValue() == 'abc' ? true : false;}
disabled : function(field) { return field.getValue() == 'abc' ? true : false;}
disabled : this.getValue() == 'abc' ? true : false
But nothing of this work. Any idea?
Try this
change: function(field, newValue,) {
field.setDisabled(newValue == 'abc');
}
Check API for more info on events, methods for TextField
UPD:
If you need to disable textfield only on form render, just add this line in buildForm function.
this.time.setDisabled(this.time.getValue() == 'abc')
Another way is to add logic on TextField's render event.
render: function(field) {
field.setDisabled(field.getValue() == 'abc')
}
UPD 2:
I suppose, that your issue is on way of setting value or in the order.
Here's a working sample.
Notice this.time.setValue('abc')
instead of this.time.value = 'abc', which won't work.
buildForm: function() {
this.timeFld = Ext.create('Ext.form.TextField', {
name: 'estimate',
allowBlank: false,
fieldLabel: 'Estimate',
onBlur: function(field) {
return this.setValue(this.getValue().replace('.', ','));
},
listeners: {
render: function(field) {
field.setDisabled(field.getValue() == 'abc');
}
}
});
this.timeFld.setValue('abc');
// this.time.setDisabled(this.time.getValue() == 'abc');
Ext.create('Ext.form.Panel', {
title: 'Test',
items: [
this.timeFld
],
renderTo: Ext.getBody()
});
// alert(this.timeFld.getValue());
}
When clicking on the dropdown to select individual months/years the dialog disappears like I am trying to click away.
fiddle: https://fiddle.sencha.com/#fiddle/9m6
Ext.onReady(function() {
Ext.create('Ext.form.Panel', {
title: 'Simple Form',
bodyPadding: 5,
width: 350,
// The fields
defaultType: 'textfield',
items: [{
xtype: 'datefield',
fieldLabel: 'Start Date',
id: 'startDate'
}],
renderTo: Ext.getBody()
});
});
This has been fixed in ExtJs 5.1.0.107
EXTJS-15968 Date Picker disappear after click on Month Picker.
http://docs.sencha.com/extjs/5.1/whats_new/release_notes.html
It turned out to be a bug indeed in Ext.Js v 5.0.1.
http://www.sencha.com/forum/showthread.php?289825
Solution with overriding Ext.picker.Date class worked for me:
Ext.define('EXTJS-14607.picker.Date', {
override: 'Ext.picker.Date',
runAnimation: function(isHide) {
var me = this,
picker = this.monthPicker,
options = {
duration: 200,
callback: function() {
picker.setVisible(!isHide);
// See showMonthPicker
picker.ownerCmp = isHide ? null : me;
}
};
if (isHide) {
picker.el.slideOut('t', options);
} else {
picker.el.slideIn('t', options);
}
},
hideMonthPicker: function(animate) {
var me = this,
picker = me.monthPicker;
if (picker && picker.isVisible()) {
if (me.shouldAnimate(animate)) {
me.runAnimation(true);
} else {
picker.hide();
// See showMonthPicker
picker.ownerCmp = null;
}
}
return me;
},
showMonthPicker: function(animate) {
var me = this,
el = me.el,
picker;
if (me.rendered && !me.disabled) {
picker = me.createMonthPicker();
if (!picker.isVisible()) {
picker.setValue(me.getActive());
picker.setSize(el.getSize());
picker.setPosition(-el.getBorderWidth('l'), -el.getBorderWidth('t'));
if (me.shouldAnimate(animate)) {
me.runAnimation(false);
} else {
picker.show();
// We need to set the ownerCmp so that owns() can correctly
// match up the component hierarchy, however when positioning the picker
// we don't want it to position like a normal floater because we render it to
// month picker element itself.
picker.ownerCmp = me;
}
}
}
return me;
}
});
this is my textfield in my formpanel:
{
xtype: 'textfield',
fieldLabel: 'Homepage',
name: 'homepage',
tabIndex: 4,
padding: '10'
}
I want the loaded value which is displayed to be a clickable link.
EDIT:
because webpages without "http://" at the beginning won't display in the new tab, i changed the solution a little bit like this:
listeners: {
render: function (field) {
this.getEl().on('click', function (e, t, eOpts) {
var url = e.target.value;
if (url != '') {
if (url.indexOf("http://") != -1) {
var win = window.open(url, '_blank');
} else {
var win = window.open('http://' + url, '_blank');
}
win.focus();
}
}
}
}
There is no way you can achieve what you desire.For 'link' you have to
use another component may be a label with a link.But with some trick you can make the value in a textfield appear as a link.For that you can do something like this:
{
xtype: 'textfield',
name: 'name',
id:'link',
fieldStyle: 'color: blue; text-decoration:underline; cursor:pointer',
listeners: {
render: function (field) {
this.getEl().on('click', function (e, t, eOpts) {
console.log(e);
//here you need to do some hack around to restrict changing href,only on click of input in the textfield.Could not achieve that,but tried to give some idea.
var url = e.target.value;
if(url != ''){
window.location="";
}
});
}
}
}
Hope this helps you :-)
To do this you can use the render function as follows:
{
xtype : 'displayfield',
id: 'yourId',
name:'yourName',
fieldLabel: 'This is the label',
renderer: function(data, field) {
return ''+data+''
}
}
It may not be the most elegant solution but it works :)
I have put a confirm box on the logout option of my application. Code for the same is as follows:
var abc = Ext.Msg.confirm('Confirm logout', 'Are you sure you want to logout?', function(e)
{
if(e == 'yes')
{
// logout code
}
}
);
No button of the confirm box is visible before the yes button.
How can I display Yes button before the No Button?
Any help is appreciated.
According to the sencha touch source code ( http://docs.sencha.com/touch/1-1/source/MessageBox.html#Ext-MessageBox-method-confirm )
YESNO is defined as "no, yes":
(function(){
var B = Ext.MessageBox;
Ext.apply(B, {
OK : {text : 'OK', itemId : 'ok', ui : 'action' },
CANCEL : {text : 'Cancel', itemId : 'cancel'},
YES : {text : 'Yes', itemId : 'yes', ui : 'action' },
NO : {text : 'No', itemId : 'no'},
// Add additional(localized) button configs here
// ICON CSS Constants
INFO : 'x-msgbox-info',
WARNING : 'x-msgbox-warning',
QUESTION : 'x-msgbox-question',
ERROR : 'x-msgbox-error'
});
Ext.apply(B, {
OKCANCEL : [B.CANCEL, B.OK],
YESNOCANCEL : [B.CANCEL, B.NO, B.YES],
YESNO : [B.NO, B.YES]
// Add additional button collections here
});
})();
You can use Ext.override to override this functionality in your own app:
Ext.override(Ext.MessageBox, {
YESNO: [Ext.MessageBox.YES, Ext.MessageBox.NO]
});
You can override like the below code in ST2.1, Can also implement localization in YES/NO buttons using this.
Ext.MessageBox.override({
confirm: function(title, message, fn, scope) {
return this.show({
title : title || null,
message : message || null,
buttons : [
{text: 'Yes', itemId: 'yes', ui: 'action'},
{text: 'No', itemId: 'no'}
],
promptConfig: false,
scope : scope,
fn: function() {
if (fn) {
fn.apply(scope, arguments);
}
}
});
}
});
It is Very easy Try this
Ext.Msg.confirm("Logout", "Are you Sure u want to LogOut?", function(btn){
if (btn == 'yes'){
Ext.Viewport.setActiveItem({xtype:"Home"}); // which page wants to redirect
}
});
I tried this, and works for me:
Try this solution:
<script type="text/javascript">
(function () {
Ext.override(Ext.MessageBox, {
buttonText: { yes: "Sí", no: "No", cancel: "Cancelar" }
});
})();
</script>
Ext.Msg.show({
title: '提示',
message: '是否继续?',
width: 300,
buttons: [
{text: '是', itemId: 'yes', ui: 'action'},
{text: '否', itemId: 'no'}
],
fn: function (buttonId) {
alert('You pressed the "' + buttonId + '" button.');
}
});