Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How can I Sort AND Edit on the same page? 1

Status
Not open for further replies.

roleki

Technical User
Sep 5, 2007
22
0
0
US
I have a report in the form of a DataGrid. The users want to be able to Sort the DataGrid AND be able to add a Comment to records when necessary.

The problem I am running into is, once the user inputs text to the editable field and clicks Update, the page refreshes to the pre-Update state, i.e. the Comment field is still a TextBox, but the user input is gone, and the TextBox reverts to whatever text it presented when Edit was clicked.

I think I am running into ViewState here, but I can't disable(?) ViewState because I need it to sort columns.

Any ideas what I should do next?

BTW, when the user clicks Update, it DOES create a Comment Record, but it sets the Comment column to '' (the value in the comment field after the textbox is refreshed.)

If it helps any, here is the _Update code:

----------------
protected void dgShipping_Update(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
try
{
if (SqlMethods.doesCommentRecordExist(e.Item.Cells[0].Text) == false)
{
int insertRecord = doInsert(e.Item.Cells[0].Text, ((System.Web.UI.WebControls.TextBox)e.Item.Cells[15].Controls[0]).Text);


if (insertRecord != 1)
{
lblError.Text = "Error creating record " + e.Item.Cells[0].Text + ".";
}
else
{
dgShipping.DataBind();
dgShipping.EditItemIndex = -1;
}
}
else
{
int updateRecord = doUpdate(e.Item.Cells[0].Text, ((System.Web.UI.WebControls.TextBox)e.Item.Cells[15].Controls[0]).Text);

if (updateRecord != 1)
{
lblError.Text = "Error updating record " + e.Item.Cells[0].Text + ".";
}
else
{
dgShipping.DataBind();
dgShipping.EditItemIndex = -1;
}
}
}
catch (Exception err)
{
lblError.Text = err.Message;
}
}

protected int doUpdate(string RecordID, string CommentText)
{
return SqlMethods.updateExistingComment(RecordID, CommentText);
}

protected int doInsert(string RecordID, string CommentText)
{
return SqlMethods.addNewComment(RecordID, CommentText);
}
 
You will need to provide the complete code for the page. Also, please use [ignore]
Code:
[/ignore] blocks when posting code as it makes it easier to read.


-------------------------------------------------------

Mark,
[URL unfurl="true"]http://aspnetlibrary.com[/url]
[URL unfurl="true"]http://mdssolutions.co.uk[/url] - Delivering professional ASP.NET solutions
[URL unfurl="true"]http://weblogs.asp.net/marksmith[/url]
 
Aye, sorry about not using code tags.

The codebehind:

Code:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Configuration;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Collections.Specialized;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

namespace MShipperTest
{
    /// <summary>
    /// Summary description for _Default.
    /// </summary>
    public partial class _Default : System.Web.UI.Page
    {
        /*
        protected System.Web.UI.WebControls.Label lblMessage;
        protected System.Web.UI.WebControls.Label lblTitle;
        protected System.Web.UI.WebControls.Label lblSubTitle;
        protected System.Web.UI.WebControls.DataGrid dgShipping;
        protected System.Data.DataView dataView;
        protected System.Web.UI.WebControls.Label lblError;
         */

        protected System.Data.DataView dataView;
        

        //needed to pull urlParams out to be accessible to the dgShipping_Update function
        NameValueCollection urlParams;
        
        
        private void Page_Load(object sender, System.EventArgs e)
        {
            DateTime dateFrom;
            DateTime dateTo;
            string refreshTime;
            try
            {
                // Load NameValueCollection object.
                urlParams = Request.QueryString;
                if (urlParams.Count < 4)
                {
                    lblError.Text = "No Dates Specified!";
                    Response.Redirect("/MShipperTest/DateFilter.aspx");
                    return;
                }

                dateFrom = (urlParams["DateFrom"] == "SysTime") ? DateTime.Now : Convert.ToDateTime(urlParams["DateFrom"]);
                dateTo = (urlParams["DateTo"] == "SysTime") ? DateTime.Now : Convert.ToDateTime(urlParams["DateTo"]);
                refreshTime = urlParams["AutoRefresh"];

                if (refreshTime != "0") Response.AppendHeader("Refresh", refreshTime);

                AppGlobals.buildConnectionStrings();
                //lblError.Text = SqlQueryStrings.getShippingInfo(DateFrom, DateTo, "");

                string otherFilters = AppGlobals.getReportFilter()[urlParams["ReportName"]];
                dataView = SqlMethods.getM2MDataSet("ShipInfo", SqlQueryStrings.getShippingInfo(dateFrom, dateTo, otherFilters)).Tables["ShipInfo"].DefaultView;
                if (dataView.Count > 0)
                {
                    lblTitle.Text = urlParams["ReportName"];
                    lblSubTitle.Text = (dateFrom == dateTo) ? "For " + dateTo.ToLongDateString() :
                        "For " + dateFrom.ToLongDateString() + " to " + dateTo.ToLongDateString();
                    lblRecordCount.Text = "(" + dataView.Count.ToString() + " orders left to ship.)";
                    if (dateFrom == Convert.ToDateTime("01/01/1900"))
                    {
                        lblSubTitle.Text = "All Items To Be Shipped Including Past Due Items";
                    }
                    dgShipping.DataSource = dataView;
                    dgShipping.DataBind();
                }
                else
                {
                    dgShipping.Visible = false;
                    lblMessage.Text = (dateFrom == dateTo) ? "All items for " + dateTo.ToLongDateString() + " have shipped, Good Job!" :
                        "All items from " + dateFrom.ToLongDateString() + " to " + dateTo.ToLongDateString() + " have shipped, Good Job!";
                }
                if (!IsPostBack)
                {
                    ViewState["LastSortOrder"] = "ASC";
                    ViewState["LastSortColumn"] = "ReleaseDate";
                    ViewState["LastFilter"] = "";
                    dataView.Sort = "ReleaseDate" + " ASC";
                    dgShipping.DataBind();
                }
                else
                // This code executes only on post back
                {
                    string lastSortColumn = (string)ViewState["LastSortColumn"];
                    string lastSortOrder = (string)ViewState["LastSortOrder"];
                    string lastFilter = (string)ViewState["LastFilter"];
                    dataView.Sort = lastSortColumn + " " + lastSortOrder;
                    dataView.RowFilter = lastFilter;
                }
            }
            catch (Exception err)
            {
                this.lblError.Text = err.Message;
            }
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.dataView = new System.Data.DataView();
            ((System.ComponentModel.ISupportInitialize)(this.dataView)).BeginInit();
            this.dgShipping.SortCommand += new System.Web.UI.WebControls.DataGridSortCommandEventHandler(this.dgShipping_SortCommand);
            this.Load += new System.EventHandler(this.Page_Load);
            ((System.ComponentModel.ISupportInitialize)(this.dataView)).EndInit();

        }
        #endregion

        private void dgShipping_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
        {
            string newSortColumn = e.SortExpression.ToString();
            string newSortOrder = "ASC"; // default
            string lastSortColumn = (string)ViewState["LastSortColumn"];
            string lastSortOrder = (string)ViewState["LastSortOrder"];
            if (newSortColumn.Equals(lastSortColumn) && lastSortOrder.Equals("ASC"))
            {
                newSortOrder = "DESC";
            } // else {newSortOrder="ASC";}
            ViewState["LastSortOrder"] = newSortOrder;
            ViewState["LastSortColumn"] = newSortColumn;
            dataView.Sort = newSortColumn + " " + newSortOrder;
            dgShipping.DataBind();
        }

        protected void dgShipping_Edit(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
        {
            dgShipping.EditItemIndex = (int)e.Item.ItemIndex;
            lblTitle.Text = "Editing record number: " + e.Item.Cells[0].Text;
            //lblTitle.Text = "Editing record number: " + e.Item.ItemIndex.ToString();
            dgShipping.DataBind();
        }

        protected void dgShipping_Cancel(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
        {
            dgShipping.EditItemIndex = -1;
            dgShipping.DataBind();
        }

        protected void dgShipping_Update(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
        {            
            try
            {
                if (SqlMethods.doesCommentRecordExist(e.Item.Cells[0].Text) == false)
                {
                    int insertRecord = doInsert(e.Item.Cells[0].Text, ((System.Web.UI.WebControls.TextBox)e.Item.Cells[15].Controls[0]).Text);
                    
                          
                    if (insertRecord != 1)
                    {
                        lblError.Text = "Error creating record " + e.Item.Cells[0].Text + ".";
                    }
                    else
                    {                     
                        dgShipping.DataBind();
                        dgShipping.EditItemIndex = -1;
                    }                   
                }
                else
                {
                    int updateRecord = doUpdate(e.Item.Cells[0].Text, ((System.Web.UI.WebControls.TextBox)e.Item.Cells[15].Controls[0]).Text);                   

                    if (updateRecord != 1)
                    {
                        lblError.Text = "Error updating record " + e.Item.Cells[0].Text + ".";
                    }
                    else
                    {
                        dgShipping.DataBind();
                        dgShipping.EditItemIndex = -1;
                    }
                }
            }
            catch (Exception err)
            {
                lblError.Text = err.Message;
            }
        }

        protected int doUpdate(string RecordID, string CommentText)
        {
            return SqlMethods.updateExistingComment(RecordID, CommentText);
        }

        protected int doInsert(string RecordID, string CommentText)
        {
            return SqlMethods.addNewComment(RecordID, CommentText);
        }
    }
}

Then the code for the actual page:

Code:
<%@ Page language="c#" CodeFile="Default.aspx.cs" AutoEventWireup="false" Inherits="MShipperTest._Default" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
	<HEAD>
		<title>Shipping Report</title>
		<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
		<meta content="C#" name="CODE_LANGUAGE">
		<meta content="JavaScript" name="vs_defaultClientScript">
		<meta content="[URL unfurl="true"]http://schemas.microsoft.com/intellisense/ie5"[/URL] name="vs_targetSchema">
		<LINK href="Styles.css" type="text/css" rel="stylesheet">
	</HEAD>
	<body>
		<form id="Form1" method="post" runat="server">
			<TABLE id="Table2" cellSpacing="1" cellPadding="1" width="100%" border="0">
			        <TR>
						<TD>
							<P align="center">
								<asp:label id="lblDEBUG" runat="server" Height="20px" Width="95%" Font-Size="Large" ForeColor="RoyalBlue"
									Font-Bold="True"></asp:label></P>
						</TD>
					</TR>
					<TR>
						<TD>
							<P align="center">
								<asp:label id="lblTitle" runat="server" Height="4px" Width="95%" Font-Size="X-Small" ForeColor="RoyalBlue"
									Font-Bold="True"></asp:label></P>
						</TD>
					</TR>
					<TR>
						<TD>
							<P align="center">
								<asp:label id="lblSubTitle" runat="server" Height="4px" Width="95%" Font-Size="X-Small" ForeColor="RoyalBlue"></asp:label>
							</P>
						</TD>
					</TR>
					<tr>
					    <td>
					        <p align="center">
					            <asp:label ID="lblRecordCount" runat="server" Height="4px" Width="95%" Font-Size="X-Small" ForeColor="RoyalBlue"></asp:label>
					        </p>
					    </td>
					</tr>
				</TABLE>
				<br>
				<asp:datagrid id="dgShipping" runat="server" Font-Size="XX-Small" Width="100%" Height="96px" AllowSorting="True"
					CellPadding="3" BackColor="White" BorderWidth="1px" BorderStyle="None" BorderColor="Black"
					AutoGenerateColumns="False" OnEditCommand="dgShipping_Edit" OnCancelCommand="dgShipping_Cancel" OnUpdateCommand="dgShipping_Update">
					<FooterStyle ForeColor="Black" BackColor="#CCCCCC"></FooterStyle>
					<SelectedItemStyle Font-Bold="True" ForeColor="White" BackColor="#008A8C"></SelectedItemStyle>
					<AlternatingItemStyle BackColor="Gainsboro"></AlternatingItemStyle>
					<ItemStyle BorderWidth="1px" ForeColor="Black" BorderStyle="Solid" BorderColor="Black" BackColor="#EEEEEE"></ItemStyle>
					<HeaderStyle Font-Bold="True" ForeColor="White" BorderStyle="Solid" BackColor="#000084"></HeaderStyle>					
					<Columns>
					    <asp:BoundColumn DataField="RecordID" SortExpression="RecordID" HeaderText="RecordID" ReadOnly="true" Visible="false"></asp:BoundColumn>
					    <asp:BoundColumn DataField="fcompany" SortExpression="fcompany" HeaderText="Customer" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="ReleaseDate" SortExpression="ReleaseDate" HeaderText="Due Date" DataFormatString="{0:MM-dd-yy}" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="fpartno" SortExpression="fpartno" HeaderText="Part Number" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="QtyOrdered" SortExpression="QtyOrdered" HeaderText="Qty Ordered" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="BOQty" SortExpression="BOQty" HeaderText="BO Qty" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="QtyMade" SortExpression="QtyMade" HeaderText="Qty Made" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="jobOrder" SortExpression="jobOrder" HeaderText="Job Order" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="fsource" SortExpression="fsource" HeaderText="S" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="QtyFromStock" SortExpression="QtyFromStock" HeaderText="From Stock" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="QtyOnHand" SortExpression="QtyOnHand" HeaderText="On Hand" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="Shortage" SortExpression="Shortage" HeaderText="Short" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="fsono" SortExpression="fsono" HeaderText="SO Number" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="ffob" SortExpression="ffob" HeaderText="FOB" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="Shipvia" SortExpression="Shipvia" HeaderText="Ship Via" ReadOnly="True"></asp:BoundColumn>
						<asp:BoundColumn DataField="ShipComments" SortExpression="ShipComments" HeaderText="Comments" ReadOnly="False"></asp:BoundColumn>
						<asp:EditCommandColumn EditText="Edit" CancelText="Cancel" UpdateText="Update" HeaderText="Edit Comment"></asp:EditCommandColumn>
					</Columns>
					<PagerStyle HorizontalAlign="Center" ForeColor="Black" BackColor="#999999" Mode="NumericPages"></PagerStyle>
				</asp:datagrid>
				<asp:label id="lblError" runat="server" Height="4px" Width="568px" ForeColor="Red"></asp:label>
				<TABLE id="Table1" style="HEIGHT: 269px" cellSpacing="1" cellPadding="1" width="95%" align="center"
					border="0">
					<TR>
						<TD align="center">
							<asp:label id="lblMessage" runat="server" Height="13px" Width="85%" Font-Size="XX-Large" ForeColor="RoyalBlue"
								Font-Bold="True"></asp:label></TD>
					</TR>
				</TABLE>			
		</form>
	</body>
</HTML>
 
on first glance, i think you need to swap your databind and edititemindex...

dgShipping_Update
...
dgShipping.EditItemIndex = -1;
dgShipping.DataBind();
dgShipping.EditItemIndex = -1;

 
on second glance, you have quite alot of actions going on during Page_Load.

you are loading your DataView and calling dgShipping.DataBind() many times.

so when you update with...

dgShipping.EditItemIndex = -1;
dgShipping.DataBind();

it then processes the dataview from the Page_Load event again and calls dgShipping.DataBind(); again?


 
Actually, switching the order of EditItemIndex-1 & .DataBind() did eliminate a secondary problem of leaving the re-rendered page in Edit state with a Cancel button that generated an Invalid postback/callback error, so yay for that :)

As far as Page_Load goes...

(Please bear with me, I inherited the guts of this from my predecessor, who has long since moved on to greener pastures.)

The .DataBind() in Page_Load *should* only get called on initial load if all report parameters are present AND the DataView has records. Unless I am mistaken, subsequent .DataBind()s are triggered by the EventHandlers that contain them (_Sort, _Edit/_Update/_Cancel, etc).

Maybe I need to develop a better understanding of when Page_Load() gets called, I had thought it was only on the initial response to the request from the Parameters page? Is Page_Load() actually called whenever the page refreshes/is sorted, etc? That could be a problem.

 
Yes, page load gets fired for EVERY postback. If you click a button for example, the PageLoad fires BEFORE the button click event. There are good articles on line that show the page lifecycle of an asp.net page.
 
Hm, would it be possible to break out of the Page_Load .DataBind() on IsPostBack so that the .DataBind() from the given _EventHandler's is the one that takes hold?

Would I want to? Or, more to the point, if I *did* circumvent the Page_Load .DataBind() would that have any effect on the Comment TextBox being blanked out/storing '' to the Comments table?
 
you had the correct order in your cancel event, why it was changed i have not a clue!

Everything under
...
private void Page_Load(object sender, System.EventArgs e)
{
...

processess on every event up until the if (!IsPostBack) every time.

Its hard for me to make a suggestion on where to place it instead, because the DataView initialization may need to be there, i would say its not "best practice" to have it how it is, will it work? maybe. double databinding will lead to other issues as you expand, so now would be a good time to review the flow and make adjustments.





 
That's where I'm kind of stuck. This report (and a dozen others like it) were designed and implemented LONG before the user request to add Comments came about. That means whatever solution I come up with to add Comments to this project has to port well to the others.

At first it seemed like a fairly easy request, but it's quickly turned into a bit of a head scratcher for me.

In any event, thanks all for your help, if you think of any other advice or ideas - please send them along :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top