User tests: Successful: Unsuccessful:
It is a common scenario that you create form fields which reference data from a database table, however the form validation API doesn't easily offer a way to ensure the given value actually exists. This PR creates a new validation rule for this purpose.
On a form field referencing data from another table, you can now use validate="exists"
as a validation rule to trigger this behavior. There are two XML attributes used by this validation rule:
exists_table
specifies the database table to check for the value in, i.e. #__content
exists_column
specifies the column in that table to check for the value in, usually this should be a primary key and the rule has a behavior defaulting to the id
column if one isn't specifiedAs an example with com_content, edit administrator/components/com_content/models/forms/article.xml
and change the created_by
field definition to the following:
<field
name="created_by"
type="user"
label="COM_CONTENT_FIELD_CREATED_BY_LABEL"
description="COM_CONTENT_FIELD_CREATED_BY_DESC"
validate="exists"
exists_table="#__users"
/>
Under normal operating conditions, everything should just keep working as you are only shown a list of users from the database in this field type. But, by manipulating the DOM, you could change this value to anything you wanted really. With the validation rule applied, if you've set this to a value that doesn't correspond to a user that exists in the database, then form validation should fail and the save operation should be blocked.
Document the new form validator and its use.
Status | New | ⇒ | Pending |
Category | ⇒ | Libraries |
Labels |
Added:
?
|
Done.
When would you ever want it to not be validated in this use case. In other words why do you need to add the xml
In this specific use case you'd always prefer it to be validated, but the form fields on their own shouldn't be introducing arbitrary rules to be run when form submissions on validated, so you still need to set up the validation rules for your data so that the form API can handle it or handle the validation yourself in your model. This allows developers to offload one validation step from somewhere in their component MVC logic into the $form->validate()
call (and honestly it's a pretty common validation rule, most frameworks with a validation component support some form of this).
i wasnt questioning the need for validation just that you would need to specify in the xml that you want it to be validated as i coudnt think of a scenario where you wouldnt want it to be validated/
For users, a case where your extension can handle the condition of the associated user being deleted without an issue.
In general to do forms right, your field definitions really need three attributes (well, two minimum, the third is an extra validation step you may want depending on the field), each one being a separate concern in the API:
type
- This is the FormField object itself, responsible for the UI aspect of formsfilter
- Tells the API how to filter/sanitize the data as it's read from the data source (typically the request ($_POST
), by default this hits the default case in the InputFilter's clean method)validate
- An optional extra validation step (defined by the FormRule class) after the data has been filtered to perform extra validation logic (for this PR, ensuring the value exists in a given database table; or the color rule for ensuring there's a valid color code)In general the FormField objects themselves aren't involved in filtering/validating data, so they shouldn't arbitrarily be modifying the form definition to create default filter/validation rules.
Rebased. I honestly figured this would get more attention, it's such a common use case if you're actually doing any kind of data validation of your form submissions. Makes me wonder now how much validation is NOT happening
I have tested this item
I have tested this item
Status | Pending | ⇒ | Ready to Commit |
RTC
Labels |
Added:
?
|
Status | Ready to Commit | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2018-05-12 17:17:26 |
Closed_By | ⇒ | mbabker | |
Labels |
Added:
?
Removed: ? |
@mbabker let's add a quoteName for the table and column to make sure we don't run into any collisions with reserved keywords