Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

call function to get enum values #22

Closed
chachou29 opened this issue Jul 18, 2014 · 28 comments
Closed

call function to get enum values #22

chachou29 opened this issue Jul 18, 2014 · 28 comments

Comments

@chachou29
Copy link

Hello,
I would like to call external functions in schemas to get enum values.
Something like that :

$scope.schema = {
    type: "object",
    properties: {
      name: { type: "string", minLength: 2, title: "Name", description: "Name or alias" },
      title: {
        type: "string",
        enum: "getTitlesValues(...,...)"
      }
    }
  };

getTitlesValues = function(data, ...) {
    if(data.xxx == "YYY")
         return ["a", "b", ...]
}

OK, it's easy if you build the schema with javascript
In my case, schemas are stored in DB, and the return values from the external function could change ... if it depend of data entered by the user.
Any idea ?

edit : I said schema ? OK, same question, but the function would be defined in the form.

Thank you !
Philippe

@davidlgj
Copy link
Contributor

Hi,

I'm not sure I really understand what it is you're trying to do, what would the variable data in the getTitleValues function be?

@torstenrudolf
Copy link
Contributor

I think a feature like that would be indeed quite handy.

Maybe you write something like this in the json string:

{
    "type": "object",
    "properties": {
      "country": {
        "type": "string",
        "enumCallback": "getTitlesValues()"
      }
    }
}

And in your controller you would have that callback defined:

...
$scope.getTitlesValues = function () {
    return ['Australia', 'Germany', 'Sweden']
}
...

Would be also necessary to have a feature like this for the titleMap I guess.

@davidlgj
Copy link
Contributor

@torstenrudolf I'm not fond of adding it to the schema, even though the json schema spec allows for extra attributes it doesn't feel right to add them.

We could do it in the form definition, the titleMap I guess, but you can also just loop over the form definition and set the titleMap before the you pass along the form and schema to sf-schema. Would that solve your scenario?

@chachou29
Copy link
Author

I agree, we could do it in the form definition.
When i said :

getTitlesValues = function(data, ...) {
    if(data.xxx == "YYY")
         return ["a", "b", ...]
}

data is very important, because values returned by the callback to fill the enum array of a field could depend of values already set in other field. data is the form objet.
The most important is that the callback must be recalled each time the form changes.
Sorry if it's not clear, my english is awful.
Philippe

@torstenrudolf
Copy link
Contributor

@davidlgj I have a general question how you implement the schemas. Do you load them from a json file or do you write them directly in javascript?

I have them in json files but I'm wondering if it would be not easier to move them into services.
But then the javascript code gets bloated.

@davidlgj
Copy link
Contributor

@torstenrudolf we usually generate them on the backend and fetch them via a ajax call. The use case for us is that the form(s) and the schema is dependent on several settings the user can set in an admin interface. That is really the main reason we used to use JSONForm and why we created angular schema form; to build forms dynamically depending on user settings.

I don't really now your use case but keeping schemas in json files is often a good idea, at least when a project grows and you have several of them. What you could do is have a build step wrap them in angular.module('mymodule').constant('myschema',{ ... }); and load them as js files, much the same way we compile html templates to js files in this project. That way you can dependency inject them in the controllers, and you don't need to wait for $http to load them. Just a thought.

@chachou29
Copy link
Author

@davidlgj
same case, angular schema form is used to to build forms dynamically depending on user settings.
Schemas and forms are stored in DB in JSON and retrieved by a dedicated angular service that does AJAX call to backend. Really cool :-)

@stevehu
Copy link

stevehu commented Aug 20, 2014

@davidlgj,
It is a very important feature to have dynamic enum for a field depending on other field(s) value changes. It can be a javascript call or based on condition to choose different array as enum.

Thanks for the good work.

@davidlgj
Copy link
Contributor

Hi @stevehu,

Are we talking like: "If you select Sweden as a country in the first dropdown then the second select gets all cities in sweden"?

Is it worth it even if it has to be synchronous, or is proper async handling a must, i.e. do you need to make ajax calls?

@fiddur
Copy link

fiddur commented Aug 21, 2014

We have the similar, as in chosing country and the perhaps a state or county. There are several layers to this problem, when it comes to the form.

Using oneOf in the schema, we might have been able to produce a complete schema, but the object "address" would have had to be multiplied for all countries that have states. Therefore I can see the need for a callback of this kind.

But. There are other ways to handle this.

One method would be watching the resulting model (from the form data) (or specific sub-part of the model) and altering the schema and/or form when something changes. So, an angular watch $formScope.model.address.country and reacting to the value, changing $formScope.schema.

Another method would be to making a field type addon for "countryState" that looks at the country field at the same level and changes valid options or disappears depending on what country is chosen.

I think I would prefer the latter, more declarative variant, than having a callback.

@bizm
Copy link

bizm commented Sep 5, 2014

Hi guys. sorry for a stupid question. when i update enum in schema that doesn't update a select automatically, right? am i missing something here?

@davidlgj
Copy link
Contributor

davidlgj commented Sep 5, 2014

@bizm do you mean that you first render the form then change a property in the schema? No that will not work. Schema form doesn't do a deep watch of the schema. And even if it did, it would be quite complicated to update just parts of the form. Currently if the schema changed, i.e. the entire object is switched, the form re-renders.

The use case for this issue would probably best be fixed with a new sort of form definition type, i.e. and addon that only rerenders it's fields.

@marcusradell
Copy link

Sounds like a problem that is solved by ui-router. Depending on the state or substate; change the content.

@markbarton
Copy link

Hi - I would like to add to this as well.

We have a lot of use cases where the possible options for our select able fields would be populated via AJAX calls rather than being defined in the schema. So reading through the comments it looks like the consensus is the best option is to define a new type of field. Question is has anyone got an example handy with this type of additional field?

@mike-marcacci
Copy link
Contributor

Hi @markbarton, perhaps this is more suited for a custom decorator than a schema definition. I have a case where I use a typeahead/select for selecting users from the database (Github style); the schema enforces that the final value is a string of the UUID format, while my custom decorator (which uses a custom directive) is actually responsible for communicating with the server and showing the different options.

From a design perspective, I appreciate how this project allows extensibility while not trying to support every use case itself. @davidlgj perhaps there needs to be a more prominent reference to custom decorators in the docs?

@davidlgj
Copy link
Contributor

davidlgj commented Sep 9, 2014

@mike-marcacci I deliberately have left decorators out of the docs since we have the ugly inheritance bug #29 which makes them less useful, and just because they lack in documentation and I feel they need quite a bit of explaining. But recent issues have made it clear that we need docs on how to extend Schema Form with your own types and how to create decorators.

I've started writing on it here https://github.com/Textalk/angular-schema-form/blob/development/docs/extending.md and would love to get your feedback on it.

@markbarton, @chachou29, @torstenrudolf, @bizm, @marcusnielsen @stevehu We at Textalk are going to need a select field that is dynamically filled at some point this autumn (country -> state case), and I feel that the best solution for that specific case is a new kind of field type (see docs linked above) that does this, i.e. something like "dynamicselect". So that is going to happen, just not sure when.

@mike-marcacci
Copy link
Contributor

@davidlgj those docs are superb :) I didn't realize that you could set the schema defaults externally – this project is just incredibly well designed. Cheers!

Also, I'm glad to know I was using the term "decorator" too broadly! Using "field type" makes more sense in my previous comment.

@majj
Copy link

majj commented Sep 11, 2014

How about a select2 add-on?

@snawbel
Copy link

snawbel commented Oct 29, 2014

@markbarton Did you find an example of a select populated async?

@samcfc
Copy link

samcfc commented Jan 22, 2015

@markbarton thanks for you work, I am also very interested in an example of select populated async :)

@davidlgj
Copy link
Contributor

@samcfc @snawbel I found this add-ons searching bower: https://github.com/networknt/angular-schema-form-strapselect

I haven't tried it myself, so I don't now what it does really, but the description looks nice :-)

I'm closing this issue since the solution is to create a custom add-on.

@stevehu
Copy link

stevehu commented Jan 22, 2015

@davldlgj I did it and I have linked two videos to show how it looks and how to use it. Thanks for the great work!

https://www.youtube.com/watch?v=B-TjSF81uuU

https://www.youtube.com/watch?v=lz8fPcY_VJY

@markbarton
Copy link

@samcfc https://github.com/samcfc @snawbel https://github.com/snawbel
Sorry havent had a chance to implement yet.

@stevehu so your method is serverside?

Your intercepting the JSON schema and using Java to populate the values
within the Schema.

On 22 January 2015 at 11:53, stevehu notifications@github.com wrote:

@davldlgj I did it and I have linked two videos to show how it looks and
how to use it. Thanks for the great work!

https://www.youtube.com/watch?v=B-TjSF81uuU

https://www.youtube.com/watch?v=lz8fPcY_VJY


Reply to this email directly or view it on GitHub
#22 (comment)
.

http://www.markbarton.com

@Dervisevic
Copy link
Contributor

Awesome videos @stevehu

@markbarton
Copy link

@stevehu https://github.com/stevehu I should have watched the whole vide0
;-)

On 22 January 2015 at 12:16, Denis Dervisevic notifications@github.com
wrote:

Awesome videos @stevehu https://github.com/stevehu


Reply to this email directly or view it on GitHub
#22 (comment)
.

http://www.markbarton.com

@stevehu
Copy link

stevehu commented Jan 22, 2015

@markbarton I have two different ways to implement dynamic dropdowns:

Strapeselect is pure dynamic as the dropdown itself has controller and services and they are lazy loaded and registered. It gives you all the flexiblity you need.

Uiselect example is pre-processed on the server to populate the dropdown values and then the json will be send to angular. Majority of the user cases can be covered this way.

I serve schema form database and I have extended schema form to have a list of actions that map to rest apis.

Both strapeselect and uiselect were created by

https://github.com/chengz

And I just make it dynamic.

@stramel
Copy link
Contributor

stramel commented Jan 22, 2015

I feel like this issue may have gotten off track...

@nicklasb
Copy link
Member

nicklasb commented May 3, 2015

Hi, just wanted to mention that the fork of schema-form-strapselect I am working on as of 0.7.1, in addition to also being dynamic in a number of ways, now also supports "filters", the functionality mentioned above where the value of one field affects the contents of another:
https://github.com/OptimalBPM/angular-schema-form-dynamic-select

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests