Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS validation, binding, etc. not working when using jQuery plugins (eg. autoNumeric)

I have an angular form which was using angular's built-in validation successfully. Take the following markup for example:

<form name="numberForm" novalidate>
    <input type="text" required />
    <button type="submit">Submit</button>
</form>

When the browser loads, the input field renders like this (unnecessary attributes removed):

<input class="ng-pristine ng-invalid ng-invalid-required" />

If I were to enter a value in the input field, the markup turns into:

<input class="ng-dirty ng-valid ng-valid-required" />

All of this was working great. Then I implemented two jQuery plugins to implement some masking/input formatting for the form: autoNumeric and jQuery.maskedinput. Now, nothing I do will change the original ng-pristine ng-invalid... classes on the input. It also doesn't seem to allow the binding of models to be successful either.

Any ideas?

I tried creating a http://jsfiddle.net/ma44H/3/, but can't seem to figure out how to get it to work.

like image 344
im1dermike Avatar asked Jun 05 '14 18:06

im1dermike


1 Answers

JQuery and Angular do not cooperate well

Chocolate and Peanut Butter taste great together, but AngularJS and JQuery are a painful mix. We've all tried (with varying success) to accomplish this.

The problem is that JQuery DOM manipulation works outside of AngularJS Digest Cycle. The lesson is usually that using pure Angular is better.

Alternative #1: Angular UI

Try Angular-UI. Set of tools every Angular Developer could use.

Whatever Mask you want to implement can be done with their ui-mask directive:

Want a Date Mask?

    <input type="text" ng-model="date" ui-mask="99/99/9999" />

Currency Mask?

    <input type="text" ng-model="currency" ui-mask="$99999999.99" />

Phone Mask?

    <input type="text" ng-model="phone" ui-mask="1 (999) 999-9999" />

:

See Fiddle

:


Alternative #2: Filters

Angular has built-in filters:

Currency:

$filter('currency')(amount, symbol)

Date:

$filter('date')(date, format)

Insist on using JQuery? Try the jQuery Passthrough directive from the angular-ui toolset. I haven't made use of this directive but it's an intriguing option:

To call something like $.fn.tooltip() simply do ui-jq="tooltip". Note that the name of the function must be identical. This also works for normal jQuery commands such as $.fn.slideUp().

To pass parameters use the ui-options attribute. The value will be evaluated in the $scope context and passed to the function. If defaults are set, the passed options will extend them. If a string is passed, the default options will be ignored.

Use the directive name jq for namespacing inside uiJqConfig. Then sub-namespace options for each function by the name of that function (exactly as it is passed to ui-jq) so that you don't have to pass options every time you call the directive.

like image 90
Dave Alperovich Avatar answered Sep 22 '22 10:09

Dave Alperovich