json-schema-form / angular-schema-form

Generate forms from a JSON schema, with AngularJS!
https://json-schema-form.github.io/angular-schema-form
MIT License
2.47k stars 653 forks source link

Creating a custom editor for a part of the schema/model tree #775

Closed jazzmanro closed 8 years ago

jazzmanro commented 8 years ago

Hello,

This is actually a question.

I Have a complex model/schema containing complex object structures. I want to create a custom type that I will attach to the property in the form definition and take complete control of the fields that I render and their bindings. But so far examples/add-ons seem to be only editors over a single model field injected by 'sf-field-model'.

Could anyone point me into the right direction of taking complete control? So far in the html template I only got the corresponding form (canonical representation I guess), but not the corresponding (complex) model structure to manually do the bindings using 'ng-model'.

I am not very experienced with this, sorry.

Thanks.

Anthropic commented 8 years ago

@jazzmanro an add on can add as much to the model as it likes, so you could indeed create an add-on that adds complex objects or whatever you like to the model. You are limited only by Angular itself in what you can do, so you would need a ng-model reference for a parent object to act upon and then do what you like for the child elements. Is this what you are referring too?

jazzmanro commented 8 years ago

@Anthropic Imagine the following example: the schema and model is server-generated based on class definitions and object instances (using Java or C#). In my model I actually use several fields of type Address (let's say) that have a few usual properties:

{
  Name: "MyModel",
  Type: ...,
  Address1: {
    Street: ...
    Zip: ...
    City: ...
  },
  Address2: {
    Street: ...
    Zip: ...
    City: ...
  },
}

For those Address field(s) I want to create a custom editor that controls all nested model fields in a custom (connected) way, more than you can do with the form definition, but of course reuse as much as I can of the ASF functionality and schema validation and do it with a minimum of effort.

What is the best approach? What builders should I use? Because I am a bit lost with the builders and so when reading https://github.com/json-schema-form/angular-schema-form-add-ons/blob/master/documentation/extending.md

Based on what I saw here I managed to successfully build my HTML based on the Address (sub)-schema passed in the 'form' variable. But there doesn't seem to be a 'model' variable to bind 'model.Zip', 'model.City', etc. to my UI fields. 'sf-field-model' is not very clear to me. How can I get the corresponding Address model instance in my HTML?

Anthropic commented 8 years ago

@jazzmanro those fields would all needed to be handled by your Angular directive and you would then use your directive to write back to a single model value for the entire address if I understand you correctly.

I'm not sure what you can't do in a connected way though, you can always write a directive add-on that can do calculations and update any value you like, thereby continuing to use the standard form behaviours for the field display.

jazzmanro commented 8 years ago

@Anthropic sure, agree with you. But what I still cannot find/understand is how do I get access to the model (more precisely, sub-model) to use it or pass it further to my custom directive? I guess starting from bootstrap decorator and datepicker example isn't that good. Because what I did so far was, given above model structure, was to add a new form type:

...
{
  key: "Address1",
  type: "address"
},
...

Then, register it via config():

angular.module('schemaForm').config(
['schemaFormProvider', 'schemaFormDecoratorsProvider', 'sfPathProvider',
  function (schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) {

      var addressControl = function (name, schema, options) {
          var f = schemaFormProvider.stdFormObj(name, schema, options);
          f.key = options.path;
          f.type = 'address';
          options.lookup[sfPathProvider.stringify(options.path)] = f;
          return f;
      };

      schemaFormProvider.defaults.object.unshift(addressControl);

      //Add to the bootstrap directive
      schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'address',
      'app/js/schema-form-controls/address.html');
      schemaFormDecoratorsProvider.createDirective('address',
      'app/js/schema-form-controls/address.html');
  }]);

Then in the address.html I can use a form variable that provides me with the corresponding schema of Address1 property, but I cannot find a model variable that provides me the actual Address1 model contents. This is all I need. The model variable seems to be the entire model and this is not good as from inside address.html I can't know which of the addresses in the model I'm editing.

Please excuse me if those are really basic things but firstly I am quite new to Angular's world, secondly it is not clear to me how can I most easily create 'widget editors' for my complex types.

Anthropic commented 8 years ago

@jazzmanro the main way to look at it is to imagine that you are using ASF simply to put a bunch of templates into your page.

Develop as if you weren't using ASF and just put your template into the page, make it work with ng-model data and then once you have a component/directive making it behave the way you want then you can use it as a template and have ASF put it in place for you and pass the model ASF prepares in instead of getting it directly off the tag scope (like you would have to if you weren't using ASF).

Does that help at all perspective wise?

You add a component/controller by attaching to an attribute or element within your template. So to help further I'd need to see your template, but I suspect you may want to make sure you can get it working on its own first.

jazzmanro commented 8 years ago

@Anthropic thanks for all your help. What I needed was $$value$$ it seems but figured it out late from the documentation and samples. I had access to the form in HTML which is the definition tailored to the sub-structure that I was editing, I needed something similar for the model.

Anthropic commented 8 years ago

@jazzmanro awesome, love it when people come back and close their own issues, thank you for your time I appreciate it :)