Skip to content

Nested Form click scope? #403

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

Closed
plong0 opened this issue May 26, 2015 · 2 comments
Closed

Nested Form click scope? #403

plong0 opened this issue May 26, 2015 · 2 comments

Comments

@plong0
Copy link

plong0 commented May 26, 2015

Hello, I am working on implementing a nested sf-form (similar to #123)

I have created a custom decorator "child-form" with a simple template:
<div sf-schema="form.child.schema" sf-form="form.child.form" sf-model="$$value$$"></div>

In my FormController, I have:

$scope.model = {};

$scope.childSubmit = function(){
    console.log('Child Submit!');
};

var child = {
    schema: {
        "type": "object",
        "title": "Test Inline",
        "properties": {
            "name": {
                "title": "Name",
                "type": "string"
            }
        }
    },
    form: [
        "name",
        {
            "type": "button",
            "style": "btn-success",
            "title": "Child Submit",
            "onClick": "childSubmit()"
        }
    ]
};

$scope.schema = {
    "type": "object",
    "title": "Test Form",
    "properties": {
        "title": {
            "title": "Title",
            "type": "string",
            "required": true
        }
    }
};

$scope.form = [
    "title",
    {
        "key": "test",
        "type": "child-form",
        "child": {
            "form": child.form,
            "schema": child.schema
        }
    },
    {
        "type": "submit",
        "style": "btn-info",
        "title": "Submit"
    }
];

Everything is working, except the "onClick": "childSubmit()".
It works if I change it to "onClick": "$parent.$parent.$parent.childSubmit()".

Wondering why that is, and how I could overcome this?

@davidlgj
Copy link
Contributor

sf-schema uses an isolated scope so for onClick that are expressions to work we evaluate them in the parent scope of the sf-schema directive. You can see the start of it here:
https://github.com/Textalk/angular-schema-form/blob/development/src/services/decorators.js#L74 and here https://github.com/Textalk/angular-schema-form/blob/development/src/services/decorators.js#L88

Since you nest your sf-schema attributes that means that the onClick in the child is evaluated in the parent of the nested sf-schema, i.e. the isolated scope of the surrounding sf-schema! Which doesn't have the function.

There is workaround though. onClick option can also take the function directly instead of a string as an expression, which should work fine. See docs here https://github.com/Textalk/angular-schema-form/blob/development/docs/index.md#button-and-submit

The flip side of that is that your form isn't pure JSON anymore. Hope that answers your question.

@plong0
Copy link
Author

plong0 commented May 28, 2015

Thanks @davidlgj ... I though it was something with an isolate scope, but didn't realize which directive was making the isolate scope until after posting (and then I saw the class="ng-isolate-scope" sitting there ;)

I made a fix for it in the buttonClick function, which allows to add an "inheritFunc": true onto the button item in the form. When buttonClick fires and inheritFunc is set, it calls buttonClick in the $parent sf-schema's scope instead. (I wonder if there is a better way than scope.$parent.$parent.$parent to call though?)

            scope.buttonClick = function($event, form) {
              if (angular.isFunction(form.onClick)) {
                form.onClick($event, form);
              } else if (angular.isString(form.onClick)) {
                if (form.inheritFunc && angular.isFunction(scope.$parent.$parent.$parent.buttonClick)) {
                  scope.$parent.$parent.$parent.buttonClick($event, form);
                }
                else if (sfSchema) {
                  //evaluating in scope outside of sfSchemas isolated scope
                  sfSchema.evalInParentScope(form.onClick, {'$event': $event, form: form});
                } else {
                  scope.$eval(form.onClick, {'$event': $event, form: form});
                }
              }
            };

@plong0 plong0 closed this as completed May 28, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants