serenity-is / Serenity

Business Apps Made Simple with Asp.Net Core MVC / TypeScript
https://serenity.is
MIT License
2.57k stars 795 forks source link

How to access form fields from an editor? #1509

Closed awesomegithubusername closed 7 years ago

awesomegithubusername commented 7 years ago

Hello everyone;

Following up on this issue, I'd like to set some of the form fields values when the lookup value changes. So how do I access the form from the CustomSelect2AjaxEditor? I know that you can do that from the Dialog, but it would be neat if you could change those values directly from the editor (formatSelection) so that you call the retrieve method only once (from a remote endpoint) :


public getSelect2Options() {
            var selec2Options = super.getSelect2Options();

            selec2Options.formatResult = this.testFormatResult;
            selec2Options.formatSelection = this.testFormatSelection;   //<-----------

            return selec2Options;
        }

        protected testFormatResult(item: Serenity.Select2Item) {
            var itemSource: YourXYZRow = item.source; //just for intelissense... only the fields available with the columns included in query
            var markup = '<div class="row-fluid">' +             
                '<div class="span6">' + item.text + '</div>' +
                '<div class="span3"><i class="fa fa-code-fork"></i> ' + item.text + '</div>' +
                '<div class="span3"><i class="fa fa-star"></i> ' + item.id + '</div>' +
                '<div class="span3"><i class="fa fa-star"></i> ' + itemSource.NameIncludedColumnField+        '</div>' +
                '</div>';

            return markup;
        }

        protected testFormatSelection(item: Serenity.Select2Item) {

          var itemSource: YourXYZRow = item.source; 

         //Define form ???

       //use the form fields

           form.MyLookupField.change(e => {

                form.FieldA.value = itemSource.value1;
                form.FieldB.value = itemSource.value2; 

            });

            return  itemSource.value3;
        }

It works with hard-coded elements:

$(document.body).on("change", "#MultiTenancy_WYZDialog42_LookuField", function () {

               $("input[name='fieldA']").val(itemSource.value1);
               $("input[name='fieldB]").val(itemSource.value2);

            });

But, as you know, the lookup field Id is generated randomly.

edson commented 7 years ago

Hi, @awesomegithubusername .

I guess by doing this, you would be hurting some SR principles...

But you could create a reference in your editor to form...

 export class YourEditor extends Serenity.Select2AjaxEditor...... {

        public myForm: YourXYZForm;

And then put it in your dialog constructor.... this.form.YourEditorField.myForm = this.form;

So you can access that in editor

var form = this.myForm;
form.MyLookupField.change(e => {

                form.FieldA.value = itemSource.value1;
                form.FieldB.value = itemSource.value2; 

            });

Or You could do directly without the form reference with finding the field with Q in your editor Something like:

var fieldAEditor = Q.findElementWithRelativeId(this.element, "FieldA").tryGetWidget(Serenity.WhateverEditorOfField);

But, anyway... You could get the value and extra data (those from itemsource) when selected when you're in dialog and do this once.... Just add a method to return that in editor.

Best Regards

awesomegithubusername commented 7 years ago

Thanks @edson. Hadn't got the time to test it yet. I'll get back to you once I do. Regarding the third option, can you give more details about accessing the editor method you suggested to add from the dialog?

edson commented 7 years ago

Hi, @awesomegithubusername .

I have added one method which relies back on (this.element as any).select2('data') in editor to return the information from selected value, including source, but I have to take a look at code to see if there's a more direct approach...

that would be something like:

public getData() {

            let data = (this.element as any).select2('data');
            return data;
        }

And then you can access data.source with those extra fields...

Actually, you don't really need a method in editor... When there's a change event in editor, the item is passed through the event.

Something like this could be done in dialog

this.form.MyLookupField.changeSelect2(e => {

           if(e.added != null) {
              var itemSource = e.added.source;

                this.form.FieldA.value = itemSource.fieldIncludedName1;
                this.form.FieldB.value = itemSource.fieldIncludedName2; 

            });
});

Keep in mind that the item.source is not passed when the editor is created and loaded from an already existing entity at the first time... Nor e.added or select2('data') works when the dialog loads an already existing entity for the first time. But it works whenever user selects from then on... Would have to dig in select2ajax code to understand what is happening or check select2 documentation... As I needed it to get the extra value fields passed to load a partialview in form when it is just opened...

Hope it helped...

Best Regards

awesomegithubusername commented 7 years ago

Thank you so much @edson! I ended up using your last suggestion (e.added) and It's exactly what I was looking for. It's even better than handling the changes in the editor which would hurt its reusability.

I appreciate your patience. Have a good day (or night ;) ).

Shraddha996 commented 5 years ago

hey @awesomegithubusername Actually, am having quite a similar issue, I want to access other modules form.cs fields from a different editor Like, I have 1 module which is NetworkModule consist of ValueTran and NetworkTran so Now from ValueTranEditor.ts, I want to access NetworkForm.cs fields

I already wasted 1,2 days in R&D Please suggest something