Serenity: How to pass data from Master Dialog to Details Memory Grid Dialog?

Created on 24 Jun 2016  路  12Comments  路  Source: serenity-is/Serenity

Hi

I want to use BranchId from MasterDialog to Memory Grid Dialog. How can i pass this??
I want to set BranchId from master as default in memory grid dialog so i need this in LoadEntity event.
If memory grids has some rows then i can get it from there, but how to do it for first record?
Please help.

Here is the screen shot for the scenario
datapasstomemorydialog

Most helpful comment

I did this in this manner.

In XYZDetailsEditor.ts added a public variable and set it in afterLoadEntity of master dialog.

    export class XYZDetailsEditor extends Common.GridEditorBase<XYZDetailRow> {
        protected getColumnsKey() { return "Test.XYZDetail"; }
        protected getDialogType() { return XYZDetailDialog; }
        protected getLocalTextPrefix() { return XYZDetailRow.localTextPrefix; }

        public myPassValue: number;

        [...]

in master dialog.ts

      @Serenity.Decorators.registerClass()
       export class MasterDialog extends Serenity.EntityDialog<MasterRow, any> {

       protected afterLoadEntity() {
            super.afterLoadEntity();

            this.form.DetailList.myPassValue = this.entity.valueToPass;
        }

then, in details dialog overried getButtons(). In onclick event of new button I set the value

        protected getButtons(): Serenity.ToolButton[] {
            var buttons = super.getButtons();
            buttons[0].onClick = () => {
                this.createEntityDialog(this.getItemType(), dlg => {
                    var dialog = dlg as XYZDetailDialog;
                    dialog.onSave = (opt, callback) => this.save(opt, callback);
                    var entity = this.getNewEntity() as XYZDetailRow;

                    entity.myPassValue = this.valueToPass;

                    dialog.loadEntityAndOpenDialog(entity);
                });
            }

            return buttons;
        }

All 12 comments

Can you provide the code for the classes that you're using for Master/Detail?

The code is normal which is use to create memory grid dialog as per documentation. My code is in C# using saltarelle (Not in type script)
Here is the brief of the code.
AdvanceRow Calss (Main Dialog) this calss has many fields so showing only relvent field.

 public sealed class AdvanceRow : LoggingRow, IIdRow, INameRow
    {
        [DisplayName("Id"), Identity, QuickSearch]
        public Int32? Id
        {
            get { return Fields.Id[this]; }
            set { Fields.Id[this] = value; }
        }

        [DisplayName("Branch"), NotNull]
        [ForeignKey("[dbo].[Common_Branch]", "Id"), LeftJoin("jBranch"), TextualField("BranchName")]
        [LookupEditor(typeof(BranchRow))]
        public Int32? BranchId
        {
            get { return Fields.BranchId[this]; }
            set { Fields.BranchId[this] = value; }
        }
        [DisplayName("Voucher"), MasterDetailRelation(foreignKey: "AdvanceId", CheckChangesOnUpdate = false), ClientSide]
        public List<AdvanceVoucherRow> AdvanceVoucher
        {
            get { return Fields.AdvanceVoucher[this]; }
            set { Fields.AdvanceVoucher[this] = value; }
        }
}

Class for AdvanceVoucherRow (Memory Grid Dialog)

public sealed class AdvanceVoucherRow : Row, IIdRow, INameRow
    {
        [DisplayName("Id"), Identity]
        public Int32? Id
        {
            get { return Fields.Id[this]; }
            set { Fields.Id[this] = value; }
        }

        [DisplayName("Advance"), NotNull, ForeignKey("[dbo].[Tranzol_Advance]", "Id"), LeftJoin("jAdvance"), TextualField("AdvanceRemarks")]
        public Int32? AdvanceId
        {
            get { return Fields.AdvanceId[this]; }
            set { Fields.AdvanceId[this] = value; }
        }

        [DisplayName("Date"), NotNull, DefaultValue("today")]
        public DateTime? PaymentDate
        {
            get { return Fields.PaymentDate[this]; }
            set { Fields.PaymentDate[this] = value; }
        }

        [DisplayName("Payment Ledger"), NotNull, ForeignKey("[dbo].[Accounts_Ledgers]", "Id"), LeftJoin("jPaymentLedger"), TextualField("PaymentLedgerLedgerName")]
        [LookupEditor(typeof(LedgersRow))]
        public Int32? PaymentLedgerId
        {
            get { return Fields.PaymentLedgerId[this]; }
            set { Fields.PaymentLedgerId[this] = value; }
        }

        [DisplayName("Branch Ledger"), NotNull, ForeignKey("[dbo].[Accounts_Ledgers]", "Id"), LeftJoin("jBranchLedger"), TextualField("BranchLedgerLedgerName")]
        [LookupEditor(typeof(LedgersRow))]
        public Int32? BranchLedgerId
        {
            get { return Fields.BranchLedgerId[this]; }
            set { Fields.BranchLedgerId[this] = value; }
        }
}

Here is my dialog class where i am trying to filter Branch Ledgers in memory dialog based on selected branch in parent dialog.

public class AdvanceVoucherDialog : GridEditorDialog<AdvanceVoucherRow>
    {
        protected AdvanceVoucherForm form;
        public int AdvanceBranchId;
        public AdvanceVoucherDialog()
        {
            form = new AdvanceVoucherForm(this.IdPrefix);
        }

        protected override void LoadEntity(AdvanceVoucherRow entity)
        {
            base.LoadEntity(entity);
            if (AdvanceBranchId > 0)
            {
                Q.ServiceCall(new ServiceCallOptions
                {
                    Url = Q.ResolveUrl("~/ServiceController/Branch/GetBranchLedgers"),
                    Request = new BranchLedgerRequest { BranchId = AdvanceBranchId, IncludeCashLedger = true },
                    Async = true,
                    OnSuccess = response =>
                    {
                        var ledgersList = ((BranchLedgerResponse)response).Ledgers;
                        var branchLedgers = form.BranchLedgerId.Items.Where(t => ledgersList.Contains(t.Id.ToInt32().Value)).ToList();
                        form.BranchLedgerId.Items.RemoveRange(0, form.BranchLedgerId.Items.Count);
                        form.BranchLedgerId.Items.AddRange(branchLedgers);
                    }
                });
            }
        }
    }

Please help and let me know if any other information is required?
Thanks!

I can post full source code if you need.

Please help me on this.

Ok, For now i have done it by creating a js variable.
Here is my code.
Added a Js element with the value having of Branch in master dialog

protected override void LoadEntity(AdvanceRow entity)
        {
            base.LoadEntity(entity);
            J("<div id='tempBranchId' style='display:none'>" + form.BranchId.Value + "</div>").AppendTo(form.BranchId.Element.Closest(".field"));
            //Q.Alert(form.BranchId.Element.OuterHtml());
        }

And access this element in child dialog and get branch id.

protected override void LoadEntity(AdvanceVoucherRow entity)
        {
            base.LoadEntity(entity);
            var tempBranch = J("#tempBranchId").GetText();
            if (!tempBranch.IsEmptyOrNull())
            {
                var tempAdvanceBranchId = J("#tempBranchId").GetText().ToInt32();
                if (tempAdvanceBranchId.HasValue)
                {
                    Q.ServiceCall(new ServiceCallOptions
                    {
                        Url = Q.ResolveUrl("~/ServiceController/Branch/GetBranchLedgers"),
                        Request = new BranchLedgerRequest { BranchId = tempAdvanceBranchId.Value, IncludeCashLedger = true },
                        Async = true,
                        OnSuccess = response =>
                        {
                            var ledgersList = ((BranchLedgerResponse)response).Ledgers;
                            var branchLedgers = form.BranchLedgerId.Items.Where(t => ledgersList.Contains(t.Id.ToInt32().Value)).ToList();
                            form.BranchLedgerId.Items.RemoveRange(0, form.BranchLedgerId.Items.Count);
                            form.BranchLedgerId.Items.AddRange(branchLedgers);
                        }
                    });
                }
            }
        }

There should be better solution for this but for now it worked for me.

I did this in this manner.

In XYZDetailsEditor.ts added a public variable and set it in afterLoadEntity of master dialog.

    export class XYZDetailsEditor extends Common.GridEditorBase<XYZDetailRow> {
        protected getColumnsKey() { return "Test.XYZDetail"; }
        protected getDialogType() { return XYZDetailDialog; }
        protected getLocalTextPrefix() { return XYZDetailRow.localTextPrefix; }

        public myPassValue: number;

        [...]

in master dialog.ts

      @Serenity.Decorators.registerClass()
       export class MasterDialog extends Serenity.EntityDialog<MasterRow, any> {

       protected afterLoadEntity() {
            super.afterLoadEntity();

            this.form.DetailList.myPassValue = this.entity.valueToPass;
        }

then, in details dialog overried getButtons(). In onclick event of new button I set the value

        protected getButtons(): Serenity.ToolButton[] {
            var buttons = super.getButtons();
            buttons[0].onClick = () => {
                this.createEntityDialog(this.getItemType(), dlg => {
                    var dialog = dlg as XYZDetailDialog;
                    dialog.onSave = (opt, callback) => this.save(opt, callback);
                    var entity = this.getNewEntity() as XYZDetailRow;

                    entity.myPassValue = this.valueToPass;

                    dialog.loadEntityAndOpenDialog(entity);
                });
            }

            return buttons;
        }

Thanks @Estrusco
This is helpful and don't know why i could not do it by creating a simple global variable. :-) :-)
Instead of overriding onclick event, i have used InitEntityDialog and set the value in this event -

 protected override void InitEntityDialog(string itemType, Widget dialog)
        {
            base.InitEntityDialog(itemType, dialog);
            ((AdvanceVoucherDialog)dialog).AdvanceBranchId = gAdvanceBranchId; //Set here 
        }

Thanks again for you input.

I couldnt read all but isnt there a sample for this under basic samples. Flow should be master dialog to grid editor to detail dialog.

@ramveersgh
Please tell me where to write this code

 protected override void InitEntityDialog(string itemType, Widget dialog)
        {
            base.InitEntityDialog(itemType, dialog);
            ((AdvanceVoucherDialog)dialog).AdvanceBranchId = gAdvanceBranchId; //Set here 
        }

@ramveersgh I think in you Editor dialog

@Estrusco
Sorry but im not getting intellisense for below "createEntitytype"
protected getButtons(): Serenity.ToolButton[] {
var buttons = super.getButtons();
buttons[0].onClick = () => {
this.createEntityDialog(this.getItemType(), dlg => { //property does not exits on type xyz dialog
var dialog = dlg as XYZDetailDialog;
dialog.onSave = (opt, callback) => this.save(opt, callback);
var entity = this.getNewEntity() as XYZDetailRow;

                entity.myPassValue = this.valueToPass;

                dialog.loadEntityAndOpenDialog(entity);
            });
        }

        return buttons;
    }

I couldnt read all but isnt there a sample for this under basic samples. Flow should be master dialog to grid editor to detail dialog.

Hello @volkanceylan
I want to send quantity numeric(18,2) from detail dialog to master dialog.
Please tell me what should I do

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chintankukadiya18 picture chintankukadiya18  路  3Comments

ahsansolution picture ahsansolution  路  3Comments

Shraddha996 picture Shraddha996  路  3Comments

Pinellus picture Pinellus  路  3Comments

Akarsh03 picture Akarsh03  路  3Comments