I'm trying to show 2 link buttons in the master page, but these buttons should be Enable/Disable according to the content page. I already retrieve the information from the content page, and it works well, the only thing is that I can't turn enable the buttons once I have disabled them. I have tried several ways, but every attempt seems to do the same. Here is my code.
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
ASPxListBox listBoxSA = new ASPxListBox();
listBoxSA = (ASPxListBox)ContentPanelHidden.FindControl("ASPxListBox2");
if (listBoxSA != null)
{
if (listBoxSA.Items.Count > 0)
{
EnableButtons(true);
}
else
{
EnableButtons(false);
}
}
}
else
{
EnableButtons(false);
}
}
public void EnableButtons(Boolean enable)
{
btnNext.Enabled = enable;
btnPrint.Enabled = enable;
}
PS. The boolean is changing its value, but the button is always disabled
I would enclose these buttons in an update panel and tell the update panel to update itself after setting the Enabled property. That should update the buttons with only a partial page update.
HTML
<asp:UpdatePanel ID="MyUpdatePanel" runat="server" UpdateMode="Conditional" ClientIDMode="Static">
<ContentTemplate>
... buttons here ...
</ContentTemplate>
</asp:UpdatePanel>
CODE BEHIND
public void EnableButtons(Boolean enable)
{
btnNext.Enabled = enable;
btnPrint.Enabled = enable;
MyUpdatePanel.Update();
}
because you are using is post back property, once it disabled you should do a post back from your current page and also listBoxSA should not be null.
Related
I have an Order page with 4 textboxes that are inside an ajax updatepanel. All the 4 have TextChanged events. None of the controls in this page have TabIndex property set. When I enter text in textbox1 & press the tab key, it causes postback, but the next focus is not on textbox2 as I want. The focus is on the page instead. Similarly with all the textboxes.
This Order page uses a master page.
Master page:
<form id = "form1" runat="server">
<asp:ScriptManager ID="ScriptManager1 " runat="server" />
Order page:
<asp:content id ="bodycontent" contentplaceholderID="maincontent" runat="server">
// 4 text boxes
</asp:content>
I cannot add another form or scriptmanager tag in the order page as it errors out saying there can be only instance of them.
So ,there is no FormOrder or ScriptManagerOrder in the Order page's code behind, but I would like to do something of the foll. way.
How can I do this.
protected void textbox1_TextChanged(object sender, EventArgs e)
{
//someFunction();
TextBox tb = (TextBox)FormOrder.FindControl("textbox2");
ScriptManagerOrder.SetFocus(tb);
}
Try this
protected void textbox1_TextChanged(object sender, EventArgs e)
{
//someFunction();
TextBox tb = (TextBox)FormOrder.FindControl("textbox2");
tb.focus();
}
Add following script in js file called i.e focus.js:
var lastFocusedControlId = "";
function focusHandler(e) {
document.activeElement = e.originalTarget;
}
function appInit() {
if (typeof(window.addEventListener) !== "undefined") {
window.addEventListener("focus", focusHandler, true);
}
Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(pageLoadingHandler);
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedHandler);
}
function pageLoadingHandler(sender, args) {
lastFocusedControlId = typeof(document.activeElement) === "undefined"
? "" : document.activeElement.id;
}
function focusControl(targetControl) {
if (Sys.Browser.agent === Sys.Browser.InternetExplorer) {
var focusTarget = targetControl;
if (focusTarget && (typeof(focusTarget.contentEditable) !== "undefined")) {
oldContentEditableSetting = focusTarget.contentEditable;
focusTarget.contentEditable = false;
}
else {
focusTarget = null;
}
targetControl.focus();
if (focusTarget) {
focusTarget.contentEditable = oldContentEditableSetting;
}
}
else {
targetControl.focus();
}
}
function pageLoadedHandler(sender, args) {
if (typeof(lastFocusedControlId) !== "undefined" && lastFocusedControlId != "") {
var newFocused = $get(lastFocusedControlId);
if (newFocused) {
focusControl(newFocused);
}
}
}
Sys.Application.add_init(appInit);
Reference it using Scriptmanager like below:
<ajax:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<ajax:ScriptReference Path="~/Js/FixFocus.js" />
</Scripts>
</ajax:ScriptManager>
For more information check out below link:
http://couldbedone.blogspot.in/2007/08/restoring-lost-focus-in-update-panel.html
It's not a good practice to use server-side controls for a Tab. Why don't you use some jQuery/Bootstrap?
With your current approach you use to many useless Posts/Postbacks overloading your server with a useless work.
I am new to ASP.NET.
I am experimenting with webforms. I have 2 pages: NewOrder.aspx which captures the user's order and then crossposts to SaveOrder.aspx where I want to save the order and display some information back to the user.
<telerik:RadButton ID="BtnSubmirOrder" runat="server" ButtonType="StandardButton" AutoPostBack="true"
Text="Place order" PostBackUrl="SaveOrder.aspx">
</telerik:RadButton>
When SaveOrder.aspx is loaded, the code below sets its control values and saves the order. however the browser stays at NewOrder.aspx.
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage==null || !PreviousPage.IsCrossPagePostBack)
Response.Redirect("~/Default.aspx");
var referencingPage = PreviousPage as NewOrder;
int id = Int32.Parse(referencingPage.SelectedPublicationId);
DateTime neededBy = referencingPage.SelectedOrderDate;
LblSummaryIsbn.Text = referencingPage.SelectedIsbn;
LblSummaryNbrCopies.Text = referencingPage.NbrOfOrderedCopies;
DateTime orderDate = DateTime.Now;
LblSummaryOrderDate.Text = orderDate.ToShortDateString();
LblSummaryTitle.Text = referencingPage.SelectedPublicationTitle;
int quantity = Int32.Parse(referencingPage.NbrOfOrderedCopies);
StockContainer _context = new StockContainer();
Order newOrder = Order.CreateOrder(orderDate, quantity, neededBy, id);
_context.Orders.AddObject(newOrder);
_context.SaveChanges();
}
I can see from the javascript that the form's action is set to SaveOrder.aspx when the button is clicked so why is the browser not displaying it?
I think the reason your browser is staying on NewOrder.aspx is that you don't have a button click event associated with your button. Without seeing the rest of your code, I'm not sure why the form's action appears different.
You could do something like the following to introduce a button click event. The redirect logic could go in there.
Markup:
<telerik:RadButton ID="btnSubmit" runat="server" Text="Place Order"
OnClick="btnSubmit_Click" />
Code:
public class NameOfPage
{
protected void btnSubmit_Click(object sender, EventArgs e)
{
// You could do validation here and display an error message if something is not right.
// For simplicity I am assuming the data comes from a set of textboxes.
if (!PageIsValid())
{
return;
}
StockContainer _context = new StockContainer();
Order newOrder = Order.CreateOrder(txtOrderDate.Text, txtQuantity.Text, txtNeededBy.Text, id);
_context.Orders.AddObject(newOrder);
_context.SaveChanges();
// Add your redirect logic here.
}
private bool PageIsValid()
{
if (string.IsNullOrEmpty(txtOrderDate.Text))
{
return false;
}
if (string.IsNullOrEmpty(txtQuantity.Text))
{
return false;
}
// and so on for the other fields that are required.
return true;
}
}
I am dynamically adding a custom user control to an update panel. My user control contains two dropdownlists and a textbox. When a control outside of the update panel triggers a postsback, I am re-adding the user control to the update panel.
The problem is...on postback when I re-add the user controls, it's firing the "SelectedIndexChanged" event of the dropdownlists inside the user control. Even if the selectedindex did not change since the last postback.
Any ideas?
I can post the code if necessary, but there's quite a bit in this particular scenario.
Thanks in advance!
EDIT...CODE ADDED BELOW
*.ASCX
<asp:DropDownList ID="ddlColumns" OnSelectedIndexChanged="ddlColumns_SelectedChanged" AppendDataBoundItems="true" AutoPostBack="true" runat="server">
*.ASCX.CS
List<dataColumnSpecs> dataColumns = new List<dataColumnSpecs>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
fillDDLColumns();
}
}
public void fillDataColumnsList()
{
dataColumns.Clear();
//COMMON GETDATATABLE RETURNS A DATA TABLE POPULATED WITH THE RESULTS FROM THE STORED PROC COMMAND
DataTable dt = common.getDataTable(storedProcs.SELECT_COLUMNS, new List<SqlParameter>());
foreach (DataRow dr in dt.Rows)
{
dataColumns.Add(new dataColumnSpecs(dr["columnName"].ToString(), dr["friendlyName"].ToString(), dr["dataType"].ToString(), (int)dr["dataSize"]));
}
}
public void fillDDLColumns()
{
fillDataColumnsList();
ddlColumns.Items.Clear();
foreach (dataColumnSpecs dcs in dataColumns)
{
ListItem li = new ListItem();
li.Text = dcs.friendlyName;
li.Value = dcs.columnName;
ddlColumns.Items.Add(li);
}
ddlColumns.Items.Insert(0, new ListItem(" -SELECT A COLUMN- ", ""));
ddlColumns.DataBind();
}
protected void ddlColumns_SelectedChanged(object sender, EventArgs e)
{
//THIS CODE IS BEING FIRED WHEN A BUTTON ON THE PARENT *.ASPX IS CLICKED
}
*.ASPX
<asp:UpdatePanel ID="upControls" runat="server">
<ContentTemplate>
<asp:Button ID="btnAddControl" runat="server" Text="+" OnClick="btnAddControl_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnGo" runat="server" Text="Go" OnClick="btnGo_Click" ValidationGroup="vgGo" />
<asp:GridView...
*.ASPX.CS
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
uc_Counter = 0;
addControl();
gridview_DataBind();
}
else
{
reloadControls();
}
}
protected void btnGo_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
//THIS BUTTON CLICK IS WHAT'S TRIGGERING THE
//SELECTEDINDEXCHANGED EVENT TO FIRE ON MY *.ASCX
gridview_DataBind();
}
}
private void reloadControls()
{
int count = this.uc_Counter;
for (int i = 0; i < count; i++)
{
Control myUserControl = Page.LoadControl("~/Controls/myUserControl.ascx");
myUserControl.ID = "scID_" + i;
upControls.ContentTemplateContainer.Controls.AddAt(i, myUserControl);
((customUserControl)myUserControl).fillDDLColumns();
}
}
private void addControl()
{
Control myUserControl = Page.LoadControl("~/Controls/myUserControl.ascx");
myUserControl.ID = "scID_" + uc_Counter.ToString();
upControls.ContentTemplateContainer.Controls.AddAt(upControls.ContentTemplateContainer.Controls.IndexOf(btnAddControl), myUserControl);
//((customUserControl)myUserControl).fillDDLColumns();
this.uc_Counter++;
}
protected int uc_Counter
{
get { return (int)ViewState["uc_Counter"]; }
set { ViewState["uc_Counter"] = value; }
}
Even though this is already answered I want to put an answer here since I've recently tangled with this problem and I couldn't find an answer anywhere that helped me but I did find a solution after a lot of digging into the code.
For me, the reason why this was happening was due to someone overwriting PageStatePersister to change how the viewstate hidden field is rendered. Why do that? I found my answer here.
One of the greatest problems when trying to optimize an ASP.NET page to be more search engine friendly is the view state hidden field. Most search engines give more score to the content of the firsts[sic] thousands of bytes of the document so if your first 2 KB are view state junk your pages are penalized. So the goal here is to move the view state data as down as possible.
What the code I encountered did was blank out the __VIEWSTATE hidden fields and create a view_state hidden field towards the bottom of the page. The problem with this is that it totally mucked up the viewstate and I was getting dropdownlists reported as being changed when they weren't, as well as having all dropdownlists going through the same handler on submit. It was a mess. My solution was to turn off this custom persister on this page only so I wouldn't have to compensate for all this weirdness.
protected override PageStatePersister PageStatePersister
{
get
{
if (LoginRedirectUrl == "/the_page_in_question.aspx")
{
return new HiddenFieldPageStatePersister(Page);
}
return new CustomPageStatePersister(this);
}
}
This allowed me to have my proper viewstate for the page I needed it on but kept the SEO code for the rest of the site. Hope this helps someone.
I found my answer in this post .net DropDownList gets cleared after postback
I changed my counter that I was storing in the viewstate to a session variable.
Then I moved my reloadControls() function from the Page_Load of the *.ASPX to the Page_Init.
The key was dynamically adding my user control in the Page_Init so it would be a member of the page before the Viewstate was applied to controls on the page.
I've been searching how to acomplish this but I have'nt been able to find a solution. I simplified the problem from my original project where I have to achieve this to the following:
In the .aspx I have:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="udpDynamicControls" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:PlaceHolder ID="PlaceHolder" runat="server">
</asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
And in code behind:
public partial class _Default : System.Web.UI.Page
{
protected string TextToShow
{
get
{
return Session["TextToShow"] == null ? "Original Text" :
Session["TextToShow"].ToString();
}
set { Session["TextToShow"] = value; }
}
protected void Page_Init(object sender, EventArgs e)
{
var lblToChange = new Label
{
ID = "lblToChange",
Text = TextToShow
};
var chkChangeText = new CheckBox
{
ID = "btnChangeText",
Text = "Change Text",
AutoPostBack = true
};
chkChangeText.CheckedChanged += ChkChangeTextClick;
PlaceHolder.Controls.Add(lblToChange);
PlaceHolder.Controls.Add(chkChangeText);
}
private void ChkChangeTextClick(object sender, EventArgs e)
{
var check = (CheckBox) sender;
TextToShow = check.Checked ? "Text Changed" : "Original Text";
udpDynamicControls.Update();
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
As you can see what i'm trying to do si to update the label when the check box is changed threw the update panel. But the udpDynamicControls.Update(); Doesnt fire the page_init event, where it would take its new value. I already checked out similar questions but I believe this is a diferent scenario.
I will be very thankfull to anybody that could help. I apologize for any bad english.
So I resolved my problem on my original project some other way, but I thought I might as well post the answer to what I did in case somebody has the same problem, the they might use the same solution.
Since I was depending on the page_init to run again after the update just to update the new value for my control and this wasn't happing, then a possible solution would be to update the value of the control in the check box changed event, where as the label is already created, and in the next page life cycle run, it would persist its value.
So the only thing I changed was the ChkChangeTextClick Event and the end result was:
protected void ChkChangeTextClick(object sender, EventArgs e)
{
var check = (CheckBox) sender;
TextToShow = check.Checked ? "Text Changed" : "Original Text";
((Label) PlaceHolder.FindControl("lblToChange")).Text = TextToShow;
}
Replacing:
udpDynamicControls.Update();
For:
((Label) PlaceHolder.FindControl("lblToChange")).Text = TextToShow;
Come to think about it, its a more simple approach, in my original project I have several dynamic controls and I just set a pattern in my controls ID to find the ones I need and change the values. The events of the controls don't get lost and I can show the updated information without the browser postback.
I hope this is of any help to anyone in the future, because I almost ripped all my hair out with this.
here is an example of what I am doing
Page Load
{
//Adds items to a panel (not an updatepanel just a normal panel control)
}
protected void btnNexMod_Click(object sender, EventArgs e)
{
// Calls DoWork() and Appends more items to the same panel
}
My problem is that the asp:button is doing a postback as well as calling DoWork()
Therefore, re-calling my page load, re-initializing my panel :(
I want my items that I have added to the panel to stay there!
All help appreciated, not looking for a hand you the answer kind-of deal. Any steps are appreciated thanks!
Here is an exact example of my problem.
protected void Page_Load(object sender, EventArgs e)
{
CheckBox chkbox = new CheckBox();
chkbox.Text = "hey";
chkbox.ID = "chk" + "hey";
// Add our checkbox to the panel
Panel1.Controls.Add(chkbox);
}
protected void Button1_Click(object sender, EventArgs e)
{
CheckBox chkbox = new CheckBox();
chkbox.Text = "hey";
chkbox.ID = "chk" + "hey";
// Add our checkbox to the panel
Panel1.Controls.Add(chkbox);
}
Only thing on the page is a empty panel and a button with this click even handler.
I have also tried this and it still doesn't work. Now its clearing the initial item appended to the panel.
if (!Page.IsPostBack) // to avoid reloading your control on postback
{
CheckBox chkbox = new CheckBox();
chkbox.Text = "Initial";
chkbox.ID = "chk" + "Initial";
// Add our checkbox to the panel
Panel1.Controls.Add(chkbox);
}
If you're adding controls to the Panel dynamically, then you'll have to recreate the controls at every postback, and make sure to assign the same IDs to the controls so that ViewState can populate the values. It's usually best to recreate dynamic content during OnInit, but this can be difficult in some situations.
One of my favorite tools is the DynamicControlsPlaceHolder, because you can add dynamic controls to it and it will persist them automagically, without any additional coding required on the page. Just add controls to it, and it will do the rest.
Here's the link:
http://www.denisbauer.com/Home/DynamicControlsPlaceholder
As for preventing your button from performing a postback, use OnClientClick and return false.
OnClientClick="return false;"
You could use
<asp:LinkButton OnClientClick="javascript:addItemsToPanel();return false;"
thus using a javascript function to add them. That's how I've got around that problem.
You can also try this:
Page Load
{
if (!this.IsPostBack) // to avoid reloading your control on postback
{
//Adds items to a panel (not an updatepanel just a normal panel control)
}
}
you can do like this...
ASPX code:
<asp:LinkButton ID="someID" runat="server" Text="clicky"></asp:LinkButton>
Code behind:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
someID.Attributes.Add("onClick", "return false;");
}
}
What renders as HTML is:
<a onclick="return false;" id="someID" href="javascript:__doPostBack('someID','')">clicky</a>
You are correct, you will have to add the new items to the Panel after a PostBack. That is the nature of the .NET pipeline.
If you use a data bound control, like a Repeater, to display the panel contents, then the button click handler just needs to rebind the control and it will all work out correctly.
Changing the asp:Button to a asp:LinkButton solved my issue.
I think, it is better use the Ajax Update panel. And put your button in to that.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button1" />
</ContentTemplate>
</asp:UpdatePanel>