1
votes

I know this has been asked numerous times, but after spending the best part of the day reading SO and other sites I am still unable to resolve my issue. I have tried playing about with Viewstate, !IsPostback, Page_Load and Page_Init all to no avail.

I have a repeater that returns a list of records and for each record it also displays two asp buttons. These buttons display an Ajax modalpopupextender. What is not happening is the Repeater ItemCommand is not being called so I cannot show the correct information in the text boxes.

I have placed the Ajax modalpopupextender is this correct? If not what do I need to do to get it to work.

Repeater Control

<div class="container">
<h2>Current Groups</h2>
<asp:Repeater ID="rptGroups" runat="server" OnItemCommand="rptGroups_ItemCommand" EnableViewState="false">
    <HeaderTemplate>
        <table class="table table-striped table-bordered">
            <tr>
                <td>GroupID</td>
                <td>Group Name</td>
                <td>Group Description</td>
                <td></td>
            </tr>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td>
                <%# DataBinder.Eval(Container.DataItem,"GroupID") %>
            </td>
            <td>
                <%# DataBinder.Eval(Container.DataItem,"GroupName") %>
            </td>
            <td>
                <%# DataBinder.Eval(Container.DataItem,"GroupDescription") %>
            </td>
            <td>
                <asp:Button ID="btnEdit" runat="server" CssClass="btn btn-default" Text="Edit" CommandName="Edit" CommandArgument='<%#Eval("GroupID") %>' OnClick="btnEdit_Click" OnClientClick="return false" UseSubmitBehavior="false"  />
                <asp:Button ID="btnDelete" runat="server" CssClass="btn btn-danger" Text="Delete" CommandName="Delete" CommandArgument='<%#Eval("GroupID") %>' OnClick="btnDelete_Click" OnClientClick="return false" UseSubmitBehavior="false" />
                <ajaxToolkit:ModalPopupExtender ID="mpeEdit" runat="server" PopupControlID="pnlEdit" TargetControlID="btnEdit"  
                    CancelControlID="btnCloseEdit" BackgroundCssClass="modalBackground"></ajaxToolkit:ModalPopupExtender>
                <ajaxToolkit:ModalPopupExtender ID="mpeDelete" runat="server" PopupControlID="pnlDelete" TargetControlID="btnDelete"
                    CancelControlID="btnCloseDelete" BackgroundCssClass="modalBackground"></ajaxToolkit:ModalPopupExtender>

            </td>
        </tr>
    </ItemTemplate>
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>

Code for popup

        <asp:Panel ID="pnlDelete" runat="server" CssClass="modalPopup" align="center" Style="display: none">
    <div style="height: 60px">
        <asp:UpdatePanel ID="upnlDelete" runat="server">
            <ContentTemplate>
                <h4>Do you wish to delete this Group?</h4>
                <asp:Label ID="lblDeleteGroupName" runat="server" ></asp:Label>
                <asp:Label ID="lblDeleteGroupDesc" runat="server" ></asp:Label>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
    <asp:Button ID="btnCloseDelete" runat="server" Text="Close" />
    </asp:Panel>

Code for ItemCommand

        protected void rptGroups_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
        if (e.CommandName == "Edit")
        {

        }
        else if (e.CommandName == "Delete")
        {
            lblDeleteGroupName.Text = Convert.ToString(e.CommandArgument);
            lblDeleteGroupDesc.Text = Convert.ToString(e.CommandArgument);

        }
    }

Thanks in advance

-- EDIT --

When I remove the ajaxToolkit:ModalPopupExtender from the repeater apart from the panel displaying on the page all the time, the postback works so I am thinking it has something to do with this, but I dont know where else I could place it

1
My answer was all wrong :P I'll post something for you tomorrow as it's quite long - Hugo Yates
Thanks Hugo I look forward to it and giving it a try - David Cleeton

1 Answers

0
votes

I find the Ajax ToolKit a bit of a pain and stopped using it (where possible) a while back.

Part of the problem is btnEdit and btnDelete are solely set up for handling the displaying of the modal, there is no point having the OnClick, CommandName and CommandArgument in there. They won't trigger any form of PostBack:

<asp:Button ID="btnEdit" runat="server" CssClass="btn btn-default" Text="Edit" OnClientClick="return false" UseSubmitBehavior="false"  />
<asp:Button ID="btnDelete" runat="server" CssClass="btn btn-danger" Text="Delete" OnClientClick="return false" UseSubmitBehavior="false" />
<ajaxToolkit:ModalPopupExtender ID="mpeEdit" runat="server" PopupControlID="pnlEdit" TargetControlID="btnEdit"  
                CancelControlID="btnCloseEdit" BackgroundCssClass="modalBackground"></ajaxToolkit:ModalPopupExtender>
<ajaxToolkit:ModalPopupExtender ID="mpeDelete" runat="server" PopupControlID="pnlDelete" TargetControlID="btnDelete"
                CancelControlID="btnCloseDelete" BackgroundCssClass="modalBackground"></ajaxToolkit:ModalPopupExtender>

However you want to pass some variables to these Modals for them to display, two options here, you either do it via a PostBack process or you set up something via JavaScript. Neither of which tie in very nicely with what you're looking to achieve with the code you've posted.

I Have two options for you (however both ditch the ajaxToolkit:ModalPopupExtender):

Option One (Basic)
You could achieve the same result with:

<asp:Button ID="btnEdit" runat="server" CssClass="btn btn-default" Text="Edit" OnCommand="rptGroups_ItemCommand" CommandName="Edit" CommandArgument='<%#Eval("GroupID") %>' OnClientClick="return confirm('Do you wish to Edit this?')"  />
<asp:Button ID="btnDelete" runat="server" CssClass="btn btn-default" Text="Delete" OnCommand="rptGroups_ItemCommand" CommandName="Delete" CommandArgument='<%#Eval("GroupID") %>' OnClientClick="return confirm('Do you wish to Delete this?')"  />

Not as fancy but as soon as the user clicks on the OK button of the popup it'll PostBack. You could try to get fancy and pass in the variables into the pop-up however this gets messy real fast and any single or double-quotes will have to be taken into account, it'd be best to steer clear.

Option Two
To achieve a similar result with the Bootstrap components you already have, this will need some refinement but the nice thing is it's very expandable and can be customised anyway you wish:

<asp:Repeater ID="DataRepeater" runat="server">
    <ItemTemplate>
        <br />
        <br />
        <%# Eval("GroupID") %><br />
        <%# Eval("GroupName") %><br />
        <%# Eval("GroupDescription") %><br />
        <asp:Button ID="btnEdit" runat="server" CssClass="btn btn-default" Text="Edit" OnCommand="DataRepeater_ItemCommand" CommandName="Edit" ValidateRequestMode="Enabled" CommandArgument='<%#Eval("GroupID") +"|"+ Eval("GroupName") +"|"+ Eval("GroupDescription") %>' />
        <asp:Button ID="btnDelete" runat="server" CssClass="btn btn-default" Text="Delete" OnCommand="DataRepeater_ItemCommand" CommandName="Delete" CommandArgument='<%#Eval("GroupID") +"|"+ Eval("GroupName") +"|"+ Eval("GroupDescription") %>' />
    </ItemTemplate>
</asp:Repeater>

<asp:Panel ID="EditPanel" runat="server" class="modal fade" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-body">
                <div class="row">
                    <div class="col-md-12">
                        <h1 style="color: #ff0000;"><i class="glyphicon glyphicon-cog"></i>&nbsp;Edit:</h1>
                        <asp:HiddenField ID="IdOfItemToEditHiddenField" runat="server" />
                        Name: <asp:TextBox ID="NameTextBox" runat="server" />
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-12">
                        <asp:Button ID="btnSaveEdit" runat="server" Text="Save" OnClick="btnSaveEdit_Click" OnClientClick="HideEditModal();" CssClass="btn btn-success" />
                        <asp:Button ID="btnCancelEdit" runat="server" Text="Cancel" OnClientClick="HideEditModal(); return false;" CssClass="btn btn-primary" />
                    </div>
                </div>

            </div>
        </div>
    </div>
</asp:Panel>

<asp:Panel ID="DeletePanel" runat="server" class="modal fade" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-body">
                <div class="row">
                    <div class="col-md-12">
                        <h1 style="color: #ff0000;"><i class="glyphicon glyphicon-warning-sign"></i>&nbsp;Delete?</h1>
                        <asp:HiddenField ID="IdOfItemToDeleteHiddenField" runat="server" />
                        <asp:Label ID="DeleteMessageLabel" runat="server" />
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-12">
                        <asp:Button ID="btnDelete" runat="server" Text="Delete" OnClick="btnDelete_Click" OnClientClick="HideDeleteModal();" CssClass="btn btn-success" />
                        <asp:Button ID="btnCancelDelete" runat="server" Text="Cancel" OnClientClick="HideDeleteModal(); return false;" CssClass="btn btn-primary" />
                    </div>
                </div>

            </div>
        </div>
    </div>
</asp:Panel>

<script type="text/javascript">
    function DisplayEditModal() {
        $('#<%=EditPanel.ClientID%>').modal('show');
    }
    function HideEditModal() {
        $('#<%=EditPanel.ClientID%>').modal('hide');
    }

    function DisplayDeleteModal() {
        $('#<%=DeletePanel.ClientID%>').modal('show');
    }
    function HideDeleteModal() {
        $('#<%=DeletePanel.ClientID%>').modal('hide');
    }
</script>

Code behind:

private Control _parentControl;
protected void Page_Load(object sender, EventArgs e)
{
    _parentControl = this; //if using an UpdatePanel use the ID of that instead of 'this'
    DataForRepeater();
}

private void DataForRepeater()
{
    //just example data to load the repeater
    var dt = new DataTable();
    dt.Columns.Add("GroupID", typeof(int));
    dt.Columns.Add("GroupName", typeof(string));
    dt.Columns.Add("GroupDescription", typeof(string));

    for (int i = 1; i <= 10; i++)
    {
        var nr = dt.NewRow();
        nr["GroupID"] = i;
        nr["GroupName"] = "SomeName" + i.ToString();
        nr["GroupDescription"] = "Description of " + i.ToString() + " item";
        dt.Rows.Add(nr);
    }
    DataRepeater.DataSource = dt;
    DataRepeater.DataBind();
}

protected void DataRepeater_ItemCommand(object sender, CommandEventArgs e)
{
    string command = e.CommandName;
    string[] arguments = e.CommandArgument.ToString().Split('|');

    switch (command)
    {
        case ("Edit"):
            //edit operation
            IdOfItemToEditHiddenField.Value = arguments[0];
            NameTextBox.Text = arguments[1];
            ScriptManager.RegisterStartupScript(_parentControl, _parentControl.GetType(), "Modal", " DisplayEditModal()", true);
            break;
        case ("Delete"):
            //delete operation
            IdOfItemToDeleteHiddenField.Value = arguments[0];
            DeleteMessageLabel.Text = arguments[1] + "<br/>" + arguments[2];
            ScriptManager.RegisterStartupScript(_parentControl, _parentControl.GetType(), "Modal", " DisplayDeleteModal()", true);
            break;
        default:
            throw new InvalidOperationException();
    }
}

protected void btnSaveEdit_Click(object sender, EventArgs e)
{
    int idToSave = int.Parse(IdOfItemToEditHiddenField.Value);
    string newName = NameTextBox.Text;

    //do something to save it
    ScriptManager.RegisterStartupScript(_parentControl, _parentControl.GetType(), "Msg", string.Format("alert('Save item {0}: {1}');", idToSave, newName), true);
}


protected void btnDelete_Click(object sender, EventArgs e)
{
    int idToDelete = int.Parse(IdOfItemToDeleteHiddenField.Value);

    //do something to delete it
    ScriptManager.RegisterStartupScript(_parentControl, _parentControl.GetType(), "Msg", string.Format("alert('Delete item {0}');", idToDelete), true);
}

That's the basics of it, like I said it'd definitly need improvement especially on passing the strings around, you'll have to be careful of quotation marks.