0

I have a nested gridview that has a footer row to insert data. When the parent row is expanded, the footer controls are created. There are 2 chosen dropdowns in which the 2nd dropdown is dependent on the 1st. When the value changes in the first dropdown, the 2nd dropdown is enabled and a list is created. The problem is that when I change the value in the first dropdown, the change() event is not triggered. I have edit functions that work fine in the endRequest function. But the Insert controls do not work.

This is the markup:

 <asp:UpdatePanel ID="updatePnlDeviceNestedGrid" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <div id="div<%# Eval("RecipientID") %>" style="display:none">
            <asp:GridView ID="RecipientDeviceGridView" runat="server" AutoGenerateColumns="false" CssClass="grid" ShowFooter="true" Caption="Device Information" 
                CaptionAlign="Top" AllowPaging="true" PageSize="3" HorizontalAlign="Left"
                 onpageindexchanging="RecipientDeviceGridView_PageIndexChanging" 
                 OnPageIndexChanged="RecipientDeviceGridView_PageIndexChanged" 
                 onrowcommand="RecipientDeviceGridView_RowCommand" 
                 onrowediting="RecipientDeviceGridView_RowEditing"
                 onrowupdating="RecipientDeviceGridView_RowUpdating"
                 OnRowCancelingEdit="RecipientDeviceGridView_RowCancelingEdit"
                 OnRowDeleting="RecipientDeviceGridView_RowDeleting"
                 OnRowDataBound="RecipientDeviceGridView_RowDataBound">
                <Columns>
                    <asp:TemplateField HeaderText="DeviceID">
                        <ItemTemplate>
                            <asp:Label ID="recdevgvLblDeviceID" runat="server" Text='<%# Bind("DeviceID") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Device"  ItemStyle-Wrap="false">
                        <ItemTemplate>
                            <asp:Label ID="recdevgvDeviceID" runat="server" Visible="false" Text='<%# Bind("DeviceID") %>'></asp:Label>
                            <asp:Label ID="recdevgvLblDeviceName" runat="server" Text='<%# Bind("DeviceName") %>'></asp:Label>
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:Label ID="recdevgvEditDeviceID" runat="server" Visible="false" Text='<%# Bind("DeviceID") %>'></asp:Label>
                            <asp:Label ID="recdevgvEditDeviceName" runat="server" Visible="false" Text='<%# Bind("DeviceName") %>'></asp:Label>
                            <asp:DropDownList ID="recdevgvDDListDeviceName" runat="server" ClientIDMode="Static" 
                                data-placeholder="Choose device…" class="chosen-single">
                            </asp:DropDownList>
                            <asp:RequiredFieldValidator ID="recdevReqValueDDLDeviceNameEdit" runat="server"  
                                    ControlToValidate="recdevgvDDListDeviceName" ValidationGroup="recdevEditDeviceValidation" 
                                    ErrorMessage="Selection required." CssClass="message-error-dropdown">
                            </asp:RequiredFieldValidator>
                        </EditItemTemplate>
                        <FooterTemplate> 
                            <asp:DropDownList ID="recdevgvDDListDeviceNameInsert" runat="server" ClientIDMode="Static"
                                data-placeholder="Choose device..." class="chosen-single">
                            </asp:DropDownList>
                            <asp:RequiredFieldValidator ID="recdevReqValueDDLDeviceNameInsert" runat="server" InitialValue="0" 
                                ControlToValidate="recdevgvDDListDeviceNameInsert" ValidationGroup="recdevInsertDeviceValidation" 
                                ErrorMessage="Selection required." CssClass="message-error-dropdown">
                            </asp:RequiredFieldValidator>
                        </FooterTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Service Provider">
                        <ItemTemplate>
                            <asp:Label ID="recdevgvLblServiceName" runat="server" Text='<%# Bind("ServiceName") %>'></asp:Label>
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:Label ID="recdevgvEditServiceName" runat="server" Visible="false" Text='<%# Bind("ServiceName") %>'></asp:Label>
                            <asp:DropDownList ID="recdevgvDDListServiceName" runat="server" ClientIDMode="Static" 
                                OnSelectedIndexChanged="RecipientDeviceGridView_SelectedIndexChanged_EditServiceName" AutoPostBack="true" EnableViewState="true"
                                 data-placeholder="Choose service…" class="chosen-single">
                            </asp:DropDownList>
                            <asp:RequiredFieldValidator ID="recdevReqValueDDLServiceNameEdit" runat="server" 
                                    ControlToValidate="recdevgvDDListServiceName" ValidationGroup="recdevEditDeviceValidation" 
                                    ErrorMessage="Selection required." CssClass="message-error-dropdown">
                            </asp:RequiredFieldValidator>
                        </EditItemTemplate>
                        <FooterTemplate>
                            <asp:DropDownList ID="recdevgvDDListServiceNameInsert" runat="server" ClientIDMode="Static" Enabled="false"
                                OnSelectedIndexChanged="RecipientDeviceGridView_SelectedIndexChanged_InsertServiceName" AutoPostBack="true" EnableViewState="true" 
                                data-placeholder="Choose service…" class="chosen-single">
                            </asp:DropDownList>
                            <asp:RequiredFieldValidator ID="recdevReqValueDDLServiceNameInsert" runat="server" InitialValue="0" 
                                    ControlToValidate="recdevgvDDListServiceNameInsert" ValidationGroup="recdevInsertDeviceValidation" 
                                    ErrorMessage="Selection required." CssClass="message-error-dropdown">
                            </asp:RequiredFieldValidator>
                        </FooterTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Address">
                        <ItemTemplate>
                            <asp:Label ID="recdevgvLblAddress" runat="server" Text='<%# Bind("Address") %>'></asp:Label>
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:TextBox ID="recdevgvTxtBoxAddress" runat="server" Text='<%# Bind("Address") %>' ClientIDMode="Static"></asp:TextBox>
                            <asp:Label ID="recdevgvEditAddressExt" runat="server" Visible="false" Text='<%# Bind("ServiceExtension") %>' 
                                    ClientIDMode="Static">
                            </asp:Label>
                            <asp:RequiredFieldValidator ID="recdevReqValueAddressEdit" runat="server" 
                                    ControlToValidate="recdevgvTxtBoxAddress" ValidationGroup="recdevEditDeviceValidation" 
                                    ErrorMessage="Required field." CssClass="message-error">
                            </asp:RequiredFieldValidator>
                            <asp:CustomValidator ID="recdevCustomValAddressEdit" runat="server" ControlToValidate="recdevgvTxtBoxAddress" CssClass="message-error" 
                                ErrorMessage="*" ClientValidationFunction="ValidateAddressEdit" EnableClientScript="true" 
                                ValidationGroup="recdevEditDeviceValidation">
                            </asp:CustomValidator>
                        </EditItemTemplate>
                        <FooterTemplate>
                            <asp:TextBox ID="recdevgvTxtBoxAddressInsert" runat="server" ClientIDMode="Static"></asp:TextBox>
                            <asp:Label ID="recdevgvAddressExtInsert" runat="server" Visible="false" ClientIDMode="Static"></asp:Label>
                            <asp:RequiredFieldValidator ID="recdevReqValueAddressInsert" runat="server" 
        ControlToValidate="recdevgvTxtBoxAddressInsert" ValidationGroup="recdevInsertDeviceValidation" 
        ErrorMessage="Required field." CssClass="message-error">
</asp:RequiredFieldValidator>
                            <asp:CustomValidator ID="recdevCustomValAddressInsert" runat="server" ControlToValidate="recdevgvTxtBoxAddressInsert" CssClass="message-error" 
    ErrorMessage="*" ClientValidationFunction="ValidateAddressInsert" EnableClientScript="true" 
    ValidationGroup="recdevInsertDeviceValidation">
</asp:CustomValidator>
                        </FooterTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Active">
                        <ItemTemplate>
                            <asp:Label ID="recdevgvLblActive" runat="server" Text='<%# (Boolean.Parse(Eval("Active").ToString())) ? "Yes" : "No" %>'></asp:Label>
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:DropDownList ID="recdevgvDDListActive" runat="server" class="no-chosen"
                                Text='<%# (Boolean.Parse(Eval("Active").ToString())) ? "Yes" : "No" %>'>
                                <asp:ListItem>Yes</asp:ListItem>
                                <asp:ListItem>No</asp:ListItem>
                            </asp:DropDownList>
                        </EditItemTemplate>
                        <FooterTemplate>
                            <asp:DropDownList ID="recdevgvDDListActiveInsert" runat="server" class="no-chosen">
                                <asp:ListItem Selected="True">Yes</asp:ListItem>
                                <asp:ListItem>No</asp:ListItem>
                            </asp:DropDownList>
                        </FooterTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Cortext Enabled">
                        <ItemTemplate>
                            <asp:Label ID="recdevgvLblCortextEnabled" runat="server" Text='<%# (Boolean.Parse(Eval("CortextEnabled").ToString())) ? "Yes" : "No" %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Action" ShowHeader="False" ItemStyle-Wrap="false" ItemStyle-HorizontalAlign="Center">
                        <ItemTemplate>
                            <asp:Button ID="recdevgvEditButton" runat="server" CausesValidation="True" CommandName="Edit" 
            Text="Edit" CssClass="gridActionbutton" ValidationGroup="EditDeviceValidation"></asp:Button>
&nbsp;<asp:Button ID="recdevgvDeleteButton" runat="server" CausesValidation="False" CommandName="Delete" 
            Text="Delete" CssClass="gridActionbutton"  OnClientClick="return confirm('Are you sure you want to delete this Device Information?')" >
                            </asp:Button>
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:Button ID="recdevgvUpdateButton" runat="server" CausesValidation="True" ValidationGroup="recdevEditDeviceValidation" CommandName="Update" 
                Text="Update" CssClass="gridActionbutton"></asp:Button>
&nbsp;<asp:Button ID="recdevgvCancelButton" runat="server" CausesValidation="False" CommandName="Cancel" 
                Text="Cancel" CssClass="gridActionbutton"></asp:Button>
                        </EditItemTemplate>
                        <FooterTemplate>
                            <asp:Button ID="recdevgvAddButton" runat="server" CommandName="Add" Text="Add Device" CausesValidation="true" 
            CssClass="gridActionbutton" ValidationGroup="recdevInsertDeviceValidation"></asp:Button>
                        </FooterTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
    </ContentTemplate>
</asp:UpdatePanel>

This is the code-behind that creates the dropdowns in the footer row:

 protected void RecipientInfoGridView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        try
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                int tiRecipientID = Convert.ToInt32(RecipientInfoGridView.DataKeys[e.Row.RowIndex].Value.ToString());
                GridView tgvDeviceGrid = (GridView)e.Row.FindControl("RecipientDeviceGridView");
                populateDeviceGrid(tgvDeviceGrid, tiRecipientID);

                // Get the Footer controls that have the new entry data
                Control tFooterControls = CommonMethods.getFooterControls(tgvDeviceGrid);

                DropDownList tddlDeviceNames = tFooterControls.FindControl("recdevgvDDListDeviceNameInsert") as DropDownList;
                m_strXmlTableData = m_pagingClient.GetDeviceTypes();
                DataTable tdtDeviceTypes = CommonMethods.ParseXML(m_strXmlTableData);
                tddlDeviceNames.DataSource = tdtDeviceTypes;
                tddlDeviceNames.DataTextField = tdtDeviceTypes.Columns["DeviceName"].ToString();
                tddlDeviceNames.DataValueField = tdtDeviceTypes.Columns["DeviceTypeID"].ToString();
                tddlDeviceNames.DataBind();
                tddlDeviceNames.Items.Insert(0, new ListItem("", "0"));

                DropDownList tddlServiceNames = tFooterControls.FindControl("recdevgvDDListServiceNameInsert") as DropDownList;
                m_strXmlTableData = m_pagingClient.GetServiceTypes();
                DataTable tdtServiceTypes = CommonMethods.ParseXML(m_strXmlTableData);
                tddlServiceNames.DataSource = tdtServiceTypes;
                tddlServiceNames.DataTextField = tdtServiceTypes.Columns["ServiceName"].ToString();
                tddlServiceNames.DataValueField = tdtServiceTypes.Columns["CombineID_Group"].ToString();
                tddlServiceNames.DataBind();
                tddlServiceNames.Items.Insert(0, new ListItem("", "0"));
            }

        }
        catch (Exception ex)
        {
            //TO DO: Response.Redirect("~/Error.aspx");
        }
    }

This is the javascript:

 //This change function is when the Device grid is in Insert Mode
        $("#recdevgvDDListDeviceNameInsert").change(function () {
            alert('Ready Fn - Insert: Device name DDL change fn');
            $("#recdevgvDDListServiceNameInsert").prop("disabled", false);
            $("#recdevgvDDListServiceNameInsert").val('');
            $("#recdevgvDDListServiceNameInsert").chosen({
                search_contains: true,
                no_results_text: "Sorry, no match!"
            });

            var DeviceSelValue = $(this).val();
            $("#recdevgvDDListServiceNameInsert").children("option").hide();
            $("#recdevgvDDListServiceNameInsert").trigger("chosen:updated");

            switch (DeviceSelValue) {
                case "1":
                    $("#recdevgvDDListServiceNameInsert option[value*='cell']").show();
                    $("#recdevgvDDListServiceNameInsert").trigger("chosen:updated");
                    $("#recdevgvAddressExtInsert").hide();
                    break;
                case "2":
                    $("#recdevgvDDListServiceNameInsert option[value*='email']").show();
                    $("#recdevgvDDListServiceNameInsert").trigger("chosen:updated");
                    $("#recdevgvAddressExtInsert").hide();
                    break;
                case "3":
                    $("#recdevgvDDListServiceNameInsert option[value*='page']").show();
                    $("#recdevgvDDListServiceNameInsert").trigger("chosen:updated");
                    $("#recdevgvAddressExtInsert").hide();
                    break;
                default:
                    break;
            }
        });

UPDATE Thanks Aleksey for the suggestion. My change function is now triggered. But the changes to the ServiceName dropdown are not occurring. I use this function call on this page when the nested grid is in Edit mode. When I change the value of the Device Name dropdown, the Service Name dropdown is not enabled and the value 'Choose service' is not displayed. It is as if the selector, #recdevgvDDListServiceNameInsert is not recognized. The control has the attribute ClientIDMode="Static".

The control is within an update panel updatePmlDeviceNestedGrid and Gridview, RecipientDeviceGridView. I tried adding the update panel control as the parent in the selector but that did not work. I use a document.ready() and for the Edit mode to work I use endRequest function.

I tried the bindEvent function but get the same results.

This is my javascript:

$(document).ready(function () {
    // alert("ready function");
    //Configure the DropDownBox using the 'chosen' jquery plugin
    $(".chosen-single").chosen({
        search_contains: true,
        width: "200px",
        no_results_text: "Sorry, no match!"
    });
});

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest);

function onEndRequest(sender, args) {
    if (sender._postBackSettings.panelsToUpdate != null) {
        $("select:not(.chosen-select, .no-chosen)").chosen({
            search_contains: true,
            width: "200px",
            no_results_text: "Sorry, no match!"
        });
    };
//more code to activate the dropdowns in Edit Mode...
};
//This change function is when the Device grid is in Insert Mode
 $(document).on("change", "#recdevgvDDListDeviceNameInsert", function () {
     alert('Ready Fn - Insert: Device name DDL change fn');
      $("#recdevgvDDListServiceNameInsert").prop("disabled", false);
      $("#recdevgvDDListServiceNameInsert").val('');
      $("#recdevgvDDListServiceNameInsert").chosen({
          search_contains: true,
          no_results_text: "Sorry, no match!"
      });

     var DeviceSelValue = $(this).val();
     $("#recdevgvDDListServiceNameInsert").children("option").hide();
     $("#recdevgvDDListServiceNameInsert").trigger("chosen:updated");

     switch (DeviceSelValue) {
         case "1":
             $("#recdevgvDDListServiceNameInsert option[value*='cell']").show();
             $("#recdevgvDDListServiceNameInsert").trigger("chosen:updated");
             $("#recdevgvAddressExtInsert").hide();
             break;
         case "2":
             $("#recdevgvDDListServiceNameInsert option[value*='email']").show();
             $("#recdevgvDDListServiceNameInsert").trigger("chosen:updated");
             $("#recdevgvAddressExtInsert").hide();
             break;
         case "3":
             $("#recdevgvDDListServiceNameInsert option[value*='page']").show();
             $("#recdevgvDDListServiceNameInsert").trigger("chosen:updated");
             $("#recdevgvAddressExtInsert").hide();
             break;
         default:
             break;
     }
 });

UPDATE I had that problem when in Edit Mode... I added this to the change function and the dropdown is at least showing the option Choose service....

function bindEvents() {
   $(document).on("change", "#recdevgvDDListDeviceNameInsert", function () {
        $("select:not(.chosen-select, .no-chosen)").chosen({
             search_contains: true,
              width: "200px",
             no_results_text: "Sorry, no match!"
          });
});

However, the dropdown is still not enabled...

UPDATE In order to enable the disabled chosen dropdown, I could not use the ID value but this: $("select").prop("disabled", false); Once it was enabled, the rest of the function worked.

Gloria Santin
  • 2,066
  • 3
  • 51
  • 124

1 Answers1

0

I'm assuming that your updatePnlDeviceNestedGrid present on the page on initial page call, so let's add ClientIDMode="Static" to your updatePanel to make our js more readable

 <asp:UpdatePanel ID="updatePnlDeviceNestedGrid" runat="server" UpdateMode="Conditional" ClientIDMode="Static">

not to reattach event each partial postback, you should make your change event attach function definition like below, we place it inside jQuery document ready to be sure updatePnlDeviceNestedGrid is in the DOM

$(function () {
    $('#updatePnlDeviceNestedGrid').on('change', '#recdevgvDDListDeviceNameInsert', function() {
        alert('Ready Fn - Insert: Device name DDL change fn');
        // ans so on .....
    });
})

not to make additional changes you can also attach it directly to document

 $(document).on('change', '#recdevgvDDListDeviceNameInsert'

here is jQuery docs reference http://api.jquery.com/on/

"Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready."

UPDATE

from the other hand you can rebind it each partial postback, like shown in this answer jQuery $(document).ready and UpdatePanels?

forexample you will create function to bind events

function bindEvents(){
   $("#recdevgvDDListDeviceNameInsert").change(function () {
       // your code......
   }

   //some other bindings
}

// initial page load
$(function () {
   bindEvents();
})

var prm = Sys.WebForms.PageRequestManager.getInstance();

prm.add_endRequest(function() {
   // re-bind your jQuery events here after updatepanel update
    bindEvents(); 
});
Community
  • 1
  • 1
makison
  • 373
  • 2
  • 10
  • Thank you for the code and the explanation. It is becoming more clear! The change event is now called. However, all of the function calls within the change event that have to do with the control `recdevgvDDListServiceNameInsert` are not working. The control is not enabled, etc. – Gloria Santin Nov 17 '15 at 14:56
  • as far you don't want to change all your evend bindings ))), see my update – makison Nov 17 '15 at 15:35
  • I added my pertinent javascript code above. I did review the UpdatePanel answer. That helped me previously to get the Edit mode to work. I think my problem has to do with the selector for the dropdown that is not changing **within** the change event. But I am not sure... – Gloria Santin Nov 17 '15 at 15:52
  • never mind removed comment, looks issue in other place – makison Nov 17 '15 at 16:10
  • sorry had to go, can't catch yet from your code what's wrong, in firebug forexample you can easily inspect elements, or run js code in the right pane of console tab, also you can use console,log() in your js code to see what happened – makison Nov 17 '15 at 16:23
  • I got it to work by using this function call to enable the chosen dropdown: ` $("select").prop("disabled", false);` Thanks for your help. – Gloria Santin Nov 17 '15 at 20:09