1

I have a project that generates forms based on the data that is passed in.

We support may field types but, for example, here is the input template:

<label>
    {{fieldSchema.label}}
    <input type="{{fieldSchema.attributes.type}}"
           name="{{fieldSchema.attributes.name}}"
           ng-model="model[ fieldSchema.attributes.name ]" />
</label>

This works great for flat models, however if the model is nested, it falls apart, eg:

$scope.model = {
    manager: {
        first_name: 'John'
    }
}
$scope.fieldSchema.attributes.name = 'manager.first_name';

Is there a way to use $parse or $interpolate or something similar within the ng-model? I've seen examples on how to fetch data in this structure, but I haven't been able to find a two-way binding solution.

(Note: Using angular version 1.5.0)

Edit: Here is a plunk, hopefully this makes it more clear. http://plnkr.co/edit/4E8jlsnuy5HkCZPxSf5z?p=preview

13
  • may I know how your input template is getting rendered? Commented Mar 15, 2016 at 15:57
  • I'm fetching an HTML template (based on what's in fieldSchema), and using element.html( html ); Commented Mar 15, 2016 at 16:00
  • Not clear at all what specific problem is. A demo would help Commented Mar 15, 2016 at 16:09
  • 1
    How about using ng-model-options="{ getterSetter: true }"? Commented Mar 15, 2016 at 16:24
  • 1
    Actually, why not simply prepend fieldSchema.attributes.name with 'model.'? Commented Mar 15, 2016 at 16:32

2 Answers 2

1

If template input template html can be controlled by code, then before rendering/appending html to DOM do manipulate, it in below way.

ng-model="model[fieldSchema.attributes.name]"

to

ng-model="model['manager']['first_name']"

Code

function createNgModel(model){
   var values = model.split('.')
   //and then create a format it do have below format
   //model['manager']['first_name']
};

var template = '<label>'+
    '{{fieldSchema.label}}'+
    '<input type="{{fieldSchema.attributes.type}}"'+
           'name="{{fieldSchema.attributes.name}}"'+
           'ng-model="+ createNgModel(fieldSchema.attributes.name) +" />'+
'</label>';

Or rather a good option would be just append the string value returned by fieldSchema.attributes.name as suggested by @Amit in comments

var template = '<label>'+
    '{{fieldSchema.label}}'+
    '<input type="{{fieldSchema.attributes.type}}"'+
           'name="{{fieldSchema.attributes.name}}"'+
           'ng-model="model.'+ fieldSchema.attributes.name+'" />'+
'</label>';
Sign up to request clarification or add additional context in comments.

3 Comments

That works for one field, but I have dozens, in an ng-repeat and not all of them are under the manager field.
Oh, I see what you're saying... I'd rather not move all of my templates into the directive, but I suppose that's an option.
@MattGrande look at the updated answer...as per Amit's comment
0

I ended up doing what Amit suggested in the comments. Thanks, Amit!

First, I created a getter/setter function in my directive:

function getterSetter( newValue ) {

     var getter = $parse( 'model.' + $scope.wxFormField.attributes.name ),
         setter = getter.assign;

     return arguments.length ? setter( $scope, newValue ) : getter( $scope );
}

Then, I changed the ng-model to a that function, and added the ng-model-options directive.

<label>
    {{fieldSchema.label}}
    <input type="{{fieldSchema.attributes.type}}"
           name="{{fieldSchema.attributes.name}}"
           ng-model="formFieldFunctions.getterSetter"
           ng-model-options="{ getterSetter: true }" />
</label>

Comments

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.