Question
How can one build a async validation on a single form field that also can trigger filed level errors, but without using a asyncValidation that also triggers onSubmit?
Background to question
I have a Redux form where the user can choose to:
a) Input adress details by hand
b) Fill in their social security number and fetch all details from a API and get the redux form fields prefilled (wohoo, time saved!)
c) Being 100% anonymous by checking a checkbox which removed all personal details fields.
Given this kind of setup a asyncValidator that triggers onSubmit and onBlur seems tricky, i don't want them to trigger more than once if a get the desired details and the form get pre-filled. But if user submits a invalid social security number I want to trigger a field error.
if you just want to validate a single field, you can pass a prop validate
with an array of validation functions, that will return false if its valid, and a string error if invalid based on your logic. and will prevent submission, or will show an error on submittion.
const required = (value) => (value ? false : 'Required')
const isSSN = (value) => (willBeTrueIfSSN ? false : 'Invalid SSN')
<Field name="ssn" validate={[isSSN, required]} {...rest} />
some good examples in the redux-form docs:
https://redux-form.com/7.2.3/examples/fieldlevelvalidation/
Related
Let's say I have a table with data in the rows coming from a database. On each row of this table there are helper buttons. These buttons perform instant operations on the database, such as setting a status code (for example sold, blocked, in progress), changing an invoice date for the row (for example from 18/11/2022 to null) and so on..
What I would like is that when a user clicks on one of these buttons, an ajax function will performs a request to the related controller that will show a modal box asking for confirmation (not a JS alert but HTML code that comes from a blade component).
So, giving a basic example in the case of the change of status code for the row, what I would do is first set up a route of this type:
Route::post('/status', [TableController::class, 'status']);
after that i will build my controller(using the related model Table) in a way that if the action value coming from the ajax request is confirm(the one coming from the confirmation modal), I will continue with the data update, if instead the action is something different such as status(the one coming from the helper button), then I will bring up my confirmation modal
class TableController extends Controller {
// Change status
public function status(Request $request){
if( $request['action'] == 'confirm' ) {
// Update DB
Table::where('id', $request->id)->update(['status' => 822]);
} else {
$id = $request->id;
// Show confirmation modal
return \Blade::render('<x-confirm :title="$title" :action="$action" :id="$id" />',
[
"title" => "Vuoi bloccare le seguenti disponibilità? ".$id ?,
"action" => "status",
"id" => $id
]);
}
}
If you notice the return of component part here
// Show confirmation modal
return \Blade::render('<x-confirm :title="$title" :action="$action" :id="$id" />'
I'm passing to the component the id of the row, and the action to perform, those datas will be usefull for the next ajax request coming from the confirmation modal, that will update the row in the database. But basically what is happening here?
Send data from frontend to the controller(id of the row, status action, status code).
Send back the same data from the backend to modal component to fill the ajax confirmation request.
Resend back to the server the same data to catch the confirm statement and update the database.
This kind of approach always worked for me, but when things becomes complex(let's say that I have different kind of helpers like I said before, in example remove a date, change the owner, set some flags etc) this will become a mess, because I have everytime to send back the same data that I just received.
So my question:
Is there a way to avoid this thing to sending back and forward those datas? like something in the middle that stores what am I doing in the current session and can inform the modal box without this round trip? Also i am really thinking that my approach is completely wrong and out of mind, so i have to see things from a different point of view? This is because I am self-taught so I certainly have some gaps that I would like to fill.
I am working in a module with Laravel and Vuejs where some fields are by default hidden. And based on user action those hidden fields are unhide and showing as form input field. These hidden fields I need to do validate when user submit the form. Following is my Json Object for creating hidden input field:
"customer_order_details":{
"payment_by": null
}
And Html input field in Vuejs is following:
<input v-model="customer_order_details.payment_by" class ="form-control" placeholder="Payment By">
And validation rules in Request controller is:
$rules = [
'payment_by' => 'sometimes|required',
];
In the above configuration whenever I submit the form whatever payment_by field hide/unhide always show validation error. But I need to show validation error only when payment_by filed is unhidden.
I tried to create a custom data annotation validation attribute (NameValidationAttribute) in MVC 5 project using VS2013. I was able to successfully add the client side validation and the error message for custom validation is getting displayed as soon as the focus leaves the textbox. However, the standard attributes like [Required] and [Range] validators are now not showing proper error messages, says 'Warning: No message defined for 'field' ' (See below screenshot).
Question:
- Why the standard validation error messages are showing as "Warning: No message defined for UnitsInStock"? What am I missing?
Below is my custom client validation script:
I included following scripts in EditProducts page.
Please note that the error messages for UnitPrice, UnitsInStock and ReorderLevel fields are defined with Range validation attribute (see below).
FYI, I tried to change the order of the scripts in ProductEdit page but still its showing the same message.
Please advise!
I ran into this issue. I had created an MVC attribute called PasswordAttribute, with a client side validator called 'password'.
$.validator.addMethod('password', function (value, element, params) {
...[validation logic]
});
$.validator.unobtrusive.adapters.addBool('password');
As soon as I added this logic to the solution I got the error you saw on my Password and ConfirmPassword fields. Note that this occurred before the attribute was even used. Simply renaming the client side validator to 'passwordcheck' fixed the issue. I initially thought that the name 'password' possibly clashed with one of the pre-defined validators (cf. jQuery Validation Documentation) but this doesn't appear to be the case. I suspect now that it is a clash with the name or value for some input field attribute. Anyway, the solution was simply to rename the validator.
jQuery unobtrusive need data-msg for default validate message.
This is how to apply dynamic error message from your model to Html
$.validator.unobtrusive.adapters.add("requireif", function (options) {
$('#' + options.element.id).attr("data-msg", options.message);
// Add rule ...
});
You can change default warning message.
$.validator.addMethod("requireif", function (value, element, pair) {
// validate logic
return true/false;
}, "YOUR DEFAULT MESSAGE HERE");
Or
#Html.TextBoxFor(m => m.Property1, new { Class = "form-control", data_msg = "YOUR DEFAULT MESSAGE HERE" })
Or if you can put it directly to your Html like this.
<input class="form-control" data-msg="YOUR DEFAULT MESSAGE HERE"/>
I made my custom date range validator, and I'm using it on date properties of my entity..
Though, when I get an error it's attached to the form and not to the field.
So I can't display errors with {{form_errors(form.date)}}. (edit : form is a prototype of a child collection)
I saw that : Custom constraint validation error doesn't display next to field in Symfony2 . But I don't want to explicitly specify on which field name the error should be attached..
Maybe it's related to the fact that this error is in a collection of the main form (using his prototype) ?
I could also add that the error is attached to the main parent form (my validator is on a field, which is in a form, which is a collection of a form, which is an embedded form of the main form).
How can I do ?
EDIT : It might be related to that : https://stackoverflow.com/questions/15907415/symfony2-data-prototype-error-bubbling
It is surely related to error_bubbling. It defaults to true if the form is compound, so you should set it to false value.
$builder
->add('field', 'collection', [
'type' => new ChildFormType(),
'error_bubbling' => false,
]);
See symfony doc page about error_bubbling for more details
I only want to require a field if the user has not checked a check box elsewhere on the form.
The checkbox's value is "Yes" if checked or "No" if not checked.
On the Edit Box's validation formula I have the computed SSJS:
getComponentValue("SoleSource") == "No"
the function is stored in as a JS source
function getComponentValue(id){
var field = getComponent(id);
var value = field.getSubmittedValue();
if( null == value ){
// else not yet submitted
value = field.getValue();
}
return value;
}
No matter if the checkbox (with the ID "SoleSource") is checked or not, it always returns "No", which is the default value, and attempts to validate my field.
Is there any way to do this without submitting the form first?
You can get access to the field value only when the value is send to the server. I would suggest a two fold approach. One: use a client side JavaScript to check (for the comfort of the user) and a server side on complete submission (for data integrity).
As stwissel already said there are two ways to validate your inputField, clientSide and on ServerSide. To manipulate the validation depending on user Input i would use ClientSide javascript code to make it feal more 'On the fly' and then validate the whole document on Submit again on the Server Side.
Here a short example how i would build this on ClientSide with dojo. But please dont forget to validate the data again on the Server when the user saves/submits it to avoid corrupted data because of manipulation of your ClientSide javascript (or someone just turns of javascript in his browser).
<xe:djCheckBox id="select" value="#{viewScope.check}"
checkedValue="yes" uncheckedValue="no">
<xp:this.dojoAttributes>
<xp:dojoAttribute name="onChange">
<xp:this.value><![CDATA[#{javascript:return "var input = dijit.byId('"+getClientId('required')+ "'); input.required = !input.required;"}]]></xp:this.value>
</xp:dojoAttribute>
</xp:this.dojoAttributes>
</xe:djCheckBox>
<xp:inputText id="required" dojoType="dijit.form.ValidationTextBox">
<xp:this.dojoAttributes>
<xp:dojoAttribute name="required"
value="true">
</xp:dojoAttribute>
</xp:this.dojoAttributes>
</xp:inputText>
In this example i use dojo to convert my inputField to a dijit.form.ValidationTextBox wich allowes me to change it's required propertie. DojoValidation.