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 Shaun E on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Datagrid with TextBox 1

Status
Not open for further replies.

romh

Programmer
Jan 3, 2003
297
US
Hi. I have a datagrid that gets binded from a mySql query.
I use all bound columns. I need one of the colums to be a text box which after the user types in a value (i use ontextchanged), I need a function to be called which runs some queries from Mysql and gives a Yes or No response. I know how to do all of this except the part of calling the function with a parameter that indicates the row or record the text box is coming from.
Here is my code for the textbox column
<asp:TemplateColumn HeaderText="Square Feet">
<ItemTemplate >
<asp:textbox runat="server" width="60" ontextchanged="FindSF"/>
</ItemTemplate >
</asp:TemplateColumn>

I have used the
DataBinder.Eval(Container.DataItem,"DataField") as an argument before. Is this what I need to use again?

Thanks. If this question is not clear, please ask further questions.




 
You can use the DataBinder.Eval(Container.DataItem,"DataField"), as you've suggested, yes.

You can also set the DataKeyField property of the datagrid to the PK of your rowset, and then you can retrieve that value in your EventHandler by examining the .DataKeys[ItemIndex] value of the DataGrid.

So:

OnTextChanged(object sender, DataGridCommandEventArgs e)
{
string id = myDataGrid.DataKeys[e.Item.ItemIndex].ToString();
}

Either way will work just fine.

-paul

penny.gif
penny.gif

The answer to getting answered -- faq855-2992
 
Thanks paul. The above works great if I replace the
e.Item.ItemIndex with a 0, 1, or depending on how many rows the datagrid has. But I can;t use e.Item.ItemIndex. I get the following error when calling the function

Method 'ASP.inventorysearch2_aspx.FindSF(object, System.Web.UI.WebControls.DataGridCommandEventArgs)' does not match delegate 'void System.EventHandler(object, System.EventArgs)'

I am simply calling the function FindSF from the textbox ontextchanged.
It goes something like this

<asp:textbox runat="server" width="60" ontextchanged="FindSF" />

Thanks again. I am just starting to work on ASP.net so I am not a pro yet by any means.


I declated FindSF like this:
void FindSF(Object source, DataGridCommandEventArgs e)
{
}

I used to have it like this
void FindSF(Object source, EventArgs e)
{
}

 
Ah. My bad. The OnTextChanged event doesn't use the DataGridCommandEventArgs argument. Hence, no ItemIndex.

Hmmmm... how to get the PK, then, if you have no access to the ItemIndex. Using OnTextChanged in this situation probably isn't going to work. You need some way to pass that argument, and unless you want to "roll your own" with a client side script solution (which could be done), you are going to have to go with a button click or the like where you can send, if not an argument, at least the ItemIndex along with the event.

Doing it with a button next to the textbox would be simple:

<asp:textbox runat="server" width="60" />
<asp:button runat=server OnCommand="FindSF" Text="Click me after the text changes"/>

Now, your:
void FindSF(Object source, DataGridCommandEventArgs e)
signature will work.

Does this work, or do you want to tackle the client side approach? It would be considerably more complicated.

-paul

penny.gif
penny.gif

The answer to getting answered -- faq855-2992
 
That didn;t work either. I get the following error

: Method 'ASP.inventorysearch2_aspx.FindSF(object, System.Web.UI.WebControls.DataGridCommandEventArgs)' does not match delegate 'void System.Web.UI.WebControls.CommandEventHandler(object, System.Web.UI.WebControls.CommandEventArgs)'

I am going to show you my datagrid so you have an idea

<asp:Datagrid ID="grid1" DataKeyField="autos" Runat="server" autogeneratecolumns="false">
<columns>
<asp:TemplateColumn HeaderText="Image">
<ItemTemplate >
<img runat="server" src=<%#DisplayURL(DataBinder.Eval(Container.DataItem,"Stock Number").ToString())%> height="30" width="30" border="1" bordercolor="lavendar">
</ItemTemplate >
</asp:TemplateColumn>
<asp:BoundColumn runat="server" DataField="autos" headertext="Autos" visible="false"/>
<asp:BoundColumn runat="server" DataField="stock number" headertext="Stock Number"/>
<asp:TemplateColumn HeaderText="Square Feet">
<ItemTemplate >
<asp:textbox id="sf" runat="server" width="60"/>
</ItemTemplate >
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Find">
<ItemTemplate >
<asp:button id="btnFind" runat="server" Text="Click to Find" width="80" onCommand="FindSF" />
</ItemTemplate >
</asp:TemplateColumn>
</columns>
</asp:DataGrid>


I appreciate everything you're doing for me. Thanks again

 
One more thing. Seems to me like I'm going to be doing alot of passing record primary key fields from datagrids so I would like to get the procedure working well. I have another similar problem. I made an asp: ImageButton inside the datagrid and when the user clicks on it, I would like the primary field to be sent to a function which performs a query, looks up a record and opens up a zoomed version of the picture. I need to run a query in a database because that is where I have the location of the file (in a varchar in mysql). Thank you. Seems like its the same type of problem as the 1st question.

 
Using OnTextChanged in this situation probably isn't going to work."

Not necessarily. A handy function that may help you out is Page.GetPostBackEventReference(). It takes the reference of a control and an optional string argument and can be used to give pretty much any element PostBack funtionality (I use it to make div elements and table cells post back onclick).

Using it, you can, for example hook the event onto a button (which you can make invisible), like:

Code:
//this will hook the onblur event of the TextBox up to
//the button "myButton".
myTextBox.Attributes.Add( "onblur", Page.GetPostBackEventReference( myButton ) );

I've only done it with normal buttons and empty EventArgs before, but I'm sure there's a way to use it to PostBack the info you want (even if it involves the optional string argument).

[COLOR=blue gainsboro]
Get a FREE iPod by helping me get mine! Click my referrer link:

More about the company and deal:
[/color]
 
<asp:button id="btnFind" runat="server" Text="Click to Find" width="80" CommandName="Find" />

The error of my ways was specifying an OnCommand for the button. Actually, if the button is clicked w/in the context of the datagrid, it's automatically considered a DataGridItemCommand, so you need to wire the OnItemCommand event of the datagrid to your FindSF, and then just set the CommandName for the button.

~~
grid1.ItemCommand += new DataGridCommandEventHandler(FindSF);
~~

The CommandName argument for the button can be inspected in your event handler if, perhaps, you want to funnel several different commands through the same event handler.


BoulderBum,

I'm interested in your solution, as well, though. How is the optional argument passed to the EventHandler? Can you show us an example event handler that would subscribe to the event in your example?

Thanks,
paul

penny.gif
penny.gif

The answer to getting answered -- faq855-2992
 
Thanks Paul. I agree. The last method worked like a charm. I appreciate it. I was also looking at some examples from msdn after you posted your solution and they also did it the way you describe. The only slight problem, is that I cannot extract the value entered into the textbox. Simply nothing comes up. Will it be possible to extract this value?
I use:
TableCell sfcell = e.Item.Cells[5];

where 5 is the 5th column in the datagrid that has the textbox.

Thanks again.
 
Use 0 (zero) indexing. Column 5 is e.Item.Cells[4].

Paul:

The optional argument is simply passed as a string. You could, for example, say:

Code:
myTextBox.Attributes.Add( "onblur", Page.GetPostBackEventReference( customControl, "RowIndex" ) );

Where "customControl" is a control you created specifically to handle the PostBack (and the string argument) and "RowIndex" would actually be the row index integer.

That said, it may be possible to simply omit the string and attach the PostBackReference to the command button (I'm actually not sure what happens to the event arguments in such a setup, which is why I say may).

It would be a fun experiment anyway.

As a trivia note, ASP.NET server-side event handlers are "called" according to a few Post parameters, which is what GetPostBackEventReference actually wires up. Interestingly, there isn't a check of the Post parameters to see if the control is actually visible when its event handler is being called.

I point this out because I've seen several developers handle page security by simply making controls "invisible" on a form, but if an attacker has a bit of knowledge about the hidden control structure then the visibiliy of the controls has no bearing on the ability to call their event handlers. The attacker need only provide the proper parameters in a Post to take advantage of the "hidden" functionality.

[COLOR=blue gainsboro]
Get a FREE iPod by helping me get mine! Click my referrer link:

More about the company and deal:
[/color]
 
Good explanation. Hey, but that didn;t work either. It seems like it doesn;t know what the value of the textbox is. Any ideas that you can share?


 
By "didn't know the value of the textbox" do you mean to say that the EventArgs were empty? All you need to do is get the index of a column somehow and you'll be golden. If need be, you can explicitly pass the row index as a string in the customControl, then reference myGrid.Items[ Convert.ToInt32( passedString ) ]; (or whatever) in its event handler.

[COLOR=blue gainsboro]
Get a FREE iPod by helping me get mine! Click my referrer link:

More about the company and deal:
[/color]
 
These are the portions of my code

string stocknumber, pattern, size, sf;

TableCell stocknumbercell = e.Item.Cells[2];
TableCell patterncell = e.Item.Cells[3];
TableCell sfcell = e.Item.Cells[5]; // this is the textbox

stocknumber = stocknumbercell.Text;
pattern = patterncell.Text;
size = sizecell.Text;
sqler.Text = stocknumber + " " + size + " " + sf + " sf";

The result goes something like this.
3ba01 20x20 sf

Somehow it just doesn;t display anything for the textbox value. There should be a number in between 20x20 and sf which represents the number type in the textbox. Hope that helps.

Thanks

 
I left out a line. Ignore the previous reply


These are the portions of my code

string stocknumber, pattern, size, sf;

TableCell stocknumbercell = e.Item.Cells[2];
TableCell patterncell = e.Item.Cells[3];
TableCell sfcell = e.Item.Cells[5]; // this is the textbox

stocknumber = stocknumbercell.Text;
size = sizecell.Text;
sf = sfcell.Text;

sqler.Text = stocknumber + " " + size + " " + sf + " sf";

The result goes something like this.
3ba01 20x20 sf

Somehow it just doesn;t display anything for the textbox value. There should be a number in between 20x20 and sf which represents the number type in the textbox. Hope that helps.

Thanks
 
romh,

The textbox value can be extracted by obtaining a reference to the textbox via the .FindControl method of the Item:

TextBox sf = (TextBox)e.Item.FindControl("sf");
string theValue = sf.Text;


BoulderBum,

Sorry if I'm being dense here (wouldn't be the first time), but I'm still unsure of how you are saying you can retrieve the argument. The method to pass it is clear enough... granted.

But do we use the CommandEventArgs signature, or the normal EventArgs signature w/ your suggested method? If it's the latter, then I don't see where the argument is passed, so that's really where I was asking for clarification.

Thanks for any additional light you can shed on the subject.

-paul

penny.gif
penny.gif

The answer to getting answered -- faq855-2992
 
That worked beautifully. Thanks Paul and BoulderBum for your help. Once I get more and more experienced, I'll ask harder questions. And I can also help people out. I'm trying to convert and Access database with alot of VBA (that I wrote) into ASP.net with mysql backend. Thanks.

 
Sorry if I'm being dense here (wouldn't be the first time), but I'm still unsure of how you are saying you can retrieve the argument."

If the event args are automatically passed with the no-string version (which may or may not be the case, I'm not sure), then you'd be able to reference any of the hooked control's EventArgs.

If only a control's handler is called without its EventArgs getting wired, then you'd need to create your own control that raises a PostBack event, and have it expect a string version of the index ("1", "2", "3") then assign said index on ItemDataBound by referencing e.Item.ItemIndex.ToString().

You don't actually worry about a signature if using the function.

[COLOR=blue gainsboro]
Get a FREE iPod by helping me get mine! Click my referrer link:

More about the company and deal:
[/color]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top