I have the following code inside the CS file of the page, i am trying to add an html button inside a div in the server side to close the alert modal dialog.
When I add the event to the button and try to fire it. The event doesn't fires.
So, where is the problem ?
public Alert(HtmlGenericControl alert ,string alertMessage)
{
vAlert = alert;
alert.Attributes.Add("class", "uk-modal");
alert.Attributes.Add("aria-hidden", "true");
alert.Attributes.Add("style", "display: none; overflow-y: scroll;");
HtmlGenericControl innerDiv = new HtmlGenericControl();
innerDiv.TagName = "div";
innerDiv.Attributes.Add("class", "uk-modal-dialog");
innerDiv.Attributes.Add("style", "top: 35.5px;text-align:center; padding:30px;");
HtmlInputButton btnclose = new HtmlInputButton();
btnclose.Attributes.Add("type", "button");
btnclose.Attributes.Add("id", "alert_close");
btnclose.Attributes.Add("runat", "server");
btnclose.Attributes.Add("class", "uk-modal-close uk-close");
btnclose.Attributes.Add("style", "padding:15px;");
btnclose.ServerClick += new EventHandler(btnclose_ServerClick);
innerDiv.Controls.Add(btnclose);
HtmlGenericControl p = new HtmlGenericControl();
p.TagName = "p";
p.InnerText = alertMessage;
innerDiv.Controls.Add(p);
alert.Controls.Add(innerDiv);
ShowAlert(alert);
}
private void btnclose_ServerClick(object sender, EventArgs e)
{
HideAlert(vAlert);
}
Can you help me ?
The button probably doesn't exist at the time when the server callback is executing.
You are using a dynamically created button. In order for it to be able to trigger a server side method, the button needs to be added and have it's event handler bound in an early stage of the page life cycle, such as On_Init.
We don't know when you call your "Alert" method, but it might very well too late. It also needs to be called on every postback - or the link between button and handler won't be there when the button causes a postback.
Related
ASP.NET 4.7.2 Web Forms c# VS 2019
I am trying to use a modalpopupextender to prompt for new data for foreign key fields. Like the form itself, the MPE is built on the fly in code -- in this case the click handler for the hidden button that the Javascript fires off to build and show the MPE.
I read every single article on SO and the ASP forums and tried everything I saw there. No joy. I get the popup perfectly. Hitting OK closes the popup, but never fires the OK Event.
Here is the code:
//Building the form, we do this in OnInit:
// AJAX Update Panel
UpdatePanel PUP = new UpdatePanel()
{
ID = "PUP",
};
PlaceHolder.Controls.Add(PUP);
// HiddenField containing the field name to permit
// creating the correct modalpopup.
HiddenField HFPopupField = new HiddenField()
{
ID = "HF_POPUP"
};
PUP.ContentTemplateContainer.Controls.Add(HFPopupField);
// Create Hidden button to track the popup
Button BPopup = new Button()
{
ID = "BPOPUP",
UseSubmitBehavior = false
};
BPopup.Click += BPopup_Click;
BPopup.Attributes.Add("style", "display: none;");
PUP.ContentTemplateContainer.Controls.Add(BPopup);
// And create the background panel for the popup.
Panel PnlPopup = new Panel()
{
ID = "PNLPOPUP",
CssClass = "MpeBackground"
};
PnlPopup.Attributes.Add("style", "display: none;");
PUP.ContentTemplateContainer.Controls.Add(PnlPopup);
/// Event handler for hidden button.
protected void BPopup_Click(object sender, EventArgs e)
{
[snip -- code to get the dataset that is being filled]
UpdatePanel PUP = Placeholder.FindControlRecursive("PUP");
Table T = new Table()
{
CssClass = "PopupTbl"
};
TableRow TRTitle = new TableRow();
TableCell TCTitle = new TableCell()
{
CssClass = "PopupTitle",
ColumnSpan = 2
};
Label LPopTitle = new Label()
{
Text = [title of the popup]
};
TCTitle.Controls.Add(LPopTitle);
TRTitle.Cells.Add(TCTitle);
DataRow drData = null;
// Add Fields, and also the cancel and Add buttons
foreach (DataColumn DC in dsColumns.Tables[0].Columns)
{
TableRow TRColumn = [create a tablerow with 2 columns, a prompt and the input field]
if (TRColumn != null)
{
T.Rows.Add(TRColumn);
[snip]
}
} // end of foreach(DataColumn DC in dsColumns.Tables[0].Columns)
PnlWindow.Controls.Add(T);
TableRow TRButtons = new TableRow();
TableCell TCButtons = new TableCell()
{
ColumnSpan = 2,
CssClass="PopupButtons"
};
Button MPEBOK = new Button()
{
ID = "MPE" + sFieldName + "_MPEBOK",
Text = "OK",
CausesValidation = false,
UseSubmitBehavior = false
};
MPEBOK.Click += MPEBOK_Clicked;
TCButtons.Controls.Add(MPEBOK);
LiteralControl LCB = new LiteralControl()
{
Text = " "
};
TCButtons.Controls.Add(LCB);
//************************************************************
//*** Postback Trigger ***
//************************************************************
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger()
{
ControlID = MPEBOK.ID,
EventName = "click"
};
PUP.Triggers.Add(trigger);
//************************************************************
//*** Cancel Button ***
//************************************************************
Button MPEBuhBye = new Button()
{
ID = "MPE" + sFieldName + "_BUHBYE",
Text = "Cancel",
UseSubmitBehavior = false
};
TCButtons.Controls.Add(MPEBuhBye);
TRButtons.Cells.Add(TCButtons);
T.Rows.Add(TRButtons);
PnlPopup.Controls.Add(PnlWindow);
AjaxControlToolkit.ModalPopupExtender MPE = new AjaxControlToolkit.ModalPopupExtender()
{
ID = "MPE" + sFieldName,
PopupControlID = "PNLPOPUP",
TargetControlID = "BPOPUP",
BackgroundCssClass = "MpeBackground"
};
// Add the MPE to the UpdatePanel.
PUP.ContentTemplateContainer.Controls.Add(MPE);
// Show the modal popup extender.
MPE.Show();
}
protected void MPEBOK_Clicked(object sender, EventArgs e)
{
[snip - this never fires]
}
I cannot find out what is happening here. Can anyone see something hinky?
Thanks
John.
You can't add a server side button or inject a server side button into the page DOM.
When you drag a asp.net button onto the form, BOTH the "mypage.cs" and mypage.desinger.cs ARE updated. The wire up of the button occurs at design time, and you would have to modify mypage.desinger.cs ALSO and ADD a button event stub.
So you can't do this.
A compromise would be to also add some js and have that HTML button execute a .click() method of a hidden asp.net button you drop into that page (that would give you the post back, and the running behind of a separate button event code stub.
This event resolution occurs at compile time - not at page render time. You have to drop that button onto the page.
I suppose you could adopt a standard that you always place right below that "div" on the page the button (hidden with style=none. And then as noted, have your injected code along with some js execute a click on the hidden button. Or just have the js button code execute a __doPostback("some value") and pick this up in the page on-load event, and then call the routine (function) from on-page load event.
I think better would be to use a jQuery.UI dialog, as that dialog CAN say load + use another different web page into a “div” on the existing page. So you layout, make, and create the nice looking popup form as a separate web page. jQuery is able to remove the “form” and additonal tags out of that page load, and then inject it into the existing page. (that code would be rather hard to re-produce). so jQuery.UI is able to pop up that separate page. however, the buttons on that loaded page (into that div) of course can't really run any code behind in the current page. However, the buttons CAN run local js in the current page. Thus the actions of this injected page would be local to each page. But the popup would not be directly calling a code behind stub.
Now, to adopt jQuery.UI, then you also have to of course adopt jQuery. So that is two extra libraries you need. (but, jQuery you likely already have).
However, I suppose the whole point of using the ajax toolkit is to avoid jQuery.ui in the first place. To be fair, before jQuery.ui came along, that tool kit was REALLY impressive, and gave asp.net folks a REAL leg up on the competition. (and it tends to be MUCH less wiring up then say using jQuery.UI
So the AjaxToolkit in its heyday was impressive. Now, it of course showing its age, but I still use the kit, and this is especially the case for the AjaxFileUploader. And yes I do use the popups – even to this day. However, I find now that jQuery.UI dialogs are more flexible, and would be better in this case (because you want a on-the fly setup).
Also, having code behind buttons in even the jQuery.UI dialog, or in this case the ajax popup? Well, only the action button can run code behind. The cancel button of course will just dismiss the dialog. However, any button in the dialog that WILL run code behind? Well, that's ok, since you have a page post back, and it actually the page postback that BLOWS out the dialog anyway.
I'm trying to call events of dynamically created buttons sending parameters, but when I click nothing happens, just Post Back the page.
public void adicionarComanda()
{
List<Comanda> lc = ControllerComanda.getComanda();
foreach (Comanda comanda in lc)
{
Button bt = new Button();
bt.Text = comanda.nome_Pessoa;
bt.CssClass = "botoes";
bt.Click += btnNome1_Click;
bt.CommandArgument = comanda.nome_Pessoa;
HtmlGenericControl li = new HtmlGenericControl("li");
li.Controls.Add(bt);
ulBotoes.Controls.Add(li);
}
}
And the Event
protected void btnNome1_Click(object sender, EventArgs e)
{
string nomePessoa = (sender as Button).CommandArgument;
Session["currentUser"] = nomePessoa.ToString();
Response.Redirect("~/Mobile/Pages/produtosCategoria.aspx");
}
But nothing Happens when I click the button, just PostBack the page. How can I fix this problem?
Thank you guys
You need to re-render all dynamically generated controls on every postback. I suggest creating a method that generates the these controls then call that method on every postback in Page_Load.
Have you thought about maybe passing "currentuser" as a parameter? bt.Attributes.Add("onclick", "javascript:redirect('~/Mobile/Pages/produtosCategoria.aspx?name=comanda.nome_Pessoa')";
Instead of defining click function you can use another approach - PostBackUrl.
public void adicionarComanda()
{
List<Comanda> lc = ControllerComanda.getComanda();
foreach (Comanda comanda in lc)
{
Button bt = new Button();
bt.Text = comanda.nome_Pessoa;
bt.CssClass = "botoes";
bt.PostBackUrl = String.Format("~/Mobile/Pages/produtosCategoria.aspx?user={0}", comanda.nome_Pessoa);
HtmlGenericControl li = new HtmlGenericControl("li");
li.Controls.Add(bt);
ulBotoes.Controls.Add(li);
}
}
Then in the redirected page you can use Request.QueryString["user"] , and use it as required.
I want to use information on which control was clicked for setting up the page. I use this to set up a sortable table in code. I found through this forum that I can use Request.Form.Get("__EVENTTARGET") for that. However, as soon as I do something with that parameter, the callback function is no longer called. Is this expected behavior or am I making a mistake?
Here some snippets of my code. The code in Page_Load() is:
string sortRequest = Request.Form.Get("__EVENTTARGET");
bool isCurrentField = false;
if (sortRequest != null) isCurrentField = sortRequest.Contains(header.Field);
if (!isCurrentField)
{
// Add a hyperlink for sorting to the cell
LinkButton newLink = new LinkButton();
newLink.Text = header.Title;
newLink.Font.Bold = true;
newLink.ID = "link" + header.Field;
newLink.CommandName = "Sort";
newLink.CommandArgument = header.Field;
newLink.Command += new CommandEventHandler(LinkButton_Command);
hdrCell.Controls.Add(newLink);
}
else
{
hdrCell.Text = header.Title;
hdrCell.Font.Bold = true;
}
My callback:
public void LinkButton_Command(Object sender, CommandEventArgs e)
{
_sortOrder = e.CommandArgument.ToString();
}
I have also tried it with copying the sortRequest into a temporary variable, but that doesn't make a difference. As soon as I comment out the line if (sortRequest != null) isCurrentField = sortRequest.Contains(header.Field);, the callback is called again.
There is a fault in your logic. You have a dynamically created control LinkButton with LinkButton_Command event handler connected to it. For the server-side event to fire on postback, the control must be present in the page control tree. This means the dynamic LinkButton must be created, configured and added to hdrCell.Controls always, regardless of sortRequest value. Only then will it be able to pick up the fact that it was clicked from the Request and fire its Command event.
I've create a dashboard that contains multiple dynamic buttons. When I click the "Delete" button I want the server side code to execute. I've added the code to the Click event handler of my button.
The dynamic button is created with the following code:
Button PopupDeleteButton = new Button();
PopupDeleteButton.ID = "PBD" + controlValue.ID.ToString();
PopupDeleteButton.Text = "Delete";
PopupDeleteButton.Style["Height"] = "15px";
PopupDeleteButton.Style["Width"] = "50px";
PopupDeleteButton.Style["top"] = "0";
PopupDeleteButton.Style["right"] = "0";
PopupDeleteButton.Style["float"] = "left";
PopupDeleteButton.Style["font-size"] = "9px";
PopupDeleteButton.Style.Add(HtmlTextWriterStyle.VerticalAlign, "top");
PopupDeleteButton.Attributes.Add("runat","server");
PopupDeleteButton.Click += new EventHandler(this.RemoveWidgetFromXML_Click);
However when the I click the dynamic button on the form a post back occurs, and the function RemoveWidgetFromXML is never called. Any ideas? I've looked all over Google but can't find how to stop the post-back from occurring prior to the event call.
You have to recreate dynamic control on every page postback. In that case event handler will be called.
I want to create dynamic buttons on button click event(for example., btnCreateDynamic_Click).
I tried creating dynamic buttons on page_load event and Pre_int event.They are all working but i want to create them in button click event. How can i do this in c# asp.net?
Your button click event at the client will cause a page postback that will start the ASP.Net Page Life-cycle;
Your button click event on the server is a PostBackEvent and you should be able to use the same method call CreateMyButton() that you used in the Load or Init events.
An idea would be to create a list of buttons in which you'd store the buttons you created in btnCreateDynamic_click.
you could have a method like:
private Button CreateButton(string id, string name)
{
Button b = new Button();
b.Text = name;
b.ID = id;
b.Click += new EventHandler(Button_Click);
b.OnClientClick = "ButtonClick('" + b.ClientID + "')";
return b;
}
in btnCreateDynamic_click you could have something like:
Button b = CreateButton("dinamicBtn"+myDinamicButtonsList.Count.ToString(),"dinamicBtn"+myDinamicButtonsList.Count.ToString());
myDinamicButtonsList.add(b);
and in the pageLoad for example you could do something like
foreach(button btn in myDinamicButtonsList){
form1.Controls.Add(btn));
}
List<Button> myDinamicButtonsList = new List<Button>();
myDinamicButtonsList should be stored somewhere from where it could be retrieved after each request.
EDIT:
In page load you could have something like this:
if(Session["myDinamicButtons"] == null){
List<Button> myDinamicButtonsList = new List<Button>();
Session["myDinamicButtons"] = myDinamicButtonsList;
}
foreach(Button btn in Session["myDinamicButtons"] as List<Button>){
form1.Controls.Add(btn));
}
i didn't tested it but it should work.