t0berius's avatar

laravel validation float number only positive

Dear community,

in my app users should be able to create coupons for other users, using their own amount of money. I need to validate the entered number of amount a user wants to use for creating a coupon.

The amount of money for a coupon must be at least 1,00. How to validate, so the user can input:

-float numbers seperated by , and . (1,15 3.04)

-numbers must be at least 1,0 (1.0)

-numbers must be smaller than 50,00 (50.00)

The numeric validator wont work, because of it allows +/- and doesn't accept amounts seperated by dots. What's the best way to validate entries like above using laravel validator?

0 likes
16 replies
t0berius's avatar

I thought combining some rules + regex would make this validation done? Am I wrong?

d3xt3r's avatar

Theoretically it could be done, but I am not sure how type casting would behave in this case.

t0berius's avatar

I dont need type casting. Number has just to be "in float" style. So number can have a , or a . to seperate the two parts of it. Hope you understand what I mean.

d3xt3r's avatar

Yes, i was not worried about you type casting it this should work,

    $regex = "/^(?=.+)(?:[1-9]\d*|0)?(?:\.\d+)?$/";

    $v = Validator::make(compact('input'),[
            'input' => array('required','regex:'.$regex)
        ]);

t0berius's avatar

Am I doing wrong?

$regex = "/^(?=.+)(?:[1-9]\d*|0)?(?:\.\d+)?$/";

    $v = Validator::make(compact('input'),[
        'amount' => array('required','regex:'.$regex)
    ]);


    if ($v->fails()) 
        dd("failed");
        //return back()->withErrors($validator)->withInput();

    dd("yes");

Entering "3.06" results in "failed". How to set custom error messages for this validator?

d3xt3r's avatar

1> How are you passing input to validator? 2> Custom messages can be set as

 $v = Validator::make(compact('input'),[
        'amount' => array('required','regex:'.$regex)
    ], [
        'input.regex' => 'Your message " // This is just an example look at the link shared before
    ]);
t0berius's avatar

here's my current function:

 public function createPostCoupon(Request $request)
{
    $regex = "/^(?=.+)(?:[1-9]\d*|0)?(?:\.\d+)?$/";

    $v = Validator::make(compact('input'),[
        'amount' => array('required','regex:'.$regex)
    ]);

    if ($v->fails()) 
        dd("nope");
        //return back()->withErrors($validator)->withInput();

    dd("yes");
}   
d3xt3r's avatar

you will have to pass the input to validator, i just used compact('input') for simplicity.

    $v = Validator::make([
        'amount' => Input::get('amount'), // assuming input is your form field
    ],[
        'amount' => array('required','regex:'.$regex)
    ]);

t0berius's avatar

I think the regex is broken somehow. Entering numbers like: 1,67 results in a fail.

All in all the number should just be XX,XX not XX,XXX, so only two numbers after the "seperator" (comma or dot) should be allowed.

d3xt3r's avatar

:) assumed you are not looking for formatted string. XXX,XX is not a float ( not mathematically ) . you will have to modify regex if you want a comma in there.

yanservicess's avatar

Well, why so complicated? What about using

'number_name' => 'numeric|min:1|max:50',

You do not care, if the number is integer or float, because integer belongs to floats (in mathematical way) and float is a number. I am using this rule and there is no problem (along with html input field type = numeric, step = 0.1)

5 likes
jimmck's avatar

It is not advisable to do currency in floating point. Use whole numbers and manage the decimal. The eventual error will creep up.

1 like
highbridgecreative's avatar

@jimmck Actually, laravel supports the decimal field type in mysql/postgres. This is the best way to store currency values. but yeah, stay away from float/double field types. for the same reason, don't do float calculations in javascript. but PHP calculation are fine. Somebody correct me if I'm wrong.

jekinney's avatar

@highbridgecreative People do it both ways. The argument for integer is you have more fine control and don't have to worry about rounding up or down. In some cases (like gas in the USA) taxes add $0.xxx (gas is $0.009 hence why many signes have the small 9). This can become an issue along with global currency like 2000 Baht (57.274 usd) or 2000 pesos (114.869 usd) etc. So dealing with integers allows for a finer control without losing or gaining the partals.

https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=2000%20pesos%20to%20usd

Big scam years ago by the USA's wall street where computers processing trades didn't use integers and always rounded charges to .xx causing the trading companies to make millions daily a fraction of a cent at a time, though it was proved un-intentional, I highly doubt that.

Please or to participate in this conversation.