I hope I can explain this properly.
I have a grid that is part of our 3rd party shopping cart software. This grid has a row of quantity text boxes into which the customer enters how many of each thing they want to buy.
I put this grid inside a panel so I can set it on or off with
myPanel.Visible=true;
I also have a button to show and one to hide using the above code method.
If I enter a value into a textbox and then click the hide button and then click the show button, when the panel reappears the values are zero. If I then reload the page (browser reload) then the value returns as it was originally. It's a pretty good magic trick but not what I need. What am I doing wrong?
Eventually I want to select a date from a calendar while it is hidden but that is not in play yet... just the show/hide buttons.
Thanks
This sounds like the correct behaviour of ASP.NET WebForms and ViewState
First page load: Panel is visible and the panel loaded with its initial values.
Hide Panel: As soon as the button is pressed a post back occurs. myPanel is set to invisible which on the server side means that the HTML for the panel is not generated (this can be confirmed by looking the generated HTML).
Show Panel: A post back occurs again. But because the values were not rendered in the previous step, they are not available in the ViewState to repopulate the panel.
Reload of the page: This start the process over again (Same as step 1)
A possible solution is to instead hide the panel (<div) on the client-side. This will also have the benefit of not making a round trip to the server to just enable/disable the panel.
Your code should be like below...
Show and Hide button definition to show/Hide the panel is in Java script. That mans there is no handler of Button click event at server side...This approach is suggested normally and fast..
Sample ASPX Code
<script type="text/javascript" language="javascript">
function Hide() {
var ID = document.getElementById('pnl');
ID.style.display = 'none';
return false;
}
function Show() {
var ID = document.getElementById('btnHide');
ID.style.display = 'block';
return false;
}
</script>
<asp:panel id="pnl" runat="server">
<asp:GridView ID="grd" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="ed" runat="server" Text='<%#Eval("name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:panel>
<asp:button text="Hide" runat="server" id="Button1" onclientclick="return Hide();" />
<asp:button text="Show" runat="server" id="btnShow" onclientclick="return Show();" />
Sample Code Behind
public partial class Default4 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
using (DataTable Dt = new DataTable())
{
using (DataColumn Dc = new DataColumn("Name"))
{
Dt.Columns.Add(Dc);
DataRow dr = Dt.NewRow();
dr["name"] = "1";
Dt.Rows.Add(dr);
dr = Dt.NewRow();
dr["name"] = "2";
Dt.Rows.Add(dr);
grd.DataSource = Dt;
grd.DataBind();
}
}
}
}
}
Related
I'm new to C# and I'm running into the following issues. When I click on the link button(for pagination), it will go to the code behind the page using postback. But the postback will refresh the background color of the button I set on CSS, how should I do?
I used the ViewState but it still doesn't work.
What I originally wanted was that when the user presses the paging number, the paging number will display a different color, so that the user can tell which button they are pressing.
Like, when the user press 2, the page will show page 2's details using postback and the paging number at button will show
1 2 3 4
Here is my code:
<asp:Repeater ID="rptPaging" runat="server" OnItemCommand="rptPaging_ItemCommand" >
<ItemTemplate>
<asp:LinkButton ID="lnkPage"
Style="padding: 8px; margin: 2px; background: lightgray; border: solid 1px #666;font-weight: bold;"
CommandName="Page" CommandArgument="<%# Container.DataItem %>" runat="server" CssClass="listbtn"
ForeColor="Black" Font-Bold="True"><%# Container.DataItem %>
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
this is the code behind,
public int PageNumber
{
get
{
if (ViewState["PageNumber"] != null)
{
return Convert.ToInt32(ViewState["PageNumber"]);
}
else
{
return 0;
}
}
set { ViewState["PageNumber"] = value; }
}
private int iPageSize = 100;
private void BindRepeater(DataTable dt)
{
//Finally, set the datasource of the repeater
PagedDataSource pdsData = new PagedDataSource();
DataView dv = new DataView(dt);
pdsData.DataSource = dv;
pdsData.AllowPaging = true;
pdsData.PageSize = iPageSize;
if (ViewState["PageNumber"] != null)
pdsData.CurrentPageIndex = Convert.ToInt32(ViewState["PageNumber"]);
else
pdsData.CurrentPageIndex = 0;
if (pdsData.PageCount > 1)
{
rptPaging.Visible = true;
ArrayList alPages = new ArrayList();
for (int i = 1; i <= pdsData.PageCount; i++)
alPages.Add((i).ToString());
rptPaging.DataSource = alPages;
rptPaging.DataBind();
}
else
{
rptPaging.Visible = false;
}
rptTxnHist.DataSource = pdsData;
rptTxnHist.DataBind();
}
protected void rptPaging_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
{
string sDateFr = datepicker.Value;
string sDateTo = datepicker2.Value;
PageNumber = Convert.ToInt32(e.CommandArgument) - 1;
//ViewState["PageNumber"] = Convert.ToInt32(e.CommandArgument);
LoadUI(PageNumber, "NAME", sDateFr, sDateTo);
}
css code:
a:hover, a:focus{
color:white;
background-color:black;
}
Now, I read the question to be about a data pager.
But, the goal seems to be just to change the style of a button in the repeater once clicked.
So, assume this repeater:
<style>
.mylinkbtn {
padding: 8px;
margin: 2px;
background: lightgray;
border: solid 1px #666;
font-weight: bold;
}
</style>
<div style="padding:35px;width:25%">
<asp:Repeater ID="rptPaging" runat="server" >
<ItemTemplate>
<div style="text-align:right">
<asp:Label ID="lblH" runat="server" Font-Size="14"
Text= "View Hotel Name ">
</asp:Label>
<asp:Label ID="lblHotel" runat="server" Font-Size="14"
Text='<%# Eval("HotelName") %>' >
</asp:Label>
<asp:LinkButton ID="lnkPage" CssClass="mylinkbtn"
runat="server" Text="View"
ForeColor="Black" Font-Bold="True"
OnClick="lnkPage_Click" >
</asp:LinkButton>
<br />
<br />
</div>
</ItemTemplate>
</asp:Repeater>
This code to load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
DataTable rstOptions =
MyRst("SELECT ID, HotelName FROM tblHotelsA ORDER BY HotelName");
rptPaging.DataSource = rstOptions;
rptPaging.DataBind();
}
DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
REMEMBER!!!! - ONLY re-bind the grid ONE time (!IsPostBack). If you leave that bit out, then you are re-binding the repeater and will LOSE your button change of style.
But, a simple post-back WILL NOT re-set the style(s) to apply to any repeated control(s) in the repeater.
So, we get this:
Now, our button click code. I really DO NOT LIKE the command and button event model for a gridview, listview, repeater etc.
I just drop in a plane jane button, or whatever. Just in the markup type in onclick= (and then space bar - you are promped to create a event click for that button (or any other event). That way you don't have to mess around with row command.
Hence this code:
protected void lnkPage_Click(object sender, EventArgs e)
{
LinkButton btn = (LinkButton)sender;
RepeaterItem rRow = (RepeaterItem)btn.NamingContainer;
int MyRowIndex = rRow.ItemIndex;
Debug.Print("row index = " + MyRowIndex);
// get hotel name value
Label lblHotel = (Label)rRow.FindControl("lblHotel");
Debug.Print("Row click hotel = " + lblHotel.Text);
// change button class to show it was clicked
btn.CssClass = "btn btn-info";
}
So, for each button I click on, we see this:
And the output window of the clicks shows this:
So any style you apply to controls - including that link button will work, and CAN survive a post-back. But, your standard page load event NEAR ALWAYS has to be placed inside of a !IsPostBack stub (last 100+ web pages have such a code stub). In other words, if you re-bind the repeater, then yes of course it will re-plot, re-load, and you lose the style buttons or any other style you applied.
However, since your page !IsPostBack stub on runs on the REAL first page load, then such style settings for buttons controls etc. will persist, and they have automatic view state preserved for you.
So, either you not setting the style to the given row in the repeater, or your page load event is re-binding and re-loading the repeater which of course will blow out and re-set your buttons.
But, for Gridview, repeater, Listview and more such data bound controls? The state of such controls and buttons should persist, assuming you use the all important !IsPostBack code stub (which as I noted, quite much every single page you write will need if you loading up any data bound control(s)).
And as above shows, you are free to have other buttons and have as many post-backs as you wish - the style settings from code behind for those buttons will and should persist.
UPDATE
I moved the Javascript to the ASPX site instead, and added a postback function for it. Now it works. Thanks to #orgtigger and especially #lucidgold for spending their time helping me!
Here is the update code that works!
<script type="text/javascript">
function changevalue(katoid) {
$('#<%=txtboxchosenkat.ClientID%>').val(katoid);
__doPostBack('<%= updpnlgridview.ClientID %>', '');
}
</script>
Code:
<asp:UpdatePanel ID="updpnlgridview" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="txtboxchosenkat" style="display:none;" runat="server" OnTextChanged="txtboxchosenkat_TextChanged" AutoPostBack="true"></asp:TextBox>
<asp:GridView ID="gridview" runat="server"></asp:GridView>
</ContentTemplate>
</asp:UpdatePane
Code-behind:
protected void hidfldchosenkat_ValueChanged(object sender, EventArgs e)
{
SqlConnection cn2 = new SqlConnection("Server=**,***,***,**;Database=******;
User Id=******;Password=******;");
SqlCommand cmd2 = new SqlCommand("SELECT * FROM tblProducts where KatID='" +
txtboxchosenkat.Text + "'", cn2);
SqlDataAdapter da2 = new SqlDataAdapter(cmd2);
da2.SelectCommand.CommandText = cmd2.CommandText.ToString();
DataTable dt = new DataTable();
da2.Fill(dt);
gridview.DataSource = dt.DefaultView;
gridview.DataBind();
}
The links (only part of code that makes links):
string line = String.Format("<li><a href='#' onclick='changevalue(" + pid + ");'>{0}",
menuText + "</a>");
Old Post
I need to update a GridView based on the value of a HiddenField. I am currently using a button to populate the GridView, but would like to do it automaticaly as soon as the value in the HiddenField changes.
But when I change the value with a javascript, then event doesn't fire.
(Same thing also happens in case of a TextBox and its OnTextChanged event.)
Not sure if this is way it's meant to work.
A Hidden field will not produce a postback (there is no AutoPostBack property), which means no postback will happen when the value of the hidden field has changed. However, when there is ANY postback from the page then OnValueChangd event will execute if a hidden field value has changed.
So you should try the following ideas:
1) Update your JavaScript for changevalue as follows:
function changevalue(katoid)
{
document.getElementById('" + hidfldchosenkat.ClientID + "').value=katoid;
_doPostBack(); // this will force a PostBack which will trigger ServerSide OnValueChange
}
2) Change your HiddenField to a TextBox but set the Style="display:none;" and set AutoPostBack="true":
<asp:TextBox runat="server" ID="hidfldchosenkat"
Value="" Style="display:none;"
AutoPostBack="true" OnTextChanged="hidfldchosenkat_TextChanged">
</asp:TextBox>
This example works great for me:
JavaScript:
function changevalue()
{
$('#<%=hidfldchosenkat.ClientID%>').val("hi");
}
ASPX Code:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="hidfldchosenkat" runat="server" AutoPostBack="true"
ontextchanged="hidfldchosenkat_TextChanged"></asp:TextBox>
<asp:Button ID="Button1"
runat="server" Text="Button" OnClientClick="changevalue()" />
</ContentTemplate>
</asp:UpdatePanel>
C# Code-Behind:
protected void hidfldchosenkat_TextChanged(object sender, EventArgs e)
{
string x = "hi"; // this fires when I put a debug-point here.
}
Your issue could be with:
document.getElementById('" + hidfldchosenkat.ClientID + "').value=katoid
You may want to try:
$('#<%=hidfldchosenkat.ClientID%>').val(katoid);
Also you should PUT changevalue() inside your ASPX JavaScript tags and not register it for every LinkButton.... so instead try the following:
protected void lagerstyringgridview_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Assuming the LinkButtons are on the FIRST column:
LinkButton lb = (LinkButton)e.Row.Cells[0].Controls[0];
if (lb != null)
lb.Attributes.Add("onClick", "javascript:return changevalue(this);");
}
}
You can have any event fire by doing a __doPostBack call with JavaScript. Here is an example of how I used this to allow me to send a hiddenfield value server side:
ASPX
<asp:HiddenField runat="server" ID="hfStartDate" ClientIDMode="Static" OnValueChanged="Date_ValueChanged" />
JavaScript
$('#hfStartDate').val('send this');
__doPostBack('hfStartDate');
This will call the OnValueChanged event and cause a postback. You can also set this is a trigger for an update panel if you would like to do a partial postback.
I have a table in an update panel. This table gets filled form the code behind and there is also a button added. This button triggers a Javascript. Because this button triggers a Javascript I don't need the button to do a postback. Is there a way to disable this postback?
This is the code I use to set the imagebutton in a table cell for each row.
ImageButton ibtnTableOneNewComment = new ImageButton();
ibtnTableOneNewComment.ImageUrl = "~/img/Pencil.png";
ibtnTableOneNewComment.OnClientClick = "setDiscription('test', 'testy')";
tabCell.Controls.Add(ibtnTableOneNewComment);
The table headers get set in the asp, the rest from the code behind.
<asp:UpdatePanel runat="server" ID="up_tableMain" UpdateMode="Conditional">
<ContentTemplate>
<asp:Table runat="server" ID="tbl_main">
...Headers...
</asp:Table>
</ContentTemplate>
</asp:UpdatePanel>
Put return false; in your OnClientClick
You have to add return false; in the OnClientClick event of the button. This will block it to send any Postback request to Server:
ImageButton ibtnTableOneNewComment = new ImageButton();
ibtnTableOneNewComment.ImageUrl = "~/img/Pencil.png";
ibtnTableOneNewComment.OnClientClick = "setDiscription('test', 'testy'); return false;";
tabCell.Controls.Add(ibtnTableOneNewComment);
I have a grid view which is in webuser control and I want to select them, so that I can edit any particular row.
The web user control's (.ascx) is:
<div class="project_data">
<asp:GridView runat="server" ID="grvBranches" GridLines="None" CellPadding="5" OnRowDataBound="grvBranches_RowDataBound">
<SelectedRowStyle BackColor="#d8d8d8" />
<HeaderStyle BackColor="#d8d8d8" />
</asp:GridView>
</div>
and on the .ascs.cs page
protected void Page_Load(object sender, EventArgs e)
{
int.TryParse(OrganizationID, out OrgId);
//if (!(Page.IsPostBack))
{
grvBranches.DataSource = //datasource;
grvBranches.DataBind();
}
}
and on the .aspx.cs page I have added this control into the placeholder.
and I want to select any particular so that I can edit that row.
Thanks.
Gurbax
you can refrence jquery in your page that contains the UserControl and then you can do this either in the containing page or the user control iteself
Example Code
<script type="text/javascript">
$(document).ready(function () {
//This will select the 2nd row specified by tr:nth-child selector
//and then the tablecells specified by children() and first column
//specified by eq(0) and get its value
$('table[id$="GridView1"] tr:nth-child(2)').children().eq(0).Text();
});
</script>
After selecting the row you can any manipulation you want using jquery.
Hope it helps
I've been trying to get this working for a couple of hours now but nothing from google could help me fix the problem.
I have a very simple repeater control:
<asp:Panel ID="userDefDiv" Visible="false" runat="server">
<asp:Repeater ID="userDefRepeater" EnableViewstate="false" runat="server">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" EnableViewState="false"></asp:TextBox><br/>
</ItemTemplate>
</asp:Repeater>
</asp:Panel>
the userDefDiv panel is inside another panel, which is inside contentPLaceHolder.
the parent panel to userDefDiv does NOT have the "enableviewstate="false"".
So.
Everything on this page happens after a couple of linkbuttons_click. so nothing happens during page_load. And after i click another linkbutton i want to get the data from the different textboxes that is within the repeater.
C# code:
This is the code to create all the repeater items.
public void createUserDef()
{
DataTable userDefData;
userDefData = ..... (data from Database.)
userDefDiv.Visible = true;
userDefRepeater.DataSource = userDefData;
userDefRepeater.DataBind();
}
The code for the linkbutton:
protected void linkButton_Click(object sender, EventArgs e)
{
createUserDef();
Label2.Visible = true;
foreach (RepeaterItem item in userDefRepeater.Items)
{
TextBox box = (TextBox)item.FindControl("TextBox1");
string b = box.Text;
Label2.Text += b + " . ";
}
}
As you see i create the repeater once again during the click. But the only thing i can read in label2. is a a number of " .", on dot for each textbox.
but the text from the textbox is empty..
What am I doing wrong??
thanks for reading!
Mattias
SOLUTION:
add EnableVIewState="true" to textbox & repeater.
Dont call call dataBind() before you get the values.
Thanks!
You need to set EnableViewState to 'true' for linkbuttons to work properly in a repeater