I asked a pretty tough question on Jquery Validation earlier on, and nobody seems able to answer it, so I am just going to go for the more basic how-to question...
Say I have a form (MVC2 asp.net form might I add), one textbox, on textbox with DateTime in it and one radio button (the values of the Radio Button are Yes or No). How do I get simple custom validation on those Form Elements if I know the name of the form elements?
Keep in mind these elements are going to be generated Dynamically and so are there validation rules... I am for now just hoping to fudge it a little bit and put permanent validation in there...
I am a complete Jquery and Javascript nooob... All I have ever done with either programming language was add simple tools into my code...
Thank you for your help.
How do I get simple custom validation on those Form Elements if I know the name of the form elements?
The documentation contains many examples of how to setup the plugin. Here's an example with static rules:
$('#myform').validate({
rules: {
Name: {
required: true
},
DateOfBirth: {
required: true,
date: true
},
IsMajor: {
required: true
}
}
});
and if you wanted to dynamically add those rules you could do this:
$('#myform').validate();
and then dynamically add rules to individual form elements:
$('#Name').rules('add', {
required: true
});
$('#DateOfBirth').rules('add', {
required: true,
date: true
});
$('#IsMajor').rules('add', {
required: true
});
You don't need to know the id of the element as long as you assign it to the proper class, e.g. the built-in "required". Set the class and everything else is taken care of.
Related
I would like to get all errors from a form.
I tried to use the live example that came with Angular documentation, and I modified it adding required to the first field:
createForm() {
this.heroForm = this.fb.group({
name: ['', Validators.required],
secretLairs: this.fb.array([]),
power: '',
sidekick: ''
});
}
https://plnkr.co/edit/6b1paWOlKtXnDn1VVCyP
As you can see, if you empty the name field it triggers the required validator and control related to name field has an errors object... but errors property of myForm object is still null. Why?
Shouldn't it contain an object with all errors that are triggered by validators of the children controls?
So what does errors property stand for?
You would have to loop through the controls of the form and see if they contain errors one by one. And I think you can actually have validators on the group it self, the same way you would have validation on a single form control.
I have a Gravity Forms form configuration that contains an input field for the user to type in a value. For now it's just a single line text field. I need to perform validation on this field - preferably upon leaving the field by way of Ajax.
I'm writing a plugin that uses GFAPI and gform_after_submission to process submitted data.
Does Gravity Forms provide actions/hooks for validation by way of Ajax?
Basically, I'm looking for a way to validate an ID that is to be entered by the user on the frontend. If the ID matches some criteria (which includes a database lookup) then I return true or false in an Ajax response.
I see gform_field_validation, but this is intended for when the entire form is submitted, I think. I need to perform validation upon leaving/entering a field, etc. by Ajax.
How can this be accomplished with a Gravity Form?
As far as i know, gravity forms does not provide client side validation:
see this article: https://www.parorrey.com/blog/front-end-development/wordpress-gravity-forms-validation-on-client-side-using-jquery/
For your specific situation i would suggest the following:
in your javascript file:
(function($){
$.validator.addMethod("validateID", function(value, element) {
//do your db lookup here and run the necessary checks
return value === "stackoverflow";
}, "Please enter in a valid ID");
$("form").validate({
rules:{
customer_id: {
validateID: true
}
}
});
$("form").on('submit',function(){
return false;
});
})(jQuery)
JsFiddle Link:
https://jsfiddle.net/craigiswayne/xpvt214o/214343/
Cross-Field Validation in Template Based Forms
Question: Is it possible to create some sort of validation context that spans multiple fields but does not modify the underlying model? If not, is there a better way to do what I'm doing?
Given a model like this and assuming that changing the model is not possible:
export interface IEvent {
location?: {
address: string;
city: string;
country: string;
};
onlineUrl?: string;
}
What is the best way to build a template-based form that will require either all of the location object (address, city, country) to be populated OR the onlineUrl to be populated?
Here is a working Plunk where I have the custom validation working but there are some challenges:
In order to match the model, we need an ngModelGroup around the location fields, but onlineUrl should not be inside that ngModelGroup since it is not part of the location object. Since onlineUrl is not inside the ngModelGroup, it's difficult to come up with a cohesive validation approach. Notice in this example, that we've added a custom validator on the ngModelGroup, that seems to break some basic validation premises - for example, notice that when the fields are invalid that the red highlighting only shows up next to the location field because the custom validator is on the ngModelGroup and onlineUrl is not inside that group.
Typing in the onlineUrl field does not automatically trigger the re-validation since this field is not in the ngModelGroup that has the custom validator on it. In order to make this work I needed to add this binding: (change)="locationGroup.control.controls.address.updateValueAndValidity()" to the onlineUrl field in order to trigger the validation on a field inside the ngModelGroup. This doesn't seem ideal.
Restating the Question: Is it possible to create some sort of validation context that spans multiple fields but does not modify the underlying model?
You can place 'validateLocation' directive up in the top 'form' tag:
<form #myForm="ngForm" (ngSubmit)="save(myForm)" autocomplete="off" novalidate validateLocation>
<fieldset ngModelGroup="location">
Then validate() method gets access to both location and onlineUrl via 'FormGroup.value' and will look like:
if (control && control.value && control.value.location) {
let g = control.value;
if (g.location.address && g.location.city && g.location.country)
return null;
if (g.onlineUrl)
return null;
}
return {validateLocation: false}
Try this plunker. Form.valid would become true when either location or url is captured.
When using a data aggregation on sap.m.Select, the first entry is always selected. Here's a link to the SDK's preview.
Example code from my app
new sap.m.Select("id-names", {
width: '100%',
}).bindAggregation("items", "data>/trip/names", new sap.ui.core.Item({
text: "{data>Name}"
}));
There is a parameter called selectedKey on the constructor to change this to another index. What I want is the select to be blank, because I want to force my users to make a choice, not blandly accept the first entry in the list.
I could force an blank entry in my aggregation data>/trip/names but that would pollute my list.
Is there a better way to achieve this?
Since the OpenUI5 version 1.34, you can set the forceSelection property to false.
The forceSelection property indicates whether the selection is restricted to one of the items in the list. The default value is true (which means, if the selection is not set, the first item in the dropdown list is selected).
When to set it to false?
If you do not want a default item to be pre selected.
Additional information
https://github.com/SAP/openui5/commit/b2191fd50e2115f8f9d2db7604a75fb50c57591f
Currently, no. There seems to be no better way.
There is a ticket for that on GitHub.
It's also my opinion to avoid messing with the dataset and much liked the idea of adding an additional item aggregate. However my improvement on this is to use a formatter on the control itself so it is clearly visible and executed at the right time.
I make use of a formatter with fully qualified controller to get the control as 'this' parameter. In the formatter function I add a ListItem, as proposed by #Victor S
In XML view
<Select forceSelection="false" selectedKey="{model>/key}" items="{path: 'model>/Items'}" icon="{path: '', formatter: 'mynamespace.Utils.addDeselectOption'}">
In the Utils controller:
addDeselectOption: function() {
var that = this;
this.getBinding("items").attachDataReceived(function(){
that.insertItem(new sap.ui.core.ListItem({text: '', key: undefined}), 0);
});
}
Works form me in UI5 1.52
Even though this solution is not great, I managed to get the empty field stick by adding both, the forceSelection=false property, and also in the controller's onInit function (I used the Select element):
var codeField = this.getView().byId("codeField");
setTimeout(function() {
codeField.insertItem(new sap.ui.core.ListItem({text: '', key: undefined}), 0);
}, 1000);
If the forceSelection=false is left out, the field will load either too early or too late to the drop down, which will cause the wrong selection to be visible. Hope it helps someone.
You can also extend the control and build you own select with e.g. an additional parameter add empty choice...I am actually also thinking about that...
I made a combobox using sap.m library:
var oSelection = new sap.m.ComboBox({
name: <name>,
id: <id>,
items: {
<items here>
})
},
});
Now, how do I make this field kind of read only, so when I tap it on mobile, it wouldn't bring up the mobile's keyboard, but it would bring up the selection options?
I've tried to use editable: false, but it disables the selection together with keyboard.
Thank you.
From what I could find out there's no method that allows such behaviour.
One option, that I personally would not advice, is to access the HTML DOM and disable the input field that composes the sap.m.Combobox component.
Keep in mind that if the development SAPUI5 changes the inner workings of the Combobox component your code could be broken if you update the SAPUI5 libraries.
This being said, to use this option you could do something like:
oSelection.onAfterRendering = function() {
if (sap.m.ComboBox.prototype.onAfterRendering) {
sap.m.ComboBox.prototype.onAfterRendering.apply(this);
}
document.getElementById("<id>-inner").disabled=true;
}
replace the < id>-inner by the correct id given to your component.
This was tested using version 1.22.8 of SAPUI5 development toolkit.
Use sap.m.Select instead of sap.m.ComboBox.
Select does not provide the ability to edit the field content.
In many instances the Select control can directly replace a ComboBox without any other changes to the properties or the items aggregation!