2

I have a multi-purpose modal dialog in my app with one text input. Sometimes I need just any text, sometimes I want to restrict the text to match a regex pattern.

I tried adding the regex with jQuery attr like this:

$("#popupTextInput").attr("ng-pattern", "/.*imdb\.com\/title\/.*/");

Doesn't work. When I inspect the rendered element the correct ng-pattern directive appears on the element but the formname.$valid is always true, no matter what I enter.

When I manually add the attribute (with the exact same appearance in firebug) it works as expected.

Instead of a string with the pattern I also tried adding a regex pattern directly to the attribute like this:

var regexp = /.*imdb\.com\/title\/.*/;
$("#popupTextInput").attr("ng-pattern", regexp);

But that doesn't work either.

I am puzzled. Can anybody shed some light on this? I should probably mention that I add the attribute before I create the modal.

ETA: Did some further experiments. I tried having ng-pattern on the input by default and remove when not needed. Something similar happened: When I remove the ng-pattern it is removed from the element (at least inspection doesn't show it) but the regex pattern is still in effect. I tried the $scope.$apply suggestion below (with and without function in $apply) but it has no effect.

Harald
  • 1,007
  • 1
  • 14
  • 27

1 Answers1

3

Try using $scope.$apply(); just after using the jQuery.

$scope.$apply( function() {
    $("#popupTextInput").attr("ng-pattern", "/.*imdb\.com\/title\/.*/");
});

It will cause your bindings to update and probably fix the problem.

To know more about it check out Stack Overflow question on what $apply does and Jim Hoskin's article on $apply

Okay after reading this

I think the correct way to go about it would be.

parent = $("#popupTextInput").parent();
var newInput = $("#popupTextInput").clone();
$("#popupTextInput").remove();
newInput.attr("ng-pattern", "/.*imdb\.com\/title\/.*/");
var compiledElement = $compile(newInput)($scope);
parent.append(compiledElement);
Community
  • 1
  • 1
kartikluke
  • 2,375
  • 1
  • 19
  • 32
  • Thanks for the suggestion but that didn't work either. – Harald Feb 19 '14 at 10:54
  • `$scope.$apply()` should wrap the jQuery DOM manipulation(s): `$scope.$apply(function() { // what you want to apply});` – glepretre Feb 19 '14 at 10:58
  • I did as suggested but this time the ng-pattern doesn't appear on the input at all. – Harald Feb 19 '14 at 11:14
  • Is it possible for you to have two inputs and disable and hide the appropriate one. Though it's still worth looking into dynamically adding ng-attributes. – kartikluke Feb 19 '14 at 11:38
  • Okay after digging around I think the correct method would be to use $compile before inserting into Angular. – kartikluke Feb 19 '14 at 11:45
  • Could you please elaborate on the $compile? I already tried putting 2 inputs on the form and not showing one of them. That didn't work either. Only one shows but it's always the last one that is active. – Harald Feb 19 '14 at 11:57