PDA

View Full Version : Adding a Listener to a Fieldset for field changes



mjew
11 Oct 2012, 10:39 AM
I have a fieldset in a form panel with several fields of different types and I want to fire a function when any field is changed. The change listener event is fine for an individual field, but rather that having to put a listener on every single field, is there a listener I can put on the fieldset or the form that fires when any field changes? I tried the updatedata event for the form but that is't doing it.

scottmartin
12 Oct 2012, 5:07 AM
You can use the following:



Ext.create('Ext.form.Panel', {
title: 'Simple Form',
bodyPadding: 5,
width: 350,

layout: 'anchor',
defaults: {
anchor: '100%'
},

// The fields
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
name: 'first',
allowBlank: false
},{
fieldLabel: 'Last Name',
name: 'last',
allowBlank: false
}],

defaults: {
listeners: {
change: function(field, newVal, oldVal) {
console.log('change');
}
},
},

renderTo: Ext.getBody()
});​


Scott

mjew
12 Oct 2012, 1:21 PM
Great, thank you. This works!

marco.marsala
4 Apr 2014, 5:04 AM
Not working in Sencha 2.3.1

scottmartin
4 Apr 2014, 5:13 AM
Not working in Sencha 2.3.1

Do you mean Touch 2.3.1?

This forum is for ExtJS4.x

marco.marsala
4 Apr 2014, 5:28 AM
Ops, sorry. Do you know how to achieve the same thing in Touch 2.3.1?

scottmartin
4 Apr 2014, 5:38 AM
In touch, change fires on blur, so you could do something like this



Ext.application({
name: 'Fiddle',

launch: function() {

Ext.create('Ext.form.Panel', {
fullscreen: true,
items: [{
xtype: 'fieldset',
title: 'About you',
items: [{
xtype: 'textfield',
label: 'First',
name: 'first',
clearIcon: true
}, {
xtype: 'textfield',
label: 'Last',
name: 'last',
clearIcon: true
}],
// on fieldset, or place on form if not present
defaults: {
listeners: {
keyup: function() {
console.log('change');
}
}
}
}]

});
}
});

marco.marsala
4 Apr 2014, 5:46 AM
Already tried, won't print anything to the console.
I'm exploring many codes found on the web. Basically I want to bubble the change event on every form field to the form itself

scottmartin
4 Apr 2014, 6:10 AM
Paste the above code in our fiddle and check the console:
https://fiddle.sencha.com/#home

Did you verify that you have the listener on the correct container?

marco.marsala
4 Apr 2014, 6:28 AM
I tried many places. This is my code for the form using MVC pattern:

View:


Ext.define('LaBucaDiSanMatteo.view.Prenota', {
extend: 'Ext.form.Panel',
xtype: 'prenota',
requires: [
'Ext.form.FieldSet',
'Ext.form.DatePicker',
'Ext.form.Spinner'
],
config: {
items: [
{
xtype: 'fieldset',
title: 'Dati della prenotazione',
instructions: 'Per favore inserire i dati richiesti.',
items: [
{
xtype: 'textfield',
name: 'nome'
label: 'Il tuo nome',
placeHolder: 'Mario Rossi',
autoCapitalize: true,
},
{
xtype: 'selectfield',
name: 'data',
label: 'Quando?',
valueField: 'data',
displayField: 'title',
store: {
data: [
{ data: Ext.Date.format(new Date(), 'd/m/Y'), title: 'oggi' },
{ data: Ext.Date.format(Ext.Date.add(new Date(), Ext.Date.DAY, 1), 'd/m/Y'), title: 'domani'},
{ data: Ext.Date.format(Ext.Date.add(new Date(), Ext.Date.DAY, 2), 'd/m/Y'), title: 'dopodomani' },
{ data: Ext.Date.format(Ext.Date.add(new Date(), Ext.Date.DAY, 3), 'd/m/Y'), title: Ext.Date.format(Ext.Date.add(new Date(), Ext.Date.DAY, 3), 'l j') },
{ data: Ext.Date.format(Ext.Date.add(new Date(), Ext.Date.DAY, 4), 'd/m/Y'), title: Ext.Date.format(Ext.Date.add(new Date(), Ext.Date.DAY, 4), 'l j') },
{ data: Ext.Date.format(Ext.Date.add(new Date(), Ext.Date.DAY, 5), 'd/m/Y'), title: Ext.Date.format(Ext.Date.add(new Date(), Ext.Date.DAY, 5), 'l j') }
]
}
},
{
xtype: 'selectfield',
name: 'ora',
label: 'A che ora?',
valueField: 'ora',
displayField: 'title',
store: {
data: [
{ ora: '19:30', title: '19:30'},
{ ora: '20:00', title: '20:00'},
{ ora: '20:30', title: '20:30'},
{ ora: '21:00', title: '21:00'},
{ ora: '21:30', title: '21:30'},
{ ora: '22:00', title: '22:00'}
]
}
},
{
xtype: 'spinnerfield',
name: 'persone',
label: 'Quanti siete?',
minValue: 1,
maxValue: 10,
value: 2,
stepValue: 1
},
{
xtype: 'numberfield',
name: 'telefono',
label: 'Telefono',
placeHolder: 'Richiesto'
},
{
xtype: 'checkboxfield',
name: 'prive',
label: 'Privé?',
value: 'SI'
},
{
xtype: 'textareafield',
name: 'note',
placeHolder: 'Richieste specifiche, speciali esigenze alimentari, etc...',
label: 'Note',
maxRows: 10
}
]
}
]
}
});


Controller:


Ext.define('LaBucaDiSanMatteo.controller.Prenota', {
extend: 'Ext.app.Controller'
});


Model:


Ext.define('LaBucaDiSanMatteo.model.Prenotazione', {
extend: 'Ext.data.Model',

config: {
fields: [
{ name: 'nome', type: 'string' },
{ name: 'data', type: 'date' },
{ name: 'ora', type: 'string' },
{ name: 'persone', type: 'integer' },
{ name: 'telefono', type: 'string' },
{ name: 'note', type: 'string' },
{ name: 'prive', type: 'boolean' },
],

validations: [
{
type: 'presence',
field: 'nome'
},
{
type: 'presence',
field: 'data'
},
{
type: 'presence',
field: 'ora'
},
{
type: 'presence',
field: 'persone'
},
{
type: 'presence',
field: 'telefono'
}
],

proxy: {
type: 'localstorage'
}
}
});



Main view (instantiating the form):


Ext.Date.dayNames = [
'sunday',
'lunedì',
'martedì',
'mercoledì',
'giovedì',
'venerdì',
'sabato'
];

Ext.define('LaBucaDiSanMatteo.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'tabpanel',
requires: [
'Ext.TitleBar'
],
config: {
tabBarPosition: 'bottom',
items: [
{
title: 'Prenota',
iconCls: 'team',
layout: 'fit',
items: [
{
docked: 'top',
xtype: 'titlebar',
title: 'Prenota un tavolo',
items: [
{
xtype: 'button',
align: 'right',
ui: 'forward',
text: 'Avanti',
handler: function() {
var form = Ext.getCmp('prenota');
var ed = Ext.create('LaBucaDiSanMatteo.model.Prenotazione', form.getValues());
ed.save();

/*form.submit({
url: 'https://www.genovaperte.it/apps/LaBucaDiSanMatteo.php',
waitMsg: 'Attendere...',
success: function(form, result) {
//
},
failure: function(form, result){
Ext.Msg.alert('Si è verificato un errore', 'Il sistema è temporaneamente in manutenzione. Non è stato possibile inviare la prenotazione al ristorante. Si prega di contattare direttamente il locale allo 010 236 23 89. Ci scusiamo per il disagio.');
}
});*/
}
}
]
},
{
xtype: 'prenota',
id: 'prenota'
}
]
},
{
title: 'Promozioni',
iconCls: 'bank',
html: 'bb'
},
{
title: 'Commenti',
iconCls: 'chat2',
html: 'aa'
},
{
title: 'Contatti',
iconCls: 'info',
html: 'aa'
}
]
}
});



I want to bubble events from form fields to the form, so I can check in one single place if all mandatory fields are valid and thus enable the "Next" button in the titlebar (I enable them only when the form is filled).

marco.marsala
4 Apr 2014, 6:29 AM
I forgot to mention this is the clean code. I don't understand very well where to place a code to bubble change event and how to catch it in the form... I tried many ways from documentation but no luck.

scottmartin
4 Apr 2014, 6:43 AM
It is cleaner to move all your events from your view and into your controller and handle then like:



Ext.define('MY.controller.Main', {
extend: 'Ext.app.Controller',

config : {
control : {
'my-main button[action=button1]' : {
tap : 'onButtonClick'
},
'my-main' : {
activeitemchange : 'onItemChange',
foo : 'onFoo',
bar : 'onBar'
}
}
},

onButtonClick : function (button, e) {
Ext.Msg.alert('Alert', 'You just clicked button ' + button._text);
}

});


You should be able to ref your view, get access to your container and then assign the listener.

marco.marsala
6 Apr 2014, 11:40 AM
Thank you. But this doesn't solve my issue. I need to bubble the onChange event from fields to form.

Actually, I can listen to onChange event on every field (I tried to add an onChange: function() { alert('a'); } to every field and the event get fired correctly), but the code to handle the event is the same for all fields.

I need to bubble onChange event to the form, so I can write the onChange handler, only one time, on the form.

I cannot accomplish this task because in all ways I tried, onChange on form won't get never called.