We are using angluar-formly forms to make our forms. However when a user inputs an invalid input we would like for them to have a clear error message. So I have created a validator using expression: and message: however I cannot get the message to show up.
The controllers fields value contains:
{
key: 'port',
defaultValue: 2301,
type: 'input',
validators: {
isPort: {
expression : function(viewValue, modelValue) {
var value = modelValue || viewValue;
return !value || (/^\d+$/.test(value) && value!='' && value>0 && value<65535);
},
message: '$viewValue +" is not a valid port"'
}
},
templateOptions: {
type: 'number',
required: true,
label: 'Port',
placeholder: 'Enter Port'
}
}
and we call on the fields in our html code:
<formly-form model="execServers" fields="informationFields" form="form2"></formly-form>
However we do not see the error message show up. It does go to red and show invalid just no message.
I have also created a jsbin depicting my problem http://jsbin.com/weyotudoqu/1/edit?html,js,console,output
I am pretty sure I am just missing something simple as I have looked at lots of examples which do this exact thing and have the text show up http://angular-formly.com/#/example/intro/codementor
I think it doesn't show because you don't set to display error in html of input. Like that:
<md-input-container class="md-block">
<label>{{to.label}}</label>
<input ng-model="model[options.key]">
<div class="my-messages" ng-messages="options.formControl.$error" ng-if="options.validation.errorExistsAndShouldBeVisible">
<div class="error-message" ng-message="{{::name}}" ng-repeat="(name, message) in ::options.validation.messages">
{{message(options.formControl.$viewValue, options.formControl.$modelValue, this)}}
</div>
</div>
</md-input-container>
You can see detail at http://angular-formly.com/#/example/advanced/validators
I was able to get this fixed. I realize I was missing some additional configurations as are outlined in this example
http://angular-formly.com/#/example/other/error-summary
Related
I am trying to create an input that takes a string that will be used as the href value for a tag. The href can be a url OR an email (for mailto:).
It works if I just check for email, or if I just check for URL. However, I want to check for one or the other. I am looking through yup documentation but I can't find a way to do an OR.
I noticed that there is a when to test for another field but I'm not checking if another field is true or not, or use test but I also can't seem to get it to work.
const vSchema = yup.object().shape({
text: yup.string().required(),
href: yup
.string()
.email('Link must be a URL or email')
.url('Link must be a URL or email')
.required('Link is a required field'),
});
test this
yup.addMethod(yup.string, "or", function(schemas, msg) {
return this.test({
name: "or",
message: "Please enter valid url or email." || msg,
test: value => {
if (Array.isArray(schemas) && schemas.length > 1) {
const resee = schemas.map(schema => schema.isValidSync(value));
return resee.some(res => res);
} else {
throw new TypeError("Schemas is not correct array schema");
}
},
exclusive: false
});
});
I am using semantic ui and am trying to do some form validation with it.
The scenario I have is the user has 2 options: email,or phone app verrifcation. They select one of the options and enter whatever in a text field then click submit.
However I am not sure how to do rules on this with semantic UI.
I know if I wanted to check if it was blank I could do something like this:
$('.ui.form')
.form({
fields: {
CODE: {
identifier: 'code',
rules: [
{
type : 'empty',
prompt : 'Please enter your verification code'
}
]
}
} } );
However I would like additional rules based upon which option is selected. I have javascript that currently tells me the value of what is selected, and is updated on change. Unsure how to add it into the rules though, so that I can be like -- If phone was select, must be exactly 6 chars long, or IF email was selected, must be 18 chars long (different lengths for different option).
Is there a way to have conditional rules like this? Closet I could find was:
depends: 'id'
Which checks to ensure it is not empty.
Does anyone know how to have conditional rules such as this based on another form element? I am using the most recent version of Semantic-UI
You can do so by adding custom rules.
$.fn.form.settings.rules.atLeastOne = function (value, fields) {
fieldsToCompare = fields.split(",")
if (value) {
// current input is not empty
return true
} else {
// check the other input field(s)
// atLeastOne is not empty
atLeastOne = false
for (i = 0; i < fieldsToCompare.length; i++) {
// gets input based on id
if ($("#" + fieldsToCompare[i]).val()) {
atLeastOne = true
}
}
return atLeastOne
}
}
$(".ui.form").form({
fields: {
number:{
identifier: "number",
rules: [{
type: "exactLength[6]",
prompt: "number has to be 6 chars long"
}, {
// include the input fields to check atLeastOne[email, address, ...]
type: "atLeastOne[email]",
prompt: "Please provide an email or a number"
}]
},
email: {
identifier: "email",
rules: [{
type: "exactLength[18]",
prompt: "email has to be 18 chars long"
}, {
type: "atLeastOne[number]",
prompt: "Please provide an email or a number"
}]
}
}
});
Note that the function uses the input id as the identifier and not the input name. You might also want to look at optional fields.
react-select just upgraded to 2.0.0 so google results on the first three pages are all about older versions, even the official document, and none of them helped.
My select box can show all options correctly, but redux form won't pick up the value, with the warning: Warning: A component is changing a controlled input of type hidden to be uncontrolled.
I wonder what have I missed here...
Form component:
<Field
name="residentialAddress"
label = "Residential Address"
type="select"
component={AddressField}
validate={required}
/>
Component
export class AddressField extends Component {
searchAddress = input => {
let options = []
return myPromise(input)
.then(suggestions => {
options = suggestions.map(suggestion =>
({
label: suggestion.label,
data: suggestion.value
})
)
return options;
}
).catch(
error => {
return options = [{ label: "Auto fetching failed, please enter your address manually", value: "", isDisabled: true }];
}
);
};
render() {
const {
input,
label,
meta: { touched, error },
type
} = this.props;
return(
<FormGroup>
<ControlLabel>{label}</ControlLabel>
<Async
{...input}
placeholder={label}
isClearable={true}
getOptionValue={(option) => option.residentialAddress}
onChange = { value => input.onChange(value.data) }
loadOptions={this.searchAddress}
/>
{ touched && error && <span>{error}</span> }
</FormGroup>
)
}
Solution: Simply remove the {...input} in <Async>.
Unlike regular custom Field component where we need to pass in {input}, the react-select Async component seems to take care of itself very well and doesn't require any intervene. Someone may explain it in a more professional way perhaps...
Also worth mention for those who come across this question:
loadOptions with promise used to require object {options: options} as return type. Now it changes to just array (options as in my code). But I didn't find any document that mentions this one.
Hope this could help.
We have a rule that all of our validation messages must be in a summary, and thus the default "this field is required" doesn't cut it because the messages lose their context in a summary and therefore need specific field indicators.
I have a solution that I like rather well, but it soon became clear that there was a need for messages outside of just the required field (email, url, custom methods like phoneUS, etc), so I made some additions to my function.
I've been using jQuery for a while, but I'm not an expert in the optimization area, so I wanted to get some expert help on whether the function below could be optimized...my question is, "is there actually a better way to handle custom error messages in a summary?"
$('.required, .email').each(function(index) {
var $this = $(this);
var label = (
$this.is(':radio')
? $("label[data-name='"+$this.attr('name')+"']")
: label = $("label[for='"+$this.attr('id')+"']")
);
var customMessages = [{}];
if($this.hasClass('required')){
customMessages.required = "'" + label.text() + "' is required.";
}
if($this.hasClass('email')){
customMessages.email = "'" + label.text() + "' has an invalid email address.";
}
$this.rules("add", {
messages: customMessages
});
});
Here is the jsFiddle:
http://jsfiddle.net/GD5nw/1/
So why not just assign the custom message on a field-by-field basis for each field as is most typically done? It seems less verbose than what you've been doing.
http://docs.jquery.com/Plugins/Validation/validate#toptions
Example for input elements with name attribute assigned as first, second, and address.
$('#myform').validate({
rules: {
first: {
required: true
},
second: {
required: true
},
address: {
required: true,
digits: true // just an example
}
},
messages: {
first: {
required: "your first name is required"
},
second: {
required: "your last name is required"
},
address: {
required: "your address is required",
digits: "must only use digits on address"
}
}
});
Working Demo: http://jsfiddle.net/x4YBw/
I'm using multiple textboxes for users to entry different credit cards#, with jquery validations. Ambiguously, only the first text box validation is working. Validation's are not working for the other boxes. There are no js errors too in error console.
It'll be very helpful if someone can please give me a clue.
//for first textbox
$("#cust_reg").validate({
rules: {
cc_num_local: {
required: true,
creditcard: true
}
}
});
//for second textbox
$("#cust_reg").validate({
rules: {
cc_num_roam: {
required: true,
creditcard: true
}
}
});
the relevant html only: http://pastie.textmate.org/2422338
You can have more then one HTML element using the id of cust_reg. If you do then only one will be available to your JavaScript code since one supersedes the other. It also isn't valid HTML. You'll need to change the name of the second field to be something different like cust_reg2.
Since you have one form and two different ID's you might try combining them in your code.
$("#cust_reg").validate({
rules: {
cc_num_local: {
required: true,
creditcard: true
},
cc_num_roam: {
required: true,
creditcard: true //Not sure if this can be the same name
}
}
});