ExtJS - disable depending on input value - extjs

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());
}

Related

Stop program flow with Ext.Msg Extjs 4.1.1

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>

ExtJS 6 - Bind disabled property to new records in a store

I'm trying to enable/disable a button when the store getNewRecords() function return the length, but not work!
bind: {
disabled: "{!grid.getStore().getNewRecords().length}"
}
Fiddle: https://fiddle.sencha.com/fiddle/1sj5
Someone have idea to how resolve this?
You need to create a formula in your viewmodel:
viewModel: {
formulas: {
hasNewRecords: function (r) {
return this.getView().down("treepanel").getStore().getNewRecords().length > 0;
}
}
}
then you can use it for your bindings:
bind: {
disabled: "{hasNewRecords}"
}
(probably not the best way to get the data you want).
You can read about it here, here and here .
What you're wanting to do here is currently not possible in the framework. Instead, you should create a ViewModel data value and modify that where need be, like this:
var form = Ext.create("Ext.form.Panel", {
viewModel: {
data: {
newRecords: false
}
},
items: [{
xtype: "textfield",
labelField: "Add Child",
name: "col1",
value: "Teste 123"
}],
tbar: {
xtype: "button",
text: "Add new record",
handler: function () {
var data = this.up("form").getForm().getFieldValues();
var rec = grid.getStore().getAt(0);
data["treeCol"] = rec.childNodes.length + 1;
// setting value, so binding updates
this.lookupViewModel().set('newRecords', true);
rec.appendChild(data);
}
},
bbar: {
xtype: "button",
text: "button to disabled when new records",
bind: {
disabled: "{newRecords}"
}
},
renderTo: Ext.getBody()
});
Or by simply doing this.
In your controller:
me.getView().getViewModel().set('storeLen', store.getNewRecords().length);
In your ViewModel, simply do this:
formulas : {
hasNewRecords : {
get : function(get){
var length = get('storeLen') // --> gets the one you set at your controller
return length > 0 ? true : false;
}
}
}
In your View:
bind : {
disabled : '{hasNewRecords}'
}

ExtJS - 'combocolumn' based renderer - rowediting does not register event or do what it is supposed to

http://2gears.com/2011/05/combobox-editor-remote-and-renderer-for-extjs-editorgridpanel/comment-page-2/#comment-11050?
Please see the function.
I am not using the 'combocolumn' completely. However i have used the major components. Please advise if there is a possibility it should work. As of now the grid refuses to render the column itself and I am unable to pinpoint what the bug is as the code is simply the same?
I did this not to act smart :) - but to simplify and run it on 1 column before standardizing the component common to the project.
The COMBO RENDERING fn()
<code>
function ComboBoxRenderer(combo, gridId) {
var getValue = function (value) {
var idx = combo.store.find(combo.valueField, value);
var rec = combo.store.getAt(idx);
if (rec) {
return rec.get(combo.displayField);
}
return value;
};
return function (value) {
if (combo.store.getCount() === 0 && gridId) {
console.log(combo.store.getCount()+gridId);
combo.store.on(
'load',
function () {
var grid = Ext.getCmp(gridId);
if (grid) {
grid.getView().refresh();
}
},
{
single: true
}
);
return value;
}
return getValue(value);
};
// Ext.getCmp(gridId).getView().refresh();
}
</code>
Editor - in Grid Column Model
{
header: 'Plan Type',
dataIndex: 'plan_id',
editor: {
// allowBlank: 'false',
xtype: 'combobox',
queryMode: 'local',
store: planTypeStore,
displayField: 'plan_name',
valueField: 'plan_id'
}
,renderer: ComboBoxRenderer(this.editor, 'gridPanelId')
/*this is the docs based renderrer - which wont work */
//, renderer: function (val) {
// var rec = planTypeStore.findRecord('plan_id', val);
// return (rec !== null ? rec.get("plan_name") : '');
// }

A formPanels textfield value should be a href link

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 :)

extjs4.1 textfield dblclick event not work in mvc

I work with mvc. When i double click on a textfield it not listening.
But specialkey that means enter work perfectly. where is my fault.
Here is my text field
{
xtype : 'textfield',
name : 'articleName',
fieldLabel : 'Article',
allowBlank : false,
readOnly : true,
width : 253,
enableKeyEvents : true
}
and here is my controller
sv01t01000102 textfield[name=articleName]':{
specialkey: function (field, el) {
if (el.getKey() == Ext.EventObject.ENTER || el.getKey()==el.TAB){
console.log('World')
}
},
dblclick : function(field, el){
console.log('Hello')
}
}
Can you help me?
Field doesn't have a double click event. Typically you'll do something like:
textfield[name=articleName]': {
afterrender: function(c) {
c.inputEl.on('dblclick', function() {
console.log('double');
});
}
}
'textfield[name = articleName]':{
render: function (component) {
component.getEl().on('dblclick', function(event, el) {
alert('You dblclicked on textfield!');
})
}
}
Just in case somebody stumbles over this and want's to solve it in the MVVM way.
View
{
xtype: 'textfield',
listeners: {
afterrender: view => {
view.getTargetEl().on('dblclick', 'onDblclick');
}
}
}
Controller
onDblclick() {
console.log(arguments) // Pick what you need
}

Resources