Welcome Guest, Not a member yet? Register   Sign In
Form validation with Greater Than won't work with international currencies (comma separated decimal numbers)
#1

[eluser]landitus[/eluser]
Hi, I was trying out the form validation Greater Than like this:
Code:
$this->form_validation->set_rules('value','Value','required|max_length[128]|xss_clean|greater_than[299]');

I'm using this for currency. So I tested with the amount 300,50 and it shows a validation error. The error says it should be greater than 300. In Argentina (and many other countries I presume) currency numbers have the following format:

- 500,40
- 1.000,40

We use the comma to separate the cents and the dot to (optionally) notate thousands. Is there a way to extend the validation or set the separator to a custom value? I feel this could be useful to other international users.
#2

[eluser]CroNiX[/eluser]
You could create a callback and convert the number to a float and then do the comparison.
Haven't tested this, but the original conversion formula was found on php.net
Code:
public function greater_than_intl($str, $max)
{
  if (strpos($str, '.') !== FALSE && strpos($str, ',') !== FALSE && strpos($str, '.') < strpos($str, ','))
  {
    $str = str_replace('.', '',$str);
    $str = strtr($str,',', '.');          
  }
  else
  {
    $str = str_replace(',', '', $str);          
  }
      
  $str = float($str);

  $this->form_validation->set_message('greater_than_intl', 'The %s field must be greater than ' . $max);

  return ($str > $max);
}
#3

[eluser]Aken[/eluser]
You also could extend the library and add your own custom rule, removing the need to add the "callback_" prefix. Good if you intend on using that rule throughout multiple controllers.
#4

[eluser]landitus[/eluser]
I think extending the library would be nicer. Unfortunately I am not fluent enough in REGEX to do so. But I was able to do a minor hack to make the validation work with commas. Before validation I do a string replace to find the dot and turn it into a comma.

This is MY_Form_validation.php file
Code:
/**
  * Money
  *
  * @access public
  * @param string
  * @return bool
  */
public function is_money($input) {
     return (bool) preg_match('/^[0-9]+(\,[0-9]{0,2})?$/', $input);
}

    
/**
  * Greather than Money
  *
  * @access public
  * @param string
  * @return bool
  */
function greater_than_money($str, $min)
{
  $str = str_replace(",", ".", $str);
  if ( ! is_numeric($str))
  {
   return FALSE;
  }
  return $str > $min;
}
#5

[eluser]CroNiX[/eluser]
You forgot to create the error messages.
#6

[eluser]landitus[/eluser]
Thanks for the remainder, but I've created them in the language files, so I'm set! Smile
#7

[eluser]CroNiX[/eluser]
Cool. I never put them there because I copy rules a lot between different projects and it's just easier if the error is contained within the rule.
#8

[eluser]Aken[/eluser]
You'll want to sanitize the numbers further, because given your example, a number with thousands would then contain more than one decimal point, providing incorrect results when comparing. For example:

Code:
$num1 = '102,33';
$num2 = '1.044,98';

$num1 = str_replace(',', '.', $num1); // 102.33
$num2 = str_replace(',', '.', $num2); // 1.044.98

var_dump($num1 > $num2); // bool(true)
#9

[eluser]CroNiX[/eluser]
The one I posted had a check for that.
#10

[eluser]landitus[/eluser]
I see. Good point. Would these 4 examples validate?

1.000
1.000,50
1000
1000.50

I would need to add a rule for the first example, right?




Theme © iAndrew 2016 - Forum software by © MyBB