Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Improved form validation rule error messages. #961

Merged
merged 10 commits into from

2 participants

@cryode

Added two keyword tags that can be added to form validation rule error messages to display the "human" field name and optional rule parameter, replacing the current sprintf method (sprintf is still retained for legacy support, so no current rules are broken).

The sprintf method limits users who may want to use custom messages with only the rule parameter.

The related language file and user guide source file have been updated accordingly. I also removed the closing PHP tags from controller examples in the user guide, as promoting closing PHP tags is just asking for whitespace and broken applications.

I encourage anyone to recommend different tag names or strings, or any other thoughts on this pretty simple update.

$this->form_validation->set_message('min_length', 'The {field} field must have at least {param} characters.');
@narfbg
Owner

What's the use case for this?

@cryode

@narfbg Currently, custom error messages allow the use of two wildcard %s tags, which will be replaced using sprintf() - the first occurrence being the field name, the second occurrence being the rule's parameter (for instance, the value 8 from the rule min_length[8]). A standard example:

$this->form_validation->set_rules('first_name', 'First Name', 'min_length[8]');

$this->form_validation->set_message('min_length', 'The %s field requires at least %s characters.');

// Error Message would read "The First Name field requires at least 8 characters."

The main benefit of this would be allowing users to get only the parameter value if they'd like. Currently, with sprintf(), the %s values are replaced in order; if only one %s exists, it will always be the field name. An updated use case:

$this->form_validation->set_message('min_length', 'All fields require a minimum of {param} characters.');

Using %s here would lead to a very confusing error message! "All fields require a minimum of First Name characters."

Two other side benefits of this are A) a more semantic, user-friendly way of defining custom error messages - {field} & {param} are far more descriptive than %s. And B) the potential ability for easier expansion of custom error messages, maybe through additional tags or something else.

I haven't updated this pull request in a while, so let me make sure it's up-to-date. Again, if there are any better ideas for tag names or something, let me know.

@narfbg
Owner

I don't think that the term semantic is the right one to use here, but OK - those are indeed improvements.

However, could you give a better example than the one shown? All fields will have an error message, so "All fields require a minimum of {param} characters." doesn't really make sense - it would either be repeated numerous times or be incorrect if the rest of the fields don't have the same rule.

@cryode

Maybe "human readable" is a better term. I tend to overuse the word semantic, I think. :laughing:

Agreed that for certain rules and conditions, this is trivial (min_length is just the first rule that popped into my head that has a parameter). A couple of use cases I can think of off the top of my head:

  • Custom callbacks.
  • When someone will only use the rule for one field, and they wish to use a more human language for that field. "Hey, your name has to be at least {param} characters!"
  • Added usefulness if combined with the ability to set field-specific error messages (which I've seen requested a few times).

These are fairly hypothetical - I don't have a downright specific case in mind at the moment. I originally wrote this when someone on the CI forums brought up their specific need for it. I wish I would've noted it in my comments here, because I don't remember it now.

@narfbg
Owner

Okay, could you update the PR?

system/libraries/Form_validation.php
@@ -730,6 +730,27 @@ protected function _translate_fieldname($fieldname)
}
// --------------------------------------------------------------------
+
+ /**
+ * Build an error message using the field and param.
+ *
+ * @param string The error message line
+ * @param string A field's human name
+ * @param mixed A rule's optional parameter
+ * @return string
+ */
+ protected function _build_error_msg($line, $field = '', $param = '')
+ {
+ // Check for %s in the string for legacy support.
+ if (strpos($line, '%s') !== false)
@narfbg Owner
narfbg added a note

false -> FALSE

Also, your patch seems to be adding a new line at the end of the file. This could be due to IDE/text editor settings - please fix it. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
cryode added some commits
@cryode cryode Merge branch 'refs/heads/develop' into feature/form_error_msgs
Conflicts:
	system/language/english/form_validation_lang.php
	user_guide_src/source/libraries/form_validation.rst

Signed-off-by: Eric Roberts <eric@cryode.com>
b9e35f2
@cryode cryode Format tweaks
Signed-off-by: Eric Roberts <eric@cryode.com>
24a13f5
@cryode cryode Find/replace oopsie.
Signed-off-by: Eric Roberts <eric@cryode.com>
7728e74
@cryode

@narfbg Fixed the format stuff (new line was probably just me - I like an extra line at the end). PR should be good to go now.

@cryode

Oh heavens to Betsy, Travis failed on me. Uno momento, por favor.

Edit: It doesn't appear to be anything relating to this code, so apparently I inherited that from someone else's pull request, or CI/Travis is just being goofy. One failure was from time() !== now(), and they were one second apart. Not sure what's up with that.

user_guide_src/source/libraries/form_validation.rst
@@ -469,7 +466,7 @@ Setting Error Messages
======================
All of the native error messages are located in the following language
-file: language/english/form_validation_lang.php
+file: /system/language/english/form_validation_lang.php
@narfbg Owner
narfbg added a note

No slash at the start please - that means an absolute path, which is not the case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@cryode cryode Remove slash!
Signed-off-by: Eric Roberts <eric@cryode.com>
d6a1902
@cryode

I'd argue that it's just a reference for humans to locate that directory, but it's pretty trivial and works either way.

@narfbg narfbg merged commit 749f250 into bcit-ci:develop
@narfbg narfbg referenced this pull request from a commit
@narfbg narfbg Fix issue #539
Form validation language line keys were not prefixed. They are
now prefixed with 'form_validation_' in order to avoid collisions.
The old keys will still work if a prefixed match is not found, but
are DEPRECATED and will be removed in the next major version.

Also added upgrade notes and changelog entries for the new error
message format from PR #961.
d4eec9f
@nonchip nonchip referenced this pull request from a commit in nonchip/CodeIgniter
@narfbg narfbg Fix issue #539
Form validation language line keys were not prefixed. They are
now prefixed with 'form_validation_' in order to avoid collisions.
The old keys will still work if a prefixed match is not found, but
are DEPRECATED and will be removed in the next major version.

Also added upgrade notes and changelog entries for the new error
message format from PR #961.
0f8a7df
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 24, 2012
  1. @cryode
Commits on Jan 27, 2012
  1. @cryode
Commits on Feb 1, 2012
  1. @cryode

    Merge branch 'develop' of https://github.com/EllisLab/CodeIgniter int…

    cryode authored
    …o feature/form_error_msgs
Commits on Apr 14, 2012
  1. @cryode

    Merge branch 'develop' of https://github.com/EllisLab/CodeIgniter int…

    cryode authored
    …o feature/form_error_msgs
    
    Conflicts:
    	system/language/english/form_validation_lang.php
  2. @cryode
  3. @cryode
Commits on Dec 12, 2012
  1. @cryode

    Merge branch 'refs/heads/develop' into feature/form_error_msgs

    cryode authored
    Conflicts:
    	system/language/english/form_validation_lang.php
    	user_guide_src/source/libraries/form_validation.rst
    
    Signed-off-by: Eric Roberts <eric@cryode.com>
  2. @cryode

    Format tweaks

    cryode authored
    Signed-off-by: Eric Roberts <eric@cryode.com>
  3. @cryode

    Find/replace oopsie.

    cryode authored
    Signed-off-by: Eric Roberts <eric@cryode.com>
Commits on Dec 13, 2012
  1. @cryode

    Remove slash!

    cryode authored
    Signed-off-by: Eric Roberts <eric@cryode.com>
This page is out of date. Refresh to see the latest.
View
52 system/language/english/form_validation_lang.php
@@ -26,32 +26,32 @@
*/
defined('BASEPATH') OR exit('No direct script access allowed');
-$lang['required'] = 'The %s field is required.';
-$lang['isset'] = 'The %s field must have a value.';
-$lang['valid_email'] = 'The %s field must contain a valid email address.';
-$lang['valid_emails'] = 'The %s field must contain all valid email addresses.';
-$lang['valid_url'] = 'The %s field must contain a valid URL.';
-$lang['valid_ip'] = 'The %s field must contain a valid IP.';
-$lang['min_length'] = 'The %s field must be at least %s characters in length.';
-$lang['max_length'] = 'The %s field cannot exceed %s characters in length.';
-$lang['exact_length'] = 'The %s field must be exactly %s characters in length.';
-$lang['alpha'] = 'The %s field may only contain alphabetical characters.';
-$lang['alpha_numeric'] = 'The %s field may only contain alpha-numeric characters.';
-$lang['alpha_dash'] = 'The %s field may only contain alpha-numeric characters, underscores, and dashes.';
-$lang['numeric'] = 'The %s field must contain only numbers.';
-$lang['is_numeric'] = 'The %s field must contain only numeric characters.';
-$lang['integer'] = 'The %s field must contain an integer.';
-$lang['regex_match'] = 'The %s field is not in the correct format.';
-$lang['matches'] = 'The %s field does not match the %s field.';
-$lang['differs'] = 'The %s field must differ from the %s field.';
-$lang['is_unique'] = 'The %s field must contain a unique value.';
-$lang['is_natural'] = 'The %s field must only contain digits.';
-$lang['is_natural_no_zero'] = 'The %s field must only contain digits and must be greater than zero.';
-$lang['decimal'] = 'The %s field must contain a decimal number.';
-$lang['less_than'] = 'The %s field must contain a number less than %s.';
-$lang['less_than_equal_to'] = 'The %s field must contain a number less than or equal to %s.';
-$lang['greater_than'] = 'The %s field must contain a number greater than %s.';
-$lang['greater_than_equal_to'] = 'The %s field must contain a number greater than or equal to %s.';
+$lang['required'] = 'The {field} field is required.';
+$lang['isset'] = 'The {field} field must have a value.';
+$lang['valid_email'] = 'The {field} field must contain a valid email address.';
+$lang['valid_emails'] = 'The {field} field must contain all valid email addresses.';
+$lang['valid_url'] = 'The {field} field must contain a valid URL.';
+$lang['valid_ip'] = 'The {field} field must contain a valid IP.';
+$lang['min_length'] = 'The {field} field must be at least {param} characters in length.';
+$lang['max_length'] = 'The {field} field cannot exceed {param} characters in length.';
+$lang['exact_length'] = 'The {field} field must be exactly {param} characters in length.';
+$lang['alpha'] = 'The {field} field may only contain alphabetical characters.';
+$lang['alpha_numeric'] = 'The {field} field may only contain alpha-numeric characters.';
+$lang['alpha_dash'] = 'The {field} field may only contain alpha-numeric characters, underscores, and dashes.';
+$lang['numeric'] = 'The {field} field must contain only numbers.';
+$lang['is_numeric'] = 'The {field} field must contain only numeric characters.';
+$lang['integer'] = 'The {field} field must contain an integer.';
+$lang['regex_match'] = 'The {field} field is not in the correct format.';
+$lang['matches'] = 'The {field} field does not match the {param} field.';
+$lang['differs'] = 'The {field} field must differ from the {param} field.';
+$lang['is_unique'] = 'The {field} field must contain a unique value.';
+$lang['is_natural'] = 'The {field} field must only contain digits.';
+$lang['is_natural_no_zero'] = 'The {field} field must only contain digits and must be greater than zero.';
+$lang['decimal'] = 'The {field} field must contain a decimal number.';
+$lang['less_than'] = 'The {field} field must contain a number less than {param}.';
+$lang['less_than_equal_to'] = 'The {field} field must contain a number less than or equal to {param}.';
+$lang['greater_than'] = 'The {field} field must contain a number greater than {param}.';
+$lang['greater_than_equal_to'] = 'The {field} field must contain a number greater than or equal to {param}.';
/* End of file form_validation_lang.php */
/* Location: ./system/language/english/form_validation_lang.php */
View
25 system/libraries/Form_validation.php
@@ -615,7 +615,7 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0)
}
// Build the error message
- $message = sprintf($line, $this->_translate_fieldname($row['label']));
+ $message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label']));
// Save the error message
$this->_field_data[$row['field']]['error'] = $message;
@@ -767,7 +767,7 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0)
}
// Build the error message
- $message = sprintf($line, $this->_translate_fieldname($row['label']), $param);
+ $message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label']), $param);
// Save the error message
$this->_field_data[$row['field']]['error'] = $message;
@@ -807,6 +807,27 @@ protected function _translate_fieldname($fieldname)
}
// --------------------------------------------------------------------
+
+ /**
+ * Build an error message using the field and param.
+ *
+ * @param string The error message line
+ * @param string A field's human name
+ * @param mixed A rule's optional parameter
+ * @return string
+ */
+ protected function _build_error_msg($line, $field = '', $param = '')
+ {
+ // Check for %s in the string for legacy support.
+ if (strpos($line, '%s') !== FALSE)
+ {
+ return sprintf($line, $field, $param);
+ }
+
+ return str_replace(array('{field}', '{param}'), array($field, $param), $line);
+ }
+
+ // --------------------------------------------------------------------
/**
* Get the value from a form
View
185 user_guide_src/source/libraries/form_validation.rst
@@ -139,7 +139,6 @@ this code and save it to your application/controllers/ folder::
}
}
}
- ?>
Try it!
=======
@@ -240,7 +239,6 @@ Your controller should now look like this::
}
}
}
- ?>
Now submit the form with the fields blank and you should see the error
messages. If you submit the form with all the fields populated you'll
@@ -436,7 +434,7 @@ Here's how your controller should now look::
{
if ($str == 'test')
{
- $this->form_validation->set_message('username_check', 'The %s field can not be the word "test"');
+ $this->form_validation->set_message('username_check', 'The {field} field can not be the word "test"');
return FALSE;
}
else
@@ -446,7 +444,6 @@ Here's how your controller should now look::
}
}
- ?>
Reload your form and submit it with the word "test" as the username. You
can see that the form field data was passed to your callback function
@@ -469,7 +466,7 @@ Setting Error Messages
======================
All of the native error messages are located in the following language
-file: language/english/form_validation_lang.php
+file: system/language/english/form_validation_lang.php
To set your own custom message you can either edit that file, or use the
following function::
@@ -479,29 +476,23 @@ following function::
Where rule corresponds to the name of a particular rule, and Error
Message is the text you would like displayed.
-If you include %s in your error string, it will be replaced with the
-"human" name you used for your field when you set your rules.
+If you'd like to include a field's "human" name, or the optional
+parameter some rules allow for (such as max_length), you can add the
+**{field}** and **{param}** tags to your message, respectively.
-In the "callback" example above, the error message was set by passing
-the name of the function::
+ $this->form_validation->set_message('min_length', '{field} must have at least {param} characters.');
- $this->form_validation->set_message('username_check')
-
-If you are using an error message that can accept two $s in your error string,
-such as:
-::
-
- $this->form_validation->set_message('min_length', 'The $s field must contain at least $s characters.');
-
-Then you can also use %1$s and %2$s:
-::
+On a field with the human name Username and a rule of min_length[5], an
+error would display: "Username must have at least 5 characters."
- $this->form_validation->set_message('min_length', 'This field must contain at least %2$s characters.');
+.. note:: The old method of using **%s** in your error messages will
+still work, however it will override the tags above. You should use
+one or the other.
-You can also override any error message found in the language file. For
-example, to change the message for the "required" rule you will do this::
+In the callback rule example above, the error message was set by passing
+the name of the function (without the "callback_" prefix)::
- $this->form_validation->set_message('required', 'Your custom message here');
+ $this->form_validation->set_message('username_check')
.. _translating-field-names:
@@ -613,7 +604,7 @@ In this case, you can specify the array to be validated::
$this->form_validation->set_data($data);
-Creating validation rules, running the validation and retrieving error messages works the
+Creating validation rules, running the validation, and retrieving error messages works the
same whether you are validating ``$_POST`` data or an array.
**Important Note:** If you want to validate more than one array during a single execution, then you should
@@ -678,56 +669,56 @@ rules. We've arbitrarily called these two rules "signup" and "email".
You can name your rules anything you want::
$config = array(
- 'signup' => array(
- array(
- 'field' => 'username',
- 'label' => 'Username',
- 'rules' => 'required'
- ),
- array(
- 'field' => 'password',
- 'label' => 'Password',
- 'rules' => 'required'
- ),
- array(
- 'field' => 'passconf',
- 'label' => 'PasswordConfirmation',
- 'rules' => 'required'
- ),
- array(
- 'field' => 'email',
- 'label' => 'Email',
- 'rules' => 'required'
- )
- ),
- 'email' => array(
- array(
- 'field' => 'emailaddress',
- 'label' => 'EmailAddress',
- 'rules' => 'required|valid_email'
- ),
- array(
- 'field' => 'name',
- 'label' => 'Name',
- 'rules' => 'required|alpha'
- ),
- array(
- 'field' => 'title',
- 'label' => 'Title',
- 'rules' => 'required'
- ),
- array(
- 'field' => 'message',
- 'label' => 'MessageBody',
- 'rules' => 'required'
- )
- )
- );
+ 'signup' => array(
+ array(
+ 'field' => 'username',
+ 'label' => 'Username',
+ 'rules' => 'required'
+ ),
+ array(
+ 'field' => 'password',
+ 'label' => 'Password',
+ 'rules' => 'required'
+ ),
+ array(
+ 'field' => 'passconf',
+ 'label' => 'Password Confirmation',
+ 'rules' => 'required'
+ ),
+ array(
+ 'field' => 'email',
+ 'label' => 'Email',
+ 'rules' => 'required'
+ )
+ ),
+ 'email' => array(
+ array(
+ 'field' => 'emailaddress',
+ 'label' => 'EmailAddress',
+ 'rules' => 'required|valid_email'
+ ),
+ array(
+ 'field' => 'name',
+ 'label' => 'Name',
+ 'rules' => 'required|alpha'
+ ),
+ array(
+ 'field' => 'title',
+ 'label' => 'Title',
+ 'rules' => 'required'
+ ),
+ array(
+ 'field' => 'message',
+ 'label' => 'MessageBody',
+ 'rules' => 'required'
+ )
+ )
+ );
Calling a Specific Rule Group
=============================
-In order to call a specific group you will pass its name to the ``run()``
+In order to call a specific group, you will pass its name to the ``run()``
method. For example, to call the signup rule you will do this::
if ($this->form_validation->run('signup') == FALSE)
@@ -770,29 +761,29 @@ In your validation config file, you will name your rule group
member/signup::
$config = array(
- 'member/signup' => array(
- array(
- 'field' => 'username',
- 'label' => 'Username',
- 'rules' => 'required'
- ),
- array(
- 'field' => 'password',
- 'label' => 'Password',
- 'rules' => 'required'
- ),
- array(
- 'field' => 'passconf',
- 'label' => 'PasswordConfirmation',
- 'rules' => 'required'
- ),
- array(
- 'field' => 'email',
- 'label' => 'Email',
- 'rules' => 'required'
- )
- )
- );
+ 'member/signup' => array(
+ array(
+ 'field' => 'username',
+ 'label' => 'Username',
+ 'rules' => 'required'
+ ),
+ array(
+ 'field' => 'password',
+ 'label' => 'Password',
+ 'rules' => 'required'
+ ),
+ array(
+ 'field' => 'passconf',
+ 'label' => 'PasswordConfirmation',
+ 'rules' => 'required'
+ ),
+ array(
+ 'field' => 'email',
+ 'label' => 'Email',
+ 'rules' => 'required'
+ )
+ )
+ );
When a rule group is named identically to a controller class/function it
will be used automatically when the run() function is invoked from that
@@ -928,8 +919,8 @@ Name Parameter Description
**encode_php_tags** No Converts PHP tags to entities.
==================== ========= ===================================================================================================
-.. note:: You can also use any native PHP functions that permit one
- parameter, like trim, htmlspecialchars, urldecode, etc.
+.. note:: You can also use any native PHP functions that permits one
+ parameter, like ``trim()``, ``htmlspecialchars()``, ``urldecode()``, etc.
.. _function-reference:
@@ -1087,5 +1078,5 @@ This function is identical to the **set_checkbox()** function above.
::
- <input type="radio" name="myradio" value="1" <?php echo set_radio('myradio', '1', TRUE); ?> />
- <input type="radio" name="myradio" value="2" <?php echo set_radio('myradio', '2'); ?> />
+ <input type="radio" name="myradio" value="1" <?php echo set_radio('myradio', '1', TRUE); ?> />
+ <input type="radio" name="myradio" value="2" <?php echo set_radio('myradio', '2'); ?> />
Something went wrong with that request. Please try again.