Link button in Repeater control redirect to grid view - asp.net

I am developing a web application where I have a repeater control. A link button is inside the repeater control. When the link button is clicked, I want it to redirect to a page which would be a data entry page for that particular user(which was clicked). It has to use the user-id/emplid and pre-populate some fields in the new page and other fields should be allowed for data-entry.
My question-
How should I redirect to the new data entry page? I haven't decided on the page yet. I am thinking that it would be a form page or grid view and would be a separate page.
Code:
<asp:LinkButton ID="getDetails" OnCommand="getDetails_cmd" runat="server"
CommandArgument='<%#DataBinder.Eval(Container.DataItem,"Emplid")%>
' Text='<%#DataBinder.Eval(Container.DataItem,"NAME")%>'
CommandName="Details"></asp:LinkButton>
After redirecting to the page, I guess, using the commandargument, I can get the emplid. an I pass multiple values? Say the keys for the page?
How should I update multiple tables in the page?
Any help would be really appreciated.
Thanks,

You need handle ItemCommand event of Repeater control.
<asp:Repeater ID="Repeater1" runat="server"
onitemcommand="Repeater1_ItemCommand">
<ItemTemplate>
<asp:LinkButton
ID="getDetails"
runat="server"
Text='<%# Eval("NAME") %>'
CommandName="cmd"
CommandArgument='<%# Eval("Empid") %>'
>
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
Handler of ItemCommand event,
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "cmd")
{
Session["empid"]=e.CommandArgument;
Response.Redirect("~/page1.aspx");
}
}

If you're trying to direct to a new page, linkbutton is probably not the way to go since it does a postback to the same form normally, a standard hyperlink sending emplid in the querystring would work. In the new page get the emplid from the querystring using Request.Querystring("emplid"). As for saving to multiple tables, there are a number of ways to do that, one would be to wrap the multiple db update calls in a transactionscope.

Related

Button inside repeater

I have a repeater on my page, page1, which displays product details in each item. Each item has "select this" button and I post to page2. I want to display which product selected on page2. Sounds simple but couldn't solve it for hours. Any idea? My itemtemplate on page1 looks like this:
<ItemTemplate>
<ul>
<li><%#Eval("Product_Name") %></li>
<li><%#Eval("Product_Code") %></li>
...
<li>
<asp:Button ID="btnSubmit" runat="server" Text="Select this" PostBackUrl="page2"/></li>
</ul>
</ItemTemplate>
Only solution came to my mind getting button number with Request.Form but this will make me add one more query to get nth product. Thanks for help
Not sure it would apply to your situation, but usually, this problem is solved by using the ItemCommand pattern :
First subscribe to ItemCommand event of your repeater (same as subscribing to ItemCreated/ItemDataBound)
yourRepeater.ItemCommand += yourRepeater_ItemCommandHandler;
where the handler is :
protected void ItemCommandHandler(object source, RepeaterCommandEventArgs e)
{
if(e.CommandName=="SelectThis")
{
var productCode = e.CommandArgument;
//...
}
}
then, in your markup :
<asp:Button ID="btnSubmit" runat="server" Text="Select this" CommandName="SelectThis" CommandArgument='<%#Eval("Product_Code")%>' />
never tried this pattern when posting to another page. Hope this will help anyway.
Is a PostBack necessary? If not i suggest you to solve this problem with this approach:
Replace your asp:Button with asp:HyperLink and pass productId or productCode in a QueryString. Here's an example:
<ItemTemplate>
<ul>
.
.
<li>
<asp:HyperLink ID="hlSelectProduct" runat="server" Text="Select this" NavigateUrl='<%# string.Format("~/Page2.aspx?Product_Code={0}", Eval("Product_Code")) %>' />
</li>
</ul>
</ItemTemplate>
and on page2.aspx just retrieve product from database by using Product_Code
I cannot use querystrings because I don't want everything to be shown on url. And I tried ItemCommand but it requires page to post itself. For the same reason, I couldn't use onclientclick either.
However, I managed to solve the problem by using Jquery. I created a hiddenfield outside of repeater and created a jquery function to handle button clicks. I put the product id value in each buttons' rel attribute and assigned it to hiddentext's val by that function. Jquery function did work before page post and since my buttons all have postbackurl addresses, it worked without problem.

Why do my dynamically added controls loose their values after Postback?

To ask my question I have created an aspx file containing a Button and a DataList with an SqlDataSource:
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:DataList ID="DataList1" runat="server" DataKeyField="a"
DataSourceID="SqlDataSource1" >
<ItemTemplate>
a:
<asp:Label ID="aLabel" runat="server" Text='<%# Eval("a") %>' />
<br />
b:
<asp:Label ID="bLabel" runat="server" Text='<%# Eval("b") %>' />
<br />
</ItemTemplate>
</asp:DataList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:probaConnectionString %>"
SelectCommand="SELECT [a], [b] FROM [PROBA_TABLE]"></asp:SqlDataSource>
In my code behind I add TextBoxes to the Items of the DataList. I add to every Item a TextBox in the Page_Load, and another TextBox in the Button Click eventhandler as well.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (DataListItem item in DataList1.Items)
{
item.Controls.Add(new TextBox());
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
foreach (DataListItem item in DataList1.Items)
{
item.Controls.Add(new TextBox());
}
}
}
}
This works fine except one thing. When I click the Button, the TextBoxes which were created in the Page_Load keep their Text value, but the TextBoxes which were created in the Button1_Click lose their Text values. My real problem is more complicated than this, but I think solving this would help me a lot.
Each control that should receive data from page ViewState should be instantiated in Init or Load event handlers, because ViewState is persisted to controls BEFORE Click, Change and the rest control events (those events are triggered when ViewState changes are detected, so ViewState must be read before Click event is fired).
So the process should look like:
OnInit (static controls get created)
Static control content is deserialized from ViewState
OnLoad (create dynamic controls, in your case textboxes that you created in last Postback)
Dynamic control content is deserialized from ViewState
Click, Change and other events are fired according to changes detected comparing POST data and ViewState data
Suggestions:
You can use hidden fields to save additional status information, and then in OnLoad you can read that info to recreate dynamically created controls.
Also, you should explicitly set ID property of your textboxes so that values can be properly persisted back, don't rely on ASP.Net.
the http by default is stateless that means after your request is processed the server keeps no data or info of the request
but the values in the form need to be persisted in special cases when there is an error
suppose you fill up a long form and then post it back to the server only to get an error message and all the filled up values are gone. wouldn't that be annoying
so what asp.net does behind the scenes that it keeps a string in the page hidden that has information about all the server controls and their ids
so when you post a form back the Page class is created and the values that are posted back and binded in the specific controls because the Page class is being created in every request the pageLoad event is run and controls created in the PageLoad are then present values corresponding to their ids are put into them unlike the controls that are being created on button click till the button_click event is run that viewstate has already been deseralized and values are filled into them

Reacting to Button commands inside a Web Usercontrol in a ASP.NET Repeater

I have an ASP.NET repeater, whose ItemTemplate is a WebUsercontrol named ProviderControl.
<asp:Repeater ID="rep" runat="server" OnItemDataBound="rep_ItemDataBound">
<ItemTemplate>
<custom:ProviderControl ID="row" runat="server" />
</ItemTemplate>
</asp:Repeater>
I am populating the custom control with data in the ItemDataBound event.
Inside the provider control I have two buttons that I want to be able to react to on the containing Page.
I know there are Commands, and Command arguments, but how would I do that?
Or is there an easier way than using Commands?
You have to handle ItemCommand event of "Repeater".
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
Button btn = e.CommandSource as Button;
Response.Write(btn.ID);
}
The best way would be to provide custom events in your UserControl for each button-click event. The UserControl will raise and the page can handle them.
http://www.codeproject.com/Articles/8797/Mastering-Page-UserControl-Communication#4.3

Gridview: how to restore page position after user clicked

i have a gridview control on the page with 10 pages and in that gridview column i have a hyperlink where user can click the link and it will take to different page.
the mainpage.aspx with my gridview control on it:
<asp:GridView ID="gv" Width="100%" runat="server" AllowPaging="true"/>
<Columns>
<asp:TemplateField ShowHeader="true">
<ItemTemplate>
<asp:Label ID="lblTitle" runat="server" Text='<%# Eval("Title") %>' />
<asp:HyperLink id="hlView" runat="server">View Users</asp:HyperLink>
</ItemTemplate>
......................
......................
.......................
public void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hl = e.Row.FindControl("hlView") as HyperLink;
Customers t = e.Row.DataItem;
hl.NavigateUrl = "User.aspx?Id=" + t.Id;
..................
......................
on my User.aspx page
i have
Back To Page
my question is:
here is the scanrio i ran into and not sure how to resolve this.
let says, i am on page 7 on the mainpage.aspx and i click on the link and it will take me to user.aspx page and from the user.aspx when i click on the BAck to Page then it will take me to page but i will be landed on page 1 instead of page 7
how can i restore or maintain the page number and back to the same page where i come from?
is there a way to do that?
Session State is your friend. You can either store the result set into session along with the resultset page or you can just store the page in session and query the data.
I just cannot remember if you use page_int or preload event - one of them... It will work on page load....
As Wicked Coder said use Session["PrevPage"], fill it on page_loaded event, click event
How about you try
Go Back Page
If nothing works out you can always create a Session["PrevPage"] and store the previous page name in that session and use it when you click back. But thats not the preferred way though.
EDIT:
Using Session from aspx page.
<a href='<%=Session["PrevPage"]%>'>Back To Page</a>

Switching a Repeater's ItemTemplate at runtime

Is it possible to define multiple templates for a Repeater's ItemTemplate and switch between them according to some condition?
I use a repeater to view a list of posts but want to have a different view for rows that belong to the current user (e.g. contains a LinkButton for deleting the post)
If this is not possible, then is it possible to use a Multiview control inside a Repeater's ItemTemplate?
I tried to use a MultiView control inside the ItemTemplate and it worked very well, hope this helps someone with the same problem:
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand">
<ItemTemplate>
<asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="<%# ((Post)Container.DataItem).Member.ID == CurrentMemberID ? 1 : 0 %>">
<asp:View ID="View1" runat="server"><!-- some links --></asp:View>
<asp:View ID="View2" runat="server"><asp:LinkButton CommandName="DeletePost" CommandArgument="<%# ((Post)Container.DataItem).Id %>" ID="LinkButton1" runat="server">Delete Post</asp:LinkButton></asp:View>
</asp:MultiView>
</ItemTemplate>
</asp:Repeater>
I don't know if it's possible to switch between templates, but I've found the the Repeater.OnItemDataBound event most useful for modifying the display of individual repeater items.
For example, to show a link button based on the current user...
protected void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
LinkButton = e.Item.FindControl("btnDelete");
LinkButton.Visible = (e.Item.DataItem as DataRow)["CreatedBy"] == getCurrentUser();
}
Generally I keep the layout of the data consistent for each repeater item and modify the visual appearance by altering the CssStyle and Visible properties of controls in the template. If there are more radical layout changes, I'll put each layout option inside a placeholder and use logic to determine which placeholder to show.

Resources