Solved

<EditItemTemplate> -- Not reading TextBox

Posted on 2004-09-12
17
298 Views
Last Modified: 2011-09-20
Hi, when I type a new value into the textbox in my <EditItemTemplate> it is not being picked up in the update method.  There are no error messages and when I try to output the value of the textbox right away in the UpdateBook method, it shows me the old value instead of the new one I just typed in.  What an I missing?

<EditItemTemplate>
   <asp:TextBox ID="bTitle" Text='<%#DataBinder.Eval(Container.DataItem,"bookTitle")%>'  runat="server"/>
</EditItemTemplate>

------- In the method:

if(BookListCmd=="UpdateBook")
{
BookList.EditItemIndex = e.Item.ItemIndex;

Response.Write(e.Item.ItemIndex); //---Returns correct index
Response.Write(ReviewList.DataKeys[e.Item.ItemIndex]); //---Returns correct ID
Response.Write(((TextBox)e.Item.FindControl("bTitle")).Text); //---- Returns old value only

//....Connect to Databse

SqlCommand cmdUpdate=new SqlCommand("UpdateBookInfo",myConn);
     cmdUpdate.CommandType=CommandType.StoredProcedure;

     cmdUpdate.Parameters.Add("@bID",SqlDbType.Int);
     cmdUpdate.Parameters["@bID"].Value=ReviewList.DataKeys[e.Item.ItemIndex];

     cmdUpdate.Parameters.Add("@frmBTitle",SqlDbType.VarChar,50);
     cmdUpdate.Parameters["@frmBTitle"].Value=((TextBox)e.Item.FindControl("bTitle")).Text;

     cmdUpdate.ExecuteNonQuery();
BookList.EditItemIndex = -1;

myConn.Close();

BindData(); //--Refresh DataList

Response.Write(((TextBox)e.Item.FindControl("bTitle")).Text); //---- Returns old value only

Response.Write("Done!");            
}
0
Comment
Question by:champ_010
  • 8
  • 5
  • 4
17 Comments
 
LVL 17

Expert Comment

by:AerosSaga
Comment Utility
You need to rebind your data on the edit command like so:

    Private Sub dg_EditCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dg.EditCommand
        dg.EditItemIndex = e.Item.ItemIndex
        LoadProductData()
        CalculateTotal()
    End Sub
    Private Sub dg_UpdateCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dg.UpdateCommand
        Dim cnn As New OleDb.OleDbConnection(ConfigurationSettings.AppSettings("SiteDB"))
        Dim cmd As New OleDb.OleDbCommand
        Dim intQuantity As String = CType(e.Item.Cells(3).Controls(0), TextBox).Text
        cmd.CommandType = CommandType.Text
        cmd.CommandText = "UPDATE TempSession SET Quantity = " & intQuantity.ToString & " WHERE SessionString LIKE '" & Me.Session.SessionID.ToString & "' AND ProductName LIKE '" & e.Item.Cells(2).Text & "'"
        cmd.Connection = cnn
        cnn.Open()
        cmd.ExecuteNonQuery()
        cnn.Close()
        cmd.Dispose()
        cnn.Dispose()
        dg.EditItemIndex = -1
        LoadProductData()
        CalculateTotal()
    End Sub

Regards,

Aeros
0
 
LVL 17

Expert Comment

by:AerosSaga
Comment Utility
loadproductdata rebinds the grid in this instance.
0
 
LVL 1

Author Comment

by:champ_010
Comment Utility
Hi, thanks but it didn't work.  Why would I rebind the data on the edit command method?--it already shows what I want in the textbox.  It's when I change the text and press update that isn't reading the new text even if I rebind the data immediately in the update method.
0
 
LVL 17

Expert Comment

by:AerosSaga
Comment Utility
specifying the edit command index should hold the value of the edited text box
0
 
LVL 1

Author Comment

by:champ_010
Comment Utility
Still no luck.  If I took out the

<asp:TextBox ID="bTitle" Text='<%#DataBinder.Eval(Container.DataItem,"bookTitle")%>'  runat="server"/>

and replaced it with: <asp:TextBox ID="bTitle" Text="Hello"  runat="server"/>

The database will be updated with the world "Hello"--so I know my stored procedure is making the update it's just that a newly typed value won't stay!  
0
 
LVL 17

Expert Comment

by:AerosSaga
Comment Utility
try using this instead of the findcontrol when passing the paramater to your sproc.

e.Item.Cells(2).Text

Whatever ordinal your textbox is really in will need to go where the 2 is.

Regards,

Aeros
0
 
LVL 1

Author Comment

by:champ_010
Comment Utility
Hi this is a DataList--I don't have cells...
0
 
LVL 10

Expert Comment

by:jnhorst
Comment Utility
First: In your page load event, make sure the code that gets data from the database is not inside the if(!Page.IsPostBack) condition.  It should be like this:

Page_Load(...)
{
     // call code to fill datatable or get datareader here.

     if(!Page.IsPostBack)
     {
          // bind the list here.
          list.DataBind();
     }
}

Second, yes, rebind in the EditCommand.  This is because in the edit command you are setting the list.EditItemIndex = e.Item.ItemIndex, and in order for the list to know to load the item using the EditItemTemplate, it needs to be rebound *after* you set the list's EditItemIndex property.

I see in your update command that you are setting the list.EditItemIndex = e.Item.ItemIndex.  You don't want to do this:  That is for the edit command.  Take that out. Then in your Update command, the link for which should only be defined in the EditItemTemplate, you will use FindControl(), but make sure you have given your textbox an id.  You can do this in the HTML view of the page or by right clicking the list and choosing in the popup menu to edit the templates.  Then after you have resolved your textbox (and any other controls) and updated the database, set the list.EditItemIbdex = -1.  This will return the item to the ItemTemplate display.

You already have the idea of resolving your TextBox using FindControl(), the problem is you are calling things a bit out of sequence.

John
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Author Comment

by:champ_010
Comment Utility

Hi John,

Sorry I'm resorting to posting my code--I tried to keep it as clear and simple as possible. Points increased if you can take a look at my sequence.

My Page_Load is slightly different in that it populates a dropdownlist first then based on what was selected, it generates the datalist.  I set the choosen dropdownlist item so that it doesn't need to be chosen everytime postback.

All the other events work--only the edit doesn't!

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

<script runat="server">
string SubCatName;
string MyDataListCommand;
void Page_Load(object Sender,EventArgs e)
{
if(!IsPostBack){

     SqlConnection myConn=new SqlConnection();
     myConn.ConnectionString=ConfigurationSettings.AppSettings["myDbConn"];
     myConn.Open();
    SqlCommand cmd1=new SqlCommand("GetBookSubCats",myConn);
      cmd1.CommandType=CommandType.StoredProcedure;
      SqlDataReader dr1=cmd1.ExecuteReader();
      ChooseSubCat.DataSource=dr1;
      ChooseSubCat.DataBind();
      ChooseSubCat.Items.Insert(0, "");
      dr1.Close();
      myConn.Close();
     }else{
                SubCatName=ChooseSubCat.SelectedItem.Value;
      GetBooks();
            }
}
void GetBooks()
{
      SqlConnection myConn=new SqlConnection();
      myConn.ConnectionString=ConfigurationSettings.AppSettings["myDbConn"];
      myConn.Open();

      SqlCommand cmd2=new SqlCommand("GetBooksEdit",myConn);
            cmd2.CommandType=CommandType.StoredProcedure;
            cmd2.Parameters.Add("@subCatName",SqlDbType.VarChar);
            cmd2.Parameters["@subCatName"].Value=SubCatName;
            SqlDataReader dr2=cmd2.ExecuteReader();
            BookDataList.DataSource=dr2;
            BookDataList.DataBind();
            dr2.Close();
            myConn.Close();
}

void MyOnItemCommandHandler(object Sender,DataListCommandEventArgs e)
{
      MyDataListCommand=e.CommandName;
      
      if(MyDataListCommand=="EditBook")
      {
            BookDataList.EditItemIndex = e.Item.ItemIndex;
            GetBooks();
      }

      if(MyDataListCommand=="UpdateBook")
      {
      SqlConnection myConn=new SqlConnection();
      myConn.ConnectionString=ConfigurationSettings.AppSettings["myDbConn"];
      myConn.Open();
      
                SqlCommand cmdUpdate=new SqlCommand("UpdateBook",myConn);
      cmdUpdate.CommandType=CommandType.StoredProcedure;
      cmdUpdate.Parameters.Add("@bookID",SqlDbType.Int);
      cmdUpdate.Parameters["@bookID"].Value=BookDataList.DataKeys[e.Item.ItemIndex];
      cmdUpdate.Parameters.Add("@frmbookTitle",SqlDbType.VarChar,50);
      cmdUpdate.Parameters["@frmbookTitle"].Value=((TextBox)e.Item.FindControl("bookTitle")).Text;
      cmdUpdate.Parameters.Add("@frmbookText",SqlDbType.Text);
      cmdUpdate.Parameters["@frmbookText"].Value=((TextBox)e.Item.FindControl("bookText")).Text;
      cmdUpdate.ExecuteNonQuery();
      BookDataList.EditItemIndex = -1;
      myConn.Close();
      }

      if(MyDataListCommand=="CancelEdit")
      {
             BookDataList.EditItemIndex = -1;
      }

      if(MyDataListCommand=="DeleteBook")
      {
      SqlConnection myConn=new SqlConnection();
      myConn.ConnectionString=ConfigurationSettings.AppSettings["myDbConn"];
      myConn.Open();
      
                SqlCommand cmdDelete=new SqlCommand("DeleteBook",myConn);
      cmdDelete.CommandType=CommandType.StoredProcedure;
      cmdDelete.Parameters.Add("@itemBookDelete",SqlDbType.Int);
      cmdDelete.Parameters["@itemBookDelete"].Value=BookDataList.DataKeys[e.Item.ItemIndex];
      cmdDelete.ExecuteNonQuery();
      myConn.Close();
      }

      if(MyDataListCommand=="PostBook")
      {
      SqlConnection myConn=new SqlConnection();
      myConn.ConnectionString=ConfigurationSettings.AppSettings["myDbConn"];
      myConn.Open();

      SqlCommand cmdPost=new SqlCommand("PostBook",myConn);
      cmdPost.CommandType=CommandType.StoredProcedure;
      cmdPost.Parameters.Add("@itemBookPost",SqlDbType.Int);
      cmdPost.Parameters["@itemBookPost"].Value=BookDataList.DataKeys[e.Item.ItemIndex];
      cmdPost.ExecuteNonQuery();
       myConn.Close();
      }
 
           GetBooks();
}
</script>
0
 
LVL 10

Expert Comment

by:jnhorst
Comment Utility
I'll pseudo code some changes:

void Page_Load(object Sender,EventArgs e)
{
     // load up drop down list if page is not postback.
     if (!Page.IsPostBack)
     {
          // code here to get dropdown list data and bind dropdown
     }
}

// code for the SelectedIndexChanged event of the dropdown.
void ChooseSubCat_SelectedIndexChanged(object sender, System.EventArgs e)
{
     // call a routine to query the db with the SelectedItem.Value
     GetBookData();

     // bind the list.
     BookDataList.DataBind();
}

// have a separate routine for the edit command.
private void BookDataList_EditCommand(object source, System.Web.UI.WebControls.DataListCommandEventArgs e)
{
     // call a routine to query the db with the SelectedItem.Value and bind the list.
     GetBookData():

     // set edit item index.
     BookDataList.EditItemIndex = e.Item.ItemIndex;

     // bind.
     BookDataList.DataBind();
}

// have a separate routine for the update command.
private void BookDataList_UpdateCommand(object source, System.Web.UI.WebControls.DataListCommandEventArgs e)
{
     // resolve textbox.
     TextBox tb = (TextBox)e.Item.FindControl("bookTitle");
     ... and so on

     // update the database.

     // reset edit item index.
     BookDataList.EditItemIndex = -1;

     // Bind.
     BookDataList.DataBind();
}

// have a separate routine for cancel.
private void BookDataList_CancelCommand(object source, System.Web.UI.WebControls.DataListCommandEventArgs e)
{
     // reset edit item index.
     BookDataList.EditItemIndex = -1;

     // Bind.
     BookDataList.DataBind();      
}

// separate routine for delete.
private void BookDataList_DeleteCommand(object source, System.Web.UI.WebControls.DataListCommandEventArgs e)
{
     // resolve the datakey and call routine to delete.

     // Bind.
     BookDataList.DataBind();
}

In your HTML, yourt <asp:DataList...> you need to specify attributes for each of your commands:

OnEditCommand="BookDataList_EditCommand"
OnUpdateCommand="BookDataList_UpdateCommand"
OnCancelCommand="BookDataList_CancelCommand"
OnDeleteCommand="BookDataList_DeleteCommand"

I'm not sure what you're doing with "post book", but just follow the above idea, using the OnItemCommand event.

John



0
 
LVL 10

Expert Comment

by:jnhorst
Comment Utility
Also, in the HTML for the drop down list, make sure to reference the routine for the OnSelectedIndexChanged event:

OnSelectedIndexChanged="ChooseSubCat_SelectedIndexChanged"

John
0
 
LVL 1

Author Comment

by:champ_010
Comment Utility
So you are saying this:

SubCatName=ChooseSubCat.SelectedItem.Value;

isn't enough to hold the value of the selected SubCatName for every postback?
0
 
LVL 1

Author Comment

by:champ_010
Comment Utility
I don't have a routine for the OnSelectedIndexChanged event.


string SubCatName;

On Page_Load:

If (!IsPostBack)
{
  The dynamic dropdown is populated from the DataBase
}
else
{
  Set a variable SubCatName= the selectedindexValue
  GetReviews(); //---Bind Data to DataList
}
0
 
LVL 10

Accepted Solution

by:
jnhorst earned 400 total points
Comment Utility
<<I don't have a routine for the OnSelectedIndexChanged event.>>

That's one of the main changes I am suggesting:  Create a routine like I showed and set the OnSelectedIndexChanged attribute of the <asp:DropDownList...> server control tag to point to that routine.  That is where you want to call the routine to get the data.

As for:

string SubCatName;

You do not need to do that since you can access it on the postback just by getting the SelectedItem.Value from the control.  Also (and I forgot this in my last post) set the AutoPostBack property of the dropdownlist to true.  When you make a selection, it will fire a postback.  The Page_Load event will fire, but since it is a postback, anything within if(!Page.IsPostBack) will not fire.  And then the SelectedIndexChanged event will fire.  In that routine you get the SelectedItem.Value for the new selection, query the database and bind the list.

When you click the Edit link, the page is posted back.  Page_Load fires, but again, ignores anything inside the if(!Page.IsPostBack) condition.  Then the edit command routine fires.  Here I was mistaken in suggesting in my last post that you get the data again.  Your grid's data is in viewstate so all you need to do is set the list's EditItemIndex to e.Item.ItemIndex.  Then bind the list.  This will cause it to show the selected item using the controls in the EditItemTemplate.

The EditItemTemplate should contain an Update and Cancel link (as well as the various textboxes).  When you click Update, you should be able to resolve the textboxes using e.Item.FindControl() and get whatever new data is there and send it to the database.  But make sure to set the EditItemIndex of the list to -1 *after* you get that data and update the database.

John
0
 
LVL 1

Author Comment

by:champ_010
Comment Utility
Thanks John--will try now.
0
 
LVL 1

Author Comment

by:champ_010
Comment Utility
Yahoo!!!

It seems like such little thing but makes a big difference.  I will try to understand this better.

I put an OnSelectedItemChanged event in the dropdownlist:

<asp:DropDownList ID="ChooseSubCat" DataTextField="subCatName" AutoPostBack="true" OnSelectedIndexChanged="GetSubCat" runat="server"/>

Then in the code:

<script runat="server">

string MyDataListCommand;
void Page_Load(object Sender,EventArgs e)
{
if(!IsPostBack){
 
    //....Get data to populate the DropDownList

     }
}

void GetSubCat(Object Sender,EventArgs e)
{
     string SubCatName=ChooseSubCat.SelectedItem.Value;
     GetBooks();
}

void GetBooks()
{
     //...Get data from database to bind to DataList
    //....Call this everytime to rebind data to DataList
}
-----------------------------

By the way, I just noticed that I only have DataTextField in my DropDownList but no DataValueField because I didn't really need one.  Then I refered to the selected item as: ChooseSubCat.SelectedItem.Value;--do you think this matters?  I'm not getting errors and I am getting things happening the way they should be.

Anyhow, thanks again for your patience.  

I also appreciate AeroSaga having taken a look at my problem and trying to help me.
0
 
LVL 10

Expert Comment

by:jnhorst
Comment Utility
When your page displays, look at the HTML source and see if your drop down list options (they will be in a <Select> element in HTML) has the same string in Value="" and in the text itself.  Like this:

<Select>
     <option value="SomeData">SomeData</option>
</Select>

If they do then your fine using SelectedItem.Value.  If not, just use SelectedItem.Text.

Glad you got it working...

John
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
One of the pain points with developing AJAX, JavaScript, JQuery, and other client-side behaviors is that JavaScript doesn’t allow for cross domain request for pulling content. For example, JavaScript code on www.johnchapman.name could not pull conte…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now