0

The concept:

<form-field ng-repeat="field in fields" field-model='settings[field.name]'
   {{field.match == undefined && '' || 'field-match="settings[field.match]"'}}>
</form-field>

As you can see, i'm trying to get conditional attribute - if field.match is set - I'd like to get:

<form-field field-model='settings[field.name]' field.match="settings[field.match]"></form-field>

otherwise:

<form-field field-model='settings[field.name]'></form-field>

Unfortunately I got Error: The string contains invalid characters.

I tried (? : ) syntax with the same result, but I found AngularJS conditionals in HTML Attribute that it should be && || syntax... What I'm doing wrong?

edited Here's my directive:

KPNDirectives.directive("formField", function ($compile) {
  return {
    restrict: 'E',
    replace:true,
    scope: {
      fieldModel : '=', 
      fieldMatch : '=' 
    },
    template:"<div></div>",
    link: function (scope, element, attrs) {
      var type = attrs.fieldType || 'text';
      var requiredAttr = attrs.fieldRequired ? ' required' : ""
      var requiredHelp = ""
      var matchAttr = ""
      var matchHelp = ""
      console.log(attrs);
      if (attrs.hasOwnProperty('fieldMatch')) {
        matchAttr = " password-match=\"fieldMatch\"";
        matchHelp = '<span ng-show="form.'+attrs.fieldName+'.$error.unique">NOT UNIQUE</span>';
      } else {
        matchAttr = ""
        matchHelp = ""
      }
      if (attrs.fieldRequired == "true") {
        var requiredAttr="required"
        var requiredHelp = '<span ng-show="form.'+attrs.fieldName+'.$error.required">REQUIRED</span>';
      } else {
        requiredAttr = ""
        requiredHelp = ""
      }

      var htmlText =  
      '<div class="form-group" ng-form="form" ng-class="{true: \'has-error\', false: \'has-success\'}[form.'+attrs.fieldName+'.$invalid]">'+
      '<label class="control-label col-sm-2" for="'+attrs.fieldName+'">'+attrs.fieldLabel+'</label>'+
      '<div class="col-sm-6">'+ 
      '<input class="form-control" type="'+type+'" placeholder="enter valid name" name="'+attrs.fieldName+'" ng-model="fieldModel" ng-minlength=3 ng-maxlength=20 '+ matchAttr + requiredAttr+'/>'+
      '<span class="help-block">'+
      requiredHelp +
      matchHelp+
      '<span ng-show="form.'+attrs.fieldName+'.$error.minlength">TOO LESS CHARS</span>'+
      '<span ng-show="form.'+attrs.fieldName+'.$error.maxlength">TOO MUCH CHARS</span>'+
      '&nbsp;'+
      '</span>'+
      '</div>'+
      '</div>';
      // console.log(htmlText)
      element.append(htmlText);
      $compile(element.contents())(scope); 
    }
  }
});

1 Answer 1

1

Templates and in general parseable text only goes inside attribute values (when some directive uses them) or in plain text nodes, surrounded by curlies.

You can obtain the needed result by putting your codintional inside of the field-match attibute, like

<form-field ng-repeat="field in fields" field-model='settings[field.name]'
   field-match="{{field.match && settings[field.match]}}">
</form-field>

Edit (after the OP added his code):

To interpolate values in attributes, use attrs.$observe (see ng.$compile.directive.Attributes ) in the link function, instead of linking the attribute in the isolated scope definition.

attrs.$observe("fieldMatch", function(fieldMatch) {
     $scope.fieldMatch = fieldMatch;
  }
)
Sign up to request clarification or add additional context in comments.

7 Comments

Syntax Error: Token 'field.match' is unexpected, expecting [:] at column 3 of the expression [{{field.match && settings[field.match]}}] starting at [field.match && settings[field.match]}}]
It depends on the directive you use. form-field as far as I remember is not part of AngularJS, so be sure to read the documentation, or to manage correctly the value templating if you have written the directive.
It's my own directive and you're right - it expects that field-match is an object not string.... that's why i'm trying to put whole attr in {{ }}
If it expects an object, then try with field-match="field.match && settings[field.match]"
Attributes {$$element: JQLite[1], $attr: Object, ngRepeat: "field in tabItem.fields", fieldModel: "settings[field.name]", …} $$element: JQLite[1] $$observers: Object $attr: Object fieldMatch: "field.match && settings[field.match]" fieldModel: "settings[field.name]" fieldName: "newpasscompare"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.