I have 3 field like this:
{
name: 'firstName',
fieldLabel: 'First name',
bind: '{person.firstName}',
xtype: 'textfield',
allowBlank: false,
listeners: {
blur : {
buffer : 1000,
fn : 'detectGender'
},
}
},
{
name: 'middleName',
fieldLabel: 'Middle name',
bind: '{person.midleName}',
xtype: 'textfield',
allowBlank: true,
listeners: {
blur : {
buffer : 1000,
fn : 'detectGender'
},
}
},
{
name: 'lastName',
fieldLabel: 'Last name',
bind: '{person.lastName}',
xtype: 'textfield',
allowBlank: true,
listeners: {
blur : {
buffer : 1000,
fn : 'detectGender'
},
}
},
And I have a function to determine the gender of the user:
detectGender: function () {
const vm = this.getViewModel()
const firstName = vm.get('person.firstName');
const lastName = vm.get('person.lastName');
const personName = `${firstName ? firstName : ' '}${middleName ? middleName : ' '}${lastName ? lastName : ' '}`
if (firstName) {
//ajax request to server with data: personName
// personName migth be SarahSmith, or Sarah, or SarahEllen, or SarahEllenSmith
}
},
It works, but my problem is that function 'detectGender' runs all three times if all these fields are filled in. And my server returns three responses. But i need run this only one time. Maybe there is some way to create an event for the viewmodel to listen when person name has been changed?
Or any ideas on how to send the user name from the three fields only once?
Hope i was clear enoght... Please any help
I think Arthur's comment is probably the simplest way to solve the issue.
However, here's a couple more options.
Opt1 - You could put each of the name fields in a "parent" and listen to the "blur" event on the parent. In the sencha fiddle example, look at the code "Opt1" which I've set up with a "fieldcontainer". Since a container doesn't have a "blur" event, the "focusleave" event is used. I think of my two options, this would be the best as it gives you a good indication the user is done entering the name.
// Opt 1: Detect "blur" on higher level element
// so you know user is done
xtype: 'fieldcontainer',
layout: 'hbox',
fieldLabel: 'Name',
listeners: {
// "Opt1: blur equivilent" for a container
focusleave: 'detectGender'
},
items: [{
name: 'firstName',
emptyText: 'First',
bind: '{person.firstName}',
xtype: 'textfield',
allowBlank: false
}, {
name: 'middleName',
emptyText: 'Middle',
bind: '{person.middleName}',
xtype: 'textfield',
allowBlank: true
}, {
name: 'lastName',
emptyText: 'Last',
bind: '{person.lastName}',
xtype: 'textfield',
allowBlank: true
}]
}
Opt2 - You brought up listening to the viewModel data. I've provided an example of this, but it's basically a "change" event, so you'd get an event each time someone typed a letter in the field, resulting in a similar problem you have now. I did an example for fun, with a throttled function to help delay, but I think you'd end up calling the server way too much as unlike the above, you don't know when someone is "done" entering the name.
This uses the bindings
config on a ViewController, which is a convenience for manually calling viewModel.bind(), which is how you can "listen" to viewModel data.
Here's the fiddle, hopefully it's not too confusing having both examples in one.