Vincent T Victor Vincent T Victor - 4 days ago 5
AngularJS Question

Angular throws error if html 'name' attribute on a form tag has special characters, ':' in my case

I am working on a Salesforce project, for which I am considering using Angular JS for its super-heroic capabilities. Salesforce prefixes form attributes like name and id with dynamic IDs.
for example if the form attributes name is

customer_registration
it becomes
i10_j30:customer_registration


Angular throws an error when the form's name attribute has special characters, ':' in my case.

I have the following questions.


  1. Why does Angular not allow use of ':' in form names if they are allowed by the browser.

  2. What are the possible work-arounds for this problem.


Answer

AngularJS Developer Guide -- Migrating from 1.3 to 1.4

Form

Due to 94533e57, the name attribute of form elements can now only contain characters that can be evaluated as part of an Angular expression. This is because Angular uses the value of name as an assignable expression to set the form on the $scope. For example, name="myForm" assigns the form to $scope.myForm and name="myObj.myForm" assigns it to $scope.myObj.myForm.

Previously, it was possible to also use names such name="my:name", because Angular used a special setter function for the form name. Now the general, more robust $parse setter is used.

The easiest way to migrate your code is therefore to remove all special characters from the name attribute.

If you need to keep the special characters, you can use the following directive, which will replace the name with a value that can be evaluated as an expression in the compile function, and then re-set the original name in the postLink function. This ensures that (1), the form is published on the scope, and (2), the form has the original name, which might be important if you are doing server-side form submission.

angular.module('myApp').directive('form', function() {
  return {
    restrict: 'E',
    priority: 1000,
    compile: function(element, attrs) {
      var unsupportedCharacter = ':'; // change accordingly
      var originalName = attrs.name;
      if (attrs.name && attrs.name.indexOf(unsupportedCharacter) > 0) {
        attrs.$set('name', 'this["' + originalName + '"]');
      }

      return postLinkFunction(scope, element) {
        // Don't trigger $observers
        element.setAttribute('name', originalName);
      }
    }
  };
});
Comments