PDA

View Full Version : Select field with your own picker



gmenuet
21 Feb 2011, 5:56 AM
Hi. Is it possible to make a selectfield with your own picker ? Currently, SelectField support just one column in the pop up showed. I would like something more like the Date Picker, but with my own picker... I don't find anything like that in the forums. I have no choice but to make a custom component?

mitchellsimoens
21 Feb 2011, 7:05 AM
All you have to do is extend the Select component and override the getPicker function I believe. Just look at the Select component's source and you will see what to do.

Just think about slots for the Picker component part of the Select component

gmenuet
22 Feb 2011, 2:29 AM
Thanks for your answer. So right now, i try to extend Ext.form.Field, exactly like the Ext.form.DatePicker ... But, i clearly don't understand everything. I think i'm close but there is still something i miss. I have my select field well-initialized, the picker shows the good value, but nothing happens when i valid my picker... This my code :



Ext.form.PickerHeuresMinutes = Ext.extend(Ext.form.Field, {
ui: 'select',
picker: pickerHeuresMinutes(this.value), //pickerHeuresMinutes is my own Ext.Picker
destroyPickerOnHide: false,
initComponent: function() {
this.addEvents(
'select'
);

this.tabIndex = -1;
this.useMask = true;
Ext.form.Text.superclass.initComponent.apply(this, arguments);
},

getPickerHeuresMinutes: function() {
if(!this.picker instanceof Ext.Picker){
this.picker = pickerHeuresMinutes(this.value);
}
return this.picker = pickerHeuresMinutes(this.value);
},

onMaskTap: function() {
this.getPickerHeuresMinutes().show();
},

onPickerChange : function(picker, value) {
this.setValue(value);
this.fireEvent('select', this, this.getValue());
},

onPickerHide: function() {
if (this.destroyPickerOnHide && this.picker) {
this.picker.destroy();
}
},

setValue: function(value) {
this.value = value;

if (this.rendered) {
this.fieldEl.dom.value = this.value;
}
},

getValue: function() {
return this.picker.getValue()['heures'] + 'h' + this.picker.getValue()['minutes'];
},

onDestroy: function() {
if (this.picker) {
this.picker.destroy();
}

Ext.Picker.superclass.onDestroy.call(this);
}
});


Ext.reg('pickerheureminutefield', Ext.form.PickerHeuresMinutes);


I don't think i should use the handler function of my picker. But i don't have any clue right now...




So you say maybe i should try something new, by overriding Select component ? Maybe it's simpler. I'm gonna look into this...

Thanks again.

mitchellsimoens
22 Feb 2011, 5:33 AM
You can do it two ways...

Assign a custom Picker to a normal Ext.form.Select field:


new Ext.form.Select({
....
picker: new Ext.Picker({ .... })
})

Or extend Ext.form.Select and override the getPicker function with your custom Ext.Picker.

The second way (extending) is the more "professional" way to do it. Either way, you will have to set up a listener to change the value and the the actual field. You can look at the onPickerChange function that the default Ext.form.Select field uses.

mitchellsimoens
22 Feb 2011, 5:34 AM
Look at the Ext.form.Select source code...


/sencha-touch-*/src/widgets/form/Select.js

gmenuet
23 Feb 2011, 12:47 AM
Ok so finally, i made it with some help. I made my component like the Ext.form.DatePicker, extending Ext.form.Field :


Ext.form.PickerHeuresMinutes = Ext.extend(Ext.form.Field, {
ui: 'select',
picker: null,
initComponent: function() {
this.useMask = true;
Ext.form.Text.superclass.initComponent.apply(this, arguments);
},

getPickerHeuresMinutes: function() {
var cmp = this;
if (!this.picker || this.picker.isDestroyed){
this.picker = pickerHeuresMinutes(this.value);
this.picker.addListener("heureSelectionnee", function(heures, minutes) {
cmp.setValue(heures + "h" + minutes);
cmp.fireEvent("heureSelectionnee", heures, minutes);
});
}
return this.picker;
},

onMaskTap: function() {
this.getPickerHeuresMinutes().show();
},

setValue: function(value) {
this.value = value;
if (this.rendered) {
this.fieldEl.dom.value = this.value;
}
return this;
},

getValue: function() {
return this.value;
},

onDestroy: function() {
if (this.picker) {
this.picker.destroy();
}

Ext.Picker.superclass.onDestroy.call(this);
}
});


Ext.reg('pickerheureminutefield', Ext.form.PickerHeuresMinutes);


I had some issues with my picker since this object has a bug. I destroy the picker when i hide it, so my component had a reference to ... nothing i guess. That's why i have a this.picker.isDestroyed in my getPicker. And "this" can be tricky in javascript sometimes ... but that is all my fault. (note to myself). And then the other important part is :


this.picker.addListener("heureSelectionnee", function(heures, minutes) {
cmp.setValue(heures + "h" + minutes);
});

So i have in my picker a picker.fireEvent("heureSelectionnee", heure, minute) on my handler doneButton (where heure and minute is the values of my picker).


And here how you can use it :


{
xtype: 'pickerheureminutefield',
name : 'arrivee1',
id: "arrivee1",
value: '08h01',
listeners: {
heureSelectionnee: function(heures, minutes) {
// whatever you want if you need
}
}
}

That works well. Since my component is a kind of TimePicker, i will need it more than one time, so that is fine, but now i think that a component where you can define each time a different picker would be really great and better.


Thanks again for your clues mitchellsimoens :)

Buckeye
9 Mar 2011, 8:11 AM
gmenuet,

Where is the place you defined "pickerHeuresMinutes" in line 12? Your own picker?

Thanks,

Buckeye

gmenuet
9 Mar 2011, 8:22 AM
yeah exactly, this is just a Ext.Picker defined by me as a global var. It allows me to use the picker on a button (for an handler event for example) but also use on my custom component.

Buckeye
9 Mar 2011, 8:34 AM
gmenuet, thanks for your reply.

I am testing your code now. Could you please give me the line how this pickerHeuresMinutes is defined?

I define it as Ext.Picker but give me a "Result of expression 'this.addEvents' [undefined] is not a function: error.

Thanks.

gmenuet
10 Mar 2011, 3:33 AM
dataMinutes and data heure are juste two array of number for hours and minutes :


pickerHeuresMinutes = function (value){

....

var p = new Ext.Picker({
doneButton:{
text:'Valider',
handler:function(){
p.fireEvent("heureSelectionnee", p.getValue()["heures"], p.getValue()["minutes"]);
this.hide();
}

},
listeners:{
hide:function(){
// BUG PICKER
this.destroy();
this.p;

}
},
cancelButton:'Annuler',
slots: [
{
name : 'heures',
title: 'Heure',
useTitles:true, //not workning
data : dataHeures
},{
name : 'minutes',
title: 'Speed',
useTitles:true, //not working
data : dataMinutes
}
]
});

p.addEvents("heureSelectionnee");
return p;
}

Buckeye
10 Mar 2011, 2:19 PM
gmenuet,

Great! It works! Thanks!

Buckeye

Allen Wu
20 Feb 2014, 6:43 PM
In Sencha Touch 2.3.0+ you can use selectfield's "defaultPhonePickerConfig" OR "defaultTabletPickerConfig" property to define custom style of Picker on Phone / Tablet.