[CLOSED] Two dynamic panels...

  1. #1

    [CLOSED] Two dynamic panels...

    I have two dynamic panels on my page, one is an edit panel that loads when clicking on a row in the grid, the other is an add window that pops up when clicking add on the grid.

    A funny thing happens...when something is loaded into the edit grid, then you click add, the edit grid disappears. No errors...it's like its trying to add a blank model.

    Both panels use the same view, model, and controller. The only difference is that the action is called with a UserID set or null.

    The edit panel is called via (item click on gridpanel):
                    .DirectEvents(de =>
                    {
                        de.ItemClick.EventMask.ShowMask = true;
                        de.ItemClick.EventMask.Msg = "Loading...";
                        de.ItemClick.Method = HttpMethod.GET;
                        de.ItemClick.EventMask.MinDelay = 500;
                        de.ItemClick.Url = Url.Action("GetUser", "Maintenance");
                        de.ItemClick.ExtraParams.Add(new Parameter("containerId", "App.EditUserPanel.down('panel').id", ParameterMode.Raw));
                        de.ItemClick.ExtraParams.Add(new Parameter("UserID", "record.get('UserID')", ParameterMode.Raw));
                    })
    The add button:
    Html.X().Button()
                                    .Text("Add")
                                    .Icon(Icon.Add)
                                    .Dock(Dock.Right)
                                    .DirectEvents(de =>
                                    {
                                        de.Click.Before = "App.UsersWindow.show(this);";
                                        de.Click.Method = HttpMethod.GET;
                                        de.Click.EventMask.ShowMask = false;
                                        de.Click.EventMask.Msg = "Loading...";
                                        de.Click.EventMask.MinDelay = 500;
                                        de.Click.Url = Url.Action("GetUser", "Maintenance");
                                        de.Click.ExtraParams.Add(new Parameter("containerId", "App.UsersWindow.down('panel').id", ParameterMode.Raw));
                                        de.Click.ExtraParams.Add(new Parameter("UserID", "null", ParameterMode.Raw));
                                    })
    Controller:
            [NoCache]
            [HttpGet]
            public ActionResult GetUser(string containerId, Guid? UserID)
            {
                CSCAttendance.Models.MaintenanceModel.User user = base.EditUser(UserID); 
    
                var result = new Ext.Net.MVC.PartialViewResult()
                {
                    ViewName = "EditUser",
                    ContainerId = containerId,
                    WrapByScriptTag = false,
                    Model = user,
                    RenderMode = Ext.Net.RenderMode.Replace
                };
    
                return result;
            }
    I attached the images to see what the result is.

    Click image for larger version. 

Name:	2.PNG 
Views:	32 
Size:	11.3 KB 
ID:	6330Click image for larger version. 

Name:	1.PNG 
Views:	33 
Size:	11.7 KB 
ID:	6331
    Last edited by Daniil; Jun 10, 2013 at 3:19 PM. Reason: [CLOSED]
  2. #2
    Hi @AmitM,

    I think a Panel is rendered with the same ID in both the scenarios and it destroys the previous one.

    Please post the partial view. Is there ID for the Panel?
  3. #3

    I checked ID

    I checked the ID in the controller when the request comes in. Because the dynamic panel replaces the panel specified in containerId, I name the parent panel and use .down('panel').id to get whatever the name of the panel is that was returned dynamically:

    Html.X().Panel()
                    .Border(false)
                    .ID("EditUserPanel")
                    .Padding(5)
                    .Flex(1)
                    .Split(true)
                    .Layout(LayoutType.Fit)
                    .Title("Edit User")
                    .Items(
                        Html.X().Panel()
                            .ID("EditUserPanelSub")
                            .Border(false)
                            .Html("Please select a user to edit")
                    )
    @(
        Html.X().Window()
            .Title("Add User")
            .ID("UsersWindow")
            .Height(400)
            .Width(400)
            .Modal(true)
            .Hidden(true)
            .Items(
                Html.X().Panel()
                    .Border(false)
                    .ID("AddUserPanel")
                    .Html("Please select a user to edit")
            )
    )
    The directEvents list the containerId in the parameters by finding the parent.down('panel').id:
    de.ItemClick.ExtraParams.Add(new Parameter("containerId", "App.EditUserPanel.down('panel').id", ParameterMode.Raw));
    and

    de.Click.ExtraParams.Add(new Parameter("containerId", "App.UsersWindow.down('panel').id", ParameterMode.Raw));
    The controller does show the correct name coming in the request. I did observe that subsequent requests the containerId was 'form-xxxx', which I believe is just a dynamically generated name. However both dynamic panels did have different Ids.

    The view for the dynamic panel does not specify an Id so that a random one will be assigned to it:

    Html.X().FormPanel()
            .BodyPadding(5)
            .Border(false)
            .Layout(LayoutType.Form)
            .Items( 
                 ...
            )
            .Buttons(
                Html.X().Button()
                    .Text("Save")
                    .Icon(Icon.DatabaseSave)
                    .Type(ButtonType.Submit)
                    .DirectEvents(de =>
                    {
                        de.Click.Url = Url.Action("SaveUser", "Maintenance");
                        de.Click.Before = "return this.up('form').isValid();";
                        de.Click.Method = HttpMethod.POST;
                        de.Click.EventMask.ShowMask = true;
                        //de.Click.Failure = "Ext.Msg.notify('Error', result.errorMessage);";
                        de.Click.Success = "Ext.Msg.notify('Saved.', 'Saved changes!');";
                        de.Click.EventMask.Msg = "Saving...";
                        de.Click.EventMask.MinDelay = 500;
                    })
                )
    )

    Should I explicitly set the Id of the dynamic form when it is sent back to the client? I tried:
    var result = new Ext.Net.MVC.PartialViewResult()
                {
                    ViewName = "EditUser",
                    ContainerId = containerId,
                    WrapByScriptTag = false,
                    Model = user,
                    RenderMode = Ext.Net.RenderMode.Replace,
                    ControlId = containerId     // <== Tried this!
                };
    
                return result;
    but the id was still 'form-xxxx'

    -Amit
  4. #4

    Did more testing....

    I confirmed that both panels do exist. When clicking the grid, the PartialView renders into the container and the Id becomes 'form-1152'.

    When clicking add, the new panel becomes 'form-1157' and the old panel still exists, although it did not have and textboxes or drop downs. It only had the Save button.

    Could it be that the model in the other panel is becoming invalid? That should not be the case since I have worked w/ MVC4 with multiple divs on the same page with @Html.RenderPartial(...).

    Perhaps I should load the panel via an ajax call instead of DirectEvent?
  5. #5
    Quote Originally Posted by AmitM View Post
    Perhaps I should load the panel via an ajax call instead of DirectEvent?
    Well, a DirectEvent is an AJAX request itself.

    According to the details you are describing, I think you have explicit IDs for the fields inside the FormPanel's Items (within the partial view).

    If so, they are rendered with the same client ids all the time. It causes "replacing". You can use ItemIDs instead of IDs.
  6. #6

    That makes sense

    However, I am not explicitly naming the controls. I am using TextFieldFor...:

    .Items(
                Html.X().HiddenFor(m => m.UserID),
                Html.X().TextFieldFor(m => m.UserName)
                    .FieldLabel("User Name")
                    .ReadOnly(Model.UserID != null),
                Html.X().TextFieldFor(m => m.Email),
                Html.X().TextFieldFor(m => m.Password)
                    .FieldLabel("Password")
                    .InputType(Ext.Net.InputType.Password)
                    .AllowBlank(Model.UserID != null)
                    .MinLength(6),
                Html.X().TextFieldFor(m => m.FirstName)
                    .FieldLabel("First Name")
                    .AllowBlank(Model.UserID != null),
                Html.X().TextFieldFor(m => m.LastName)
                    .FieldLabel("Last Name")
                    .AllowBlank(Model.UserID != null),
                Html.X().ComboBoxFor(m => m.SchoolID)
                    .FieldLabel("School")
                    .ValueField("SchoolID")
                    .DisplayField("SchoolName")
                    .Store(Html.X().Store()
                        .Model(Html.X().Model()
                            .Fields(
                                new ModelField("SchoolID"),
                                new ModelField("SchoolName")
                            ).IDProperty("SchoolID")
                        )
                    .DataSource(Model.Schools)
                ),
                Html.X().ComboBoxFor(m => m.ProviderID)
                    .FieldLabel("Provider")
                    .ValueField("ProviderID")
                    .DisplayField("ProviderName")
                    .Store(Html.X().Store()
                    .Model(Html.X().Model()
                        .Fields(
                            new ModelField("ProviderID"),
                            new ModelField("ProviderName")
                        ).IDProperty("ProviderID")
                    )
                    .DataSource(Model.Providers)
                ),
                Html.X().ComboBoxFor(m => m.Role)
                    .FieldLabel("Role")
                    .Items(Model.Roles.ToArray())
            )
    How would I change the items so that they do not overwrite each other?

    Thanks,
    Amit
  7. #7
    Yes, "...For" helpers take a Model property's name as an ID by default. Please pass false as the second parameter.
    Html.X().TextFieldFor(m => m.UserName, false)
    By the way, we are trying to come up with a solution to provide a global setting for it.
  8. #8

    That works!

    It's always the simple things...
  9. #9
    Quote Originally Posted by Daniil View Post
    By the way, we are trying to come up with a solution to provide a global setting for it.
    Created an Issue for that.
    https://github.com/extnet/Ext.NET/issues/271

Similar Threads

  1. TabPanel with dynamic Panels
    By alpeter in forum 1.x Help
    Replies: 0
    Last Post: Feb 01, 2013, 2:11 PM
  2. Replies: 3
    Last Post: Jan 04, 2012, 9:14 AM
  3. Bug with dynamic panels and slider control
    By decho in forum 1.x Help
    Replies: 7
    Last Post: Sep 09, 2011, 8:13 AM
  4. Bug with dynamic Add/Remove of panels
    By decho in forum 1.x Help
    Replies: 7
    Last Post: Aug 10, 2011, 10:16 AM
  5. Issues with dynamic IDs and tab panels
    By mindcore1 in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Dec 21, 2008, 4:41 PM

Tags for this Thread

Posting Permissions