Skip to content
This repository has been archived by the owner on Jul 1, 2020. It is now read-only.

Numeric allows invalid numbers like "3.1.5" and "32.e.e3" #69

Closed
luyseyal opened this issue Sep 20, 2015 · 17 comments
Closed

Numeric allows invalid numbers like "3.1.5" and "32.e.e3" #69

luyseyal opened this issue Sep 20, 2015 · 17 comments

Comments

@luyseyal
Copy link

If you enter invalid numeric values like "3.1.5" and "32.e.e3" then no error is shown.

<input name="createPayType{{payType.payType}}Amount"
  class="form-control"
  id="createPayType{{payType.payType}}Amount"
  type="number"
  min="0"
  max="9999.99"
  ng-maxlength="{{payType.payTypeLength}}"
  ng-model="payType.payTypeAmount"
  aria-label="{{payType.payTypeDesc}} Amount"
  validation="numeric|between_num:0,9999.99">
@luyseyal
Copy link
Author

This is nested inside an ng-if. Wondering if this is just a classic scoping issue. The element is nuked in the DOM and recreated on selecting from a dropdown.

@ghiscoding
Copy link
Owner

Looking at the validation-rules, the 2 invalid numbers you sent are not passing through the Regex. If you think the scope is an issue then I suggest you use the isolated scope (see the Wiki - Isolated Scope).

Unless you have a plunker that I can debug with, it's a little hard to help you more...

@luyseyal
Copy link
Author

I solved half the problem by creating a dynamicName directive so that it could find the element. I still can't figure out why it is only partially validating.

I'll put together a Plunker and get back with you. This is a spidery demo I'm putting together and I'm a total Angular noob so I'm struggling, for sure. Thanks!

@ghiscoding
Copy link
Owner

Have you tried defining the Isolated Scope like I mentioned in my first reply. If you didn't then you seriously should.

@luyseyal
Copy link
Author

@ghiscoding

Here's the plunker for the intramodal problem I'm experiencing. Again, it is testing the range just fine (0-9999.99) but not the Regex as you said.

http://plnkr.co/edit/V3qGHusBu3aW3ejLOAPI?p=preview

@ghiscoding
Copy link
Owner

I'm not sure about your problems but what I noticed so far is that you are showing the result with a binding just over each input with {{item.id}} and for some unknown reason when you enter double decimals that text result (which is the id) disappears. So perhaps your problem is related to HTML5 validate or something else? Even after removing the validation completely, that behavior still shows up. So you might want to fix that first, that might explain the rest...

before_error
after_error

@luyseyal
Copy link
Author

On that thought, I have changed it to <input type="text"... and it seems to be working. Weird. Why would angular-validator parse it correctly for type=text but not type=number?

@ghiscoding
Copy link
Owner

I had problems with that too at the beginning, I even blocked character input so that it doesn't influence the validation but at the end I removed that character blocking because it caused other indirect problems.
On another note, I don't have that problem on my own Plunker demo, it might be related to your own code, maybe in your Directive or something else. I also always add the novalidate in my forms to bypass HTML5 auto validation, but in your case you don't even have a form. It's hard to exactly pinpoint your problem, but I have a feeling it's related to HTML5 or $compile.

So if that fixes your problem, you could close the issue... and if you like my Angular-Validation, you could click on the Star on top (if you haven't already done so).
Thanks

@luyseyal
Copy link
Author

There is a <form> tag. On your suggestion, I added novalidate to it in the Plunker. It has the same problem, though.

... I also tried removing dynamic-name, reducing the list to 1 item, and setting name="foo" and it still has the same problem with type="number".

... Also tried moving the <form> tag closer to the element but that makes no difference.

@ghiscoding
Copy link
Owner

is this still a problem, did you find a resolution? Can I close the issue?

@luyseyal
Copy link
Author

I wouldn't call it "solved" but the workaround is changing from <input type="number"...> to <input type="text"...>. I never could solve it in the Plunker or my application so I am using the workaround.

@ghiscoding
Copy link
Owner

I'll see if I can look at it later on, but I don't currently have the time right now since I'm working on implementing validation for external 3rd party addons (like ngTagsInput, multipleSelect, etc..). I will hopefully push that implementation this week.

At least you have a workaround for the time being.

@ghiscoding
Copy link
Owner

Note: I don't know if you had time to read the 2 messages I sent a day before, but I deleted them from the thread since they were wrong information.

Scrap all that, I found the problem. It's multiple factors that comes into play. Let's analyze all that.

1- Reading the AngularJS documentation
Issues with HTML5 constraint validation
In browsers that follow the HTML5 specification, input[number] does not work as expected with ngModelOptions.allowInvalid. If a non-number is entered in the input, the browser will report the value as an empty string, which means the view / model values in ngModel and subsequently the scope value will also be an empty string.

2- Also, you did not make the validation as required

validation="numeric|between_num:0,9999.99"

3- Angular-Validation make a field as Valid if the field is empty and not required.

[A] Which mean that if you take Step1 into effect (it returns undefined or empty) and you add up Step2 (value not required) and Step3 (Valid if empty + non-required) = Field is Valid ... and there you go.

So the end of the story is, because of HTML5 browser if the user types in invalid characters, let say "2.5.aaa" (in Firefox you can, but Chrome seems to block that) it will make the value as undefined. There is nothing I can do about that unfortunately since a $watch will really returned undefined.
BUT if you make the field as required the validation will catch it and make it look like a value was never entered (because undefined is like never entered).

I would basically suggest you use the required if you can. If you can't use required, then stick with input[text] so that at least the validation can get a real value instead of undefined.

Suggestion?
Does that answer all your questions?
Please give me some feedback. Thanks

@luyseyal
Copy link
Author

luyseyal commented Oct 7, 2015

Sorry, just been busy. My parents are having their 40th anniversary so I'm putting together a slideshow and editing a video together, I'm launching a startup, we're moving into a house, and I'm trying to keep my dayjob happy. :)

required might be OK so long as I force a default. This is for a demo so that could be fine... though, if you did blank it out but set the radio to another option, it would complain the field is "required" even though you weren't even selecting that option. Bad UX.

I could write something to stick the default back in if you blank it out but that seems like overkill and might interfere with your validation.

o  Option 1   [50]
o  Option 2   [500]
o  Option 3   [183.33]

Does Angular-validation have an option to reset a field back to its default value if you blank out the field and click/tab out of it?

That would be cool because then it would pass validation.

Something like:

<!-- "default_on_blank" would use what's in the value attribute if the user blanked the field -->
<input type="number"
  name="mynumb" 
  id="mynumb"
  value="99"
  validation="numeric|between_num:0,9999.99|default_on_blank">

I'm uncertain how well this would work with ng-value/ng-model.

Best,

-s

@ghiscoding
Copy link
Owner

Wow that is we call quite busy, hope you have time to sleep in between...

Now to resume some of your questions/answers

  • Just need to make sure you understood that input[number] is returning undefined is an HTML5 constrain (they could call that a feature lol). Basically implemented in each browsers.
    • Note: Angular-Validation cannot distinct differences between a input[number] that has wrong characters typed and a virgin input, in both cases what Angular-Validation sees is undefined. I lost lot of hours of debugging to find that out and it sometimes come back too, your issue is the perfect example.
  • Not sure to fully understand your demo with the radio button. But if you mean radio button that would display/hide an input, then you can make that input disable (validation is skipped on disabled element), or you could also use interpolation to add/remove validators dynamically. Something like this:
<input ... validation="numeric|{{ isRequired }}" />
  • On previous note, Angular-Validation support this that might help
    • disabled / ngDisabled (disabled element are completely skipped)
    • interpolation
    • ngIf / ngShow (destroy is watched, so validation goes away too)
    • For all of these, you can find demos in the /more-examples/ folder of the project
  • Does Angular-Validation support reset on a field? On a field NO, but on a form Yes.
    • What I support instead is (Wiki) Reset of Form. It was made for a complete form reset.
    • Implementing a reset of a particular field shouldn't be too hard since I already implemented a full reset, but what would trigger a reset? I don't understand what your default on blank would do...
    • Side note the validation attribute should only contain Validators. If you want a new feature, it would go as another html attribute, preferably starting with the word validation so it doesn't get mixed with other library, perhaps validation-default-on-blank="true"
    • By default a blur or tab out triggers a $touched event which I use in Angular-Validation. As soon as an element is $touched or $dirty, I display the error message. In this way, the form doesn't display errors when going in the page at first (less annoying to the user).
    • If you want to blank out a field, why don't you do it with an ngBind or interpolation?

ghiscoding added a commit that referenced this issue Oct 13, 2015
- Added sanitize to the demo page
- Fixed issue #69, display proper error message when user type invalid
chars on an input[number]
@ghiscoding
Copy link
Owner

After some code refactoring, I found the proper way to trigger bad input on an input[number]. Once a user start typing invalid characters, it automatically replace the error message by the following:
Invalid keyboard entry on a field of type 'number'.

So your original issue is now fixed, for anything else, please open another one.

Thanks for your feedback, it helped making the library better :)

@luyseyal
Copy link
Author

You're welcome and thanks for your hard work on this!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants