I added TextEditingController to my TextFormField for reading the user input, but I want to read the input at every update in the TextFormField, and the Controller shows previous updates. In short I want an alternative to something like onChanged method in TextField, since I'm using this for a form, I need to use TextFormField. Suggest me something.
Just add a listener to the TextEditingController.
something like below.
#override
void initState() {
super.initState();
_editingController.addListener(() {
print(_editingController.text);
});
}
#override
void dispose() {
// Clean up the controller when the Widget is disposed
_editingController.dispose();
super.dispose();
}
Hope it helps!
use the onChange(text) function of the TextFormField with a ValueNotifier, this should help you out.
TextFormField(
controller: _Controller,
label: "Input",
currentNode: _Node,
nextNode: FocusNode(),
keyboard: TextInputType.visiblePassword,
onChanged: (text) {
_avalueNotifier.value = text;
},
inputFormatters: <TextInputFormatter>[
BlacklistingTextInputFormatter.singleLineFormatter,
],
validator: (String value) {
if (value.isEmpty) {
return 'Please make inputs';
}
return null;
},
),
Related
I've got an ExtJs ViewModel where I try to use fomulas. The following code is working as expected:
viewModel: {
formulas: {
isPressed: function (get) {
return get('state.attribute');
}
}
}
The debugger pauses two times in this formula. Once when opening the view and once when the state and property is initialized.
But if I try this:
viewModel: {
formulas: {
isPressed: function (get) {
var x = 'state.attribute';
return get(x);
}
}
}
The debugger only stops when opening the view but not the second time, when everything is initialized.
Edit
I tried to do the following. In my component I've got this config:
config: {
target: null
}
target contains a string like 'state.property' from my parent view which contains the component. Now in this component I want a binding to the value of target but don't want to write:
formulas: {
isPressed: {
bind: '{state.property'},
get: function(property) { ... }
}
}
because the value to bind to should be dynamic. I want to reuse the component in different places. So I tried this, but didn't work:
viewModel: {
formulas: {
isPressed: function (get) {
return get(this.getView().getTarget());
}
}
}
The reason this occurs is because it parses the contents of the function to figure out the dependencies. However it only uses a really naive parser, so things like you described won't be picked up. You can explicitly specify dependencies using bindTo:
const viewModel = new Ext.app.ViewModel({
formulas: {
isNameModified: {
bind: {
bindTo: '{theUser}',
deep: true
},
get: user => user.foo
}
},
data: {
theUser: {
foo: 1
}
}
});
I am doing form validations in Sencha Touch 2.3. My model looks like following.
Ext.define('net.omobio.dialog.dialogcc.model.StockTransferDetails', {
extend: 'Ext.data.Model',
config: {
fields: ['to_msisdn','to_profile_id','transfer_lob','transfer_item_status','transfer_product','transfer_qty','transfer_req_type','transfer_item_type','transfer_pack_type'],
validations: [
{ type: 'presence', field: 'to_msisdn' },
{ type: 'presence', field: 'to_profile_id' },
{ type: 'exclusion', field: 'transfer_lob', list: ['null'] },
{ type: 'exclusion', field: 'transfer_req_type', list: ['null'] },
{ type: 'exclusion', field: 'transfer_item_type', list: ['null'] },
{ type: 'exclusion', field: 'transfer_pack_type', list: ['null'] }
]
}
});
Following is a code segment that I use in my controller to remove validations from hidden form fields but no luck.
var form1 = me.getStockTransferRequestPage();
var model = Ext.create("net.omobio.dialog.dialogcc.model.StockTransferDetails", form1.getValues());
// validate form fields
var errors = model.validate();
if (!errors.isValid()) {
// loop through validation errors and generate a message to the user
errors.each(function (errorObj){
//errorString += errorObj.getField() + " " + errorObj.getMessage();
console.log('7777777777777777777 '+errorObj.getField());
if (!Ext.getCmp(errorObj.getField().toString()).isHidden()) {
var s = Ext.String.format('field[name={0}]',errorObj.getField());
form1.down(s).addCls('invalidField');
}
});
Ext.Msg.alert('','stock_transfer.errors.required_fields_empty');
}
I would be much appreciated if anyone could help me to solve this.
Thank you
so there are multiple ways to achieve this, my preference even though some folks won't like it, but it will always work.
I did the following override to solve this problem, tried my best not to affect the normal flow of validation.the first two overrides have to be added somewhere to your overrides folder, you only have to add them once for the whole app.
Ext.Define('Ext.form.field.BaseOverride', {
override: 'Ext.form.field,Base',
/* traverse up and look for a hidden Parent/Ancestor */
isParentHidden: function () {
return this.up('[hidden=true]');
}
/* override isValid basic method to consider skipValidateWhenHidden property, when skipValidateWhenHidden is set to true code should check if the elementor it's Parent/Ancestors is hidden */
isValid: function () {
var me = this,
disabled = me.disabled,
isHidden = me.isHidden(),
skipValidateWhenHidden = !!me.skipValidateWhenHidden,
validate = me.forceValidation || !disabled,
isValid = validate ? me.validateValue(me.processRawValue(me.getRawValue())) : disabled;
if (isValid || !skipValidateWhenHidden) {
return isValid;
}
if (skipValidateWhenHidden) {
isHidden = isHidden ? true : me.isParentHidden();
if (isHidden) {
return skipValidateWhenHidden;
}
}
return isValid;
}
});
and eventually you'll be able to do the following, which is set the property to true on any field so if its not visible for the user, it will survive validation
{
itemId: 'City',
cls: 'AddressCity',
xtype: 'textfield',
emptyText: emptyCityText,
skipValidateWhenHidden: true,
},
another approach is to add a show()/Hide() listener on the fields container to enable/disable the children, disabling the fields would make them skip validation, but i'm not a big fan of managing button states and wiring listeners.
Note
Ext.getCmp() takes component id
errorObj.getField().toString() returns model field name, It won't
return id of the component (hidden) field.
So if model field name matches with hidden field id, It will work. Otherwise it won't work.
The following screenshot shows a combined form for sign-in and sign-up:
The following module is used to render the AuthView:
MyApp.module("User", function(User, App, Backbone, Marionette, $, _) {
User.AuthView = Marionette.ItemView.extend({
className: "reveal-modal",
template: "user/auth",
ui: {
signInForm: "#signin-form",
signUpForm: "#signup-form"
},
events: {
"focus input": "onFocus"
},
onFocus: function() {
console.log("Some input field has received focus.");
},
onRender: function() {
this.signInForm = new Backbone.Form({
schema: {
signInEmail: {
type: "Text",
title: "E-Mail address"
},
signInPassword: {
type: "Password",
title: "Password"
}
}
}).render();
this.ui.signInForm.prepend(this.signInForm.el);
this.signUpForm = new Backbone.Form({
schema: {
signUpEmail: {
type: "Text",
title: "E-Mail address"
},
signUpPassword: {
type: "Password",
title: "Password"
},
signUpPasswordConfirmation: {
type: "Password",
title: "Password confirmation"
}
}
}).render();
this.ui.signUpForm.prepend(this.signUpForm.el);
}
});
});
How can I automatically focus the first field in each sub-form whenever it is rendered? The first fields would be signInEmail for the signInForm and signUpEmail for the signUpForm.
I tried to listen to focus input events. Such an event is triggered when I click into one of the input fields, not before.
Meanwhile, inspired by the current answers I came up with the following helper function:
focusFirstFormField: function(form) {
if (_.isUndefined(form)) {
throw "IllegalStateException: Form is undefined."
}
// TODO: AuthView does not focus first sign-in field.
var firstInput = form.find(':input:first');
if (_.isObject(firstInput)) {
if (firstInput.length > 0) {
firstInput = firstInput[0];
}
else {
throw "IllegalStateException: Form find returns an empty jQuery object."
}
}
_.defer(function() {
firstInput.focus();
});
}
There is still need for improvement, though.
The events object are DOM events which are generally triggered by the user so that's not what you'll likely want to use in this case.
If I'm understanding you correctly you would like to put the focus in the first input of each of the forms but since you can only have focus on one thing at a time and they are rendering together you'll have to choose one or the other.
The simplest option is to add another line at the end of onRender focusing on the input. If your input is generating an input something like this:
<input type="text" name="signInEmail">
Then you can add:
this.$('[name=signInEmail]').focus();
If not you'll have to change the selector this.$(xxxx).focus() to suit.
You can use onDomRefresh event of the view. It will be triggered after view rendered and Dom refreshed.
onDomRefresh: function() {
this.focusFirstInput();
};
focusFirstInput: function() {
this.$(':input:visible:enabled:first').focus();
};
This solution applies to general cases. However, pay attention if you are using Bootstrap. I can't get this work there. Instead, I set autofocus: 'autofocus' in the field and it works.
You can add it to onRender method.
this.ui.signInForm.find('input[type=text]:first').focus();
this.ui.signUpForm.find('input[type=text]:first').focus();
On the onRender method I do :
$(this.el).find(':input[autofocus]').focus();
And I add the autofocus="" flag onto my HTML node. This works for refresh.
I would like to remove the tool from my panel;
SO I have this code, when I add tool Ext.widget to my panel and then I would like to remove this just created tool, how can I do this. I haven't fount the removeTool method. and I tried to us remove method and remove it, but nothing; Here is the code:
if (...) {
var a = Ext.widget({
id: 'kuku',
xtype: 'tool',
type: 'close',
handler: Ext.Function.bind(me.close, me, [])
});
if (closable && !me.hasUICls('closable')) {
me.addClsWithUI('closable');
me.addTool(a);
}
} else {
if (Ext.getCmp('kuku') != null) {
me.remove("kuku", false); //here how can I remove??
me.doLayout();
}
}
If you are unable to remove using id, try using component ref. as arg... something like below
me.remove(Ext.getCmp('kuku'), false);
I have a simple radio button:
new Ext.form.Radio({
id: 'ptype',
boxLabel:'Yes',
name: 'price_type',
value: 1
})
However Im having trouble adding a on click event ot it.
I usually use:
listeners: {
click: function (a,e) {
//event
}
}
As a config parameter, however it does not seem to work in this case.
Any advice appreciated, thanks.
Radio and checkboxes do not have a click event -- I believe you want the check event instead. Your listener should look like:
listeners: {
check: function (ctl, val) {
// val is the new checked boolean value
}
}
Note that the handler config is a handy shortcut for this (also available on buttons). Instead of the listeners syntax you could just do this:
handler: function(ctl, val) {
// etc
}
Try this:
new Ext.form.Radio({
id: 'ptype',
boxLabel:'Yes',
name: 'price_type',
value: 1
onClick: function(e){
.....
.....
}
})
If you're using a CheckBoxGroup, you should do something like this to make sure you are firing on the correct Radio.
listeners: {
check: function(checkbox, checked) {
if(checked) {
// do whatever.
}
}
}