Allow comma (in addition to dot) in decimals for form validations in CodeIgniter 4

I have a pretty simple task and I don’t know how to adjust my code to an extend, which solves my problem:

I have a pretty simple form with an input-field like this:

<input type="text" name="weight">

In my controller, after calling the respective function, I end up in my validation-part. Have a look here:

public function store()
{
    helper(['form']);
    $data = [];
    
    $rules = [
        'currentWeight' => [
            'label'  => 'weight',
            'rules'  => 'required|numeric',
            'errors' => [
                'required'   => 'The {field} is required.',
                'numeric'    => '{field} needs to be numeric (e.g. 88.2)'
            ]
        ],
    ];
    
    
    if($this->validate($rules)) {           
        $data = [
            'weight'  => $this->request->getVar('currentWeight'),
        ];
        
        $data["success"] = "New Entry point set";
        echo view('useradmin/insert_weight', $data);
        
    } else {
        $data['validation'] = $this->validator;
        echo view('useradmin/insert_weight', $data);
    }
}

So, as you can see, this is super simple. However, the decimal-rule from CI4 only allows . in a decimal-number. So basically, 88.2 is allowed, while 88,2 isn’t. I followed a tutorial on how to use the validator, but everywhere else, it seems like they are doing it different.

My initial thought was, that I could simply str_replace the comma with a dot and let it be checked afterwards. However, it seems like I can’t hook into the $this->validate function with custom rules or even adjusted variables.

I know that I could potentially add a new rule, which takes care of the , in such numbers, but I thought that there would be a smarter, more efficient way.

I also tried using some sort of callbacks, which I wasn’t able to address properly.

From what I have gathered, it seems like there is also an option to use a validation-helper or similar functions like validateData(), but I’m kinda stuck here.

I also wasn’t able to find some kind of locales, which might have solved the problem with the decimal-point. Could you point me in the right direction? I’m using CI 4.5.5

(I found similar questions like this here: Codeigniter form validation allow numeric type to include comma - but this is heavily outdated)

The issue with validating numeric fields with decimals represented as a comma (e.g., 88,2) is a common problem, especially in locales where commas are used as decimal separators. In your CodeIgniter 4 application, you can solve this issue efficiently by normalizing the input before validation.

Here’s how you can tackle this:

1. Normalize the Input Before Validation

You can replace commas with dots in the input data before running the validation rules. This avoids the need to customize validation rules.

Here’s the updated store method:

public function store()
{
    helper(['form']);
    $data = [];

    // Replace commas with dots in the input
    $rawWeight = $this->request->getVar('weight');
    $normalizedWeight = str_replace(',', '.', $rawWeight);

    $rules = [
        'weight' => [
            'label'  => 'Weight',
            'rules'  => 'required|numeric',
            'errors' => [
                'required'   => 'The {field} is required.',
                'numeric'    => '{field} needs to be numeric (e.g. 88.2)'
            ]
        ],
    ];

    // Overwrite the normalized weight before validation
    $_POST['weight'] = $normalizedWeight;

    if ($this->validate($rules)) {
        $data = [
            'weight' => $normalizedWeight,
        ];

        $data["success"] = "New Entry point set";
        echo view('useradmin/insert_weight', $data);
    } else {
        $data['validation'] = $this->validator;
        echo view('useradmin/insert_weight', $data);
    }
}

Explanation

  1. Normalization: The str_replace function is used to replace commas with dots in the input field (weight).
  2. Overwriting the Input: The normalized value is directly assigned to the $_POST global, ensuring the validation uses the updated value.
  3. Validation Rules: The default numeric rule is applied to validate the normalized value.

2. Alternative: Use validateData Method

You can also use the validateData method, which allows you to pass pre-processed data for validation:

public function store()
{
    helper(['form']);
    $data = [];

    // Normalize input
    $rawWeight = $this->request->getVar('weight');
    $normalizedWeight = str_replace(',', '.', $rawWeight);

    $inputData = [
        'weight' => $normalizedWeight
    ];

    $rules = [
        'weight' => [
            'label'  => 'Weight',
            'rules'  => 'required|numeric',
            'errors' => [
                'required'   => 'The {field} is required.',
                'numeric'    => '{field} needs to be numeric (e.g. 88.2)'
            ]
        ],
    ];

    if ($this->validateData($inputData, $rules)) {
        $data = [
            'weight' => $normalizedWeight,
        ];

        $data["success"] = "New Entry point set";
        echo view('useradmin/insert_weight', $data);
    } else {
        $data['validation'] = $this->validator;
        echo view('useradmin/insert_weight', $data);
    }
}

Benefits

  • Simple Implementation: No need to create custom rules or callback methods.
  • Locale Compatibility: Works well for locales that use commas as decimal points.
  • Reusable Code: You can easily adapt this approach to other inputs requiring normalization.

Key Notes

  • Always sanitize and normalize inputs at the earliest stage to avoid inconsistencies in validation or storage.
  • For enhanced localization, you can integrate additional libraries or frameworks that handle locale-based numeric formats if your application demands it.