Ant Design: Validating form fields w/custom validators - reactjs

I'd like to use notifications to push form feedback, instead of the inline messaging. e.g.
<Form.Item label="Name">
{getFieldDecorator("name", {
rules: [
{
validator(rule, value, callback) {
if (!value) {
callback("Enter Your Name");
// I'd like to use this instead:
// notification.open({
// message: "Enter Your Name",
// description:
// 'This is the content of the notification.',
// })
}
callback();
}
}
]
})(<Name />)}
</Form.Item>;
Is is possible to validate form fields and maintain the visual feedback (i.e. things like the border-color change), without the inline messaging?

You can do as you showed in your code and use css to hide error messages.
display: none

You can throw custom error message using this.props.form.setFields
this.props.form.setFields({
user: {
value: values.user,
errors: [new Error('forbid ha')],
},
});
Reference for form.setFields

Related

Editable Label And Checkbox Not Working In GrapesJs With React

I am working on grapesjs and Building a custom block. The Problem is that I Want to make the checkbox workable and label to be editable when someone clicks on it. I tried to read documentation of grapesjs and other google stuff but it didn't work :(
Here Is My Code Of Block
import Icon from "../../assets/images/icons8-form-100.png";
export default function upsell(editor, options) {
// // creating new trait for form plugin
// editor.DomComponents.addType("input", {
// // isComponent: (el) => el.tagName === "INPUT",
// model: {
// defaults: {
// traits: [
// {
// type: "text", // If you don't specify the type, the `text` is the default one
// name: "actionUrl", // Required and available for all traits
// label: "Action Url", // The label you will see near the input
// // label: false, // If you set label to `false`, the label column will be removed
// placeholder: "Enter URL", // Placeholder to show inside the input
// changeProp: 1,
// },
// ],
// // As by default, traits are binded to attributes, so to define
// // their initial value we can use attributes
// attributes: { type: "text", required: true },
// },
// },
// });
// creating new block
editor.BlockManager.add("#editor", {
label: `<div>
<img src=${Icon} width="50" style="filter:invert(1)" />
<h3>Upsell</h3>
</div>`,
content: {
// type: "input",
content: `<div class="upsell-comp">
<input data-gjs-editable="true" id="chkUpsell" name="chkUpsell" type="checkbox" />
<label for="upsell">Add On Size With Just $1!</label>
</div>`,
},
});
return;
}
Issue Solved By Using grapesjs-plugin-forms package

How to show Error or Validation messages only after form is submitted and not when user is typing in antd?

I have created a form using Ant Design with Reactjs. It works great except it shows error messages that I have specified for each field under the input field before the "Submit" button is even clicked and user is typing in. It looks very odd and I would like to change that behavior. I want to show these messages only after the submit button is clicked. Is there a way to do it?
I went through the official doc. I couldn't find anything regarding "async validator" or "getFieldDecorator" that suggested what I wanted to achieve.
The "getFieldDecorator" to specify validation rules and error messages for each field is set in this way:
<Form.Item label="Title" style={{ margin: 0 }}>
{getFieldDecorator('Title', {
rules: [{ required: true, message: 'Please input the title', whitespace: true }], initialValue: title
})(<Input onChange={this.onTitleChange.bind(this)} value={title} />)}
</Form.Item>
My "OnSubmit()" method looks like this:
handleSubmit = () => {
this.props.form.validateFields((err, values) => {
if (err) {
return;
}
this.handleSaveBanner();
});
};
Expected is to show error messages only after the submit button is clicked and not before that even if user types invalid inputs or leaves it blank. Help would be appreciated since I am new to React.
Please look through this. https://ant.design/components/form/#getFieldDecorator(id,-options)-parameters.
There is a option named validateTrigger. It can control when to do validation.
Wish it may hlp you.
As mentioned above we just have to specify the trigger, validateTrigger. In our case onSubmit should do the job.
{
initialValue: '',
rules: [{message: 'Cannot leave blank', required: true},
{max: 25, message: 'Must be less than 25', min: 20},
],
validateTrigger: 'onSubmit' // or 'onBlur' , default -> 'onChange' (change as you wish)
}

AlertInput handler never gets called

I'm using Ionic 4 with React and typescript.
I'm looking to create an alert with a email input and 2 buttons, "cancel" and "accept".
I want the "accept" button to only be available when the user is giving a valid email address. Therefore I want to use a regex in the input field handler, but the handler is never called, not when typing nor when pressing enter. How can I get it to get callled when the user is typing
async showAlert() {
var promise = await alertController.create({
header: "Recevez la photo dans votre boƮte mail",
inputs: [{
name: "email",
type: "email",
placeholder: "email",
handler: () => {
console.log("input Fild Hanlder Called");
}
}],
buttons: [{
text: "cancel",
role: "cancel",
handler: cancel => {
console.log("cancel");
}
},
{
text: "envoyer photo",
role: "send",
handler: (alertData) => {
console.log((/^[a-zA-Z0-9]+#[a-zA-Z0-9]+\.[A-Za-z]+$/.test((alertData.email))));
}
}
]
});
await promise.present();
let result = await promise.onDidDismiss();
}
tl;tr This feature is not implemented in ionic4: ionic/issues/19059
After comparing the ionic code for rendering a checkbox in an alert and any other input element I came to the sad conclusion that the feature you are looking for doesn't exist.
At the moment it looks like handler on input in alerts is only supported for checkboxes and radio-inputs
There was a PR for ionic3 that added the validators option to AlertInputs to provide angular form validation but its not there anymore in ionic4.
There is still an open issue for ionic3 requesting input validation for alert inputs but non for ionic4 as far as I can see.
Update: new feature request for ionic4

Sencha Touch 2.3: Remove validations from hidden form fields

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.

How to automatically focus first backbone-forms input field?

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.

Resources