Multiple User Control On Same Page And reference issue with Javascript - asp.net

I have one usercontrol which contain one textbox, few buttons and one calander.
I had place two instance of user control in one page as design time. It works fine all working from server side...mean server side events reference proper control at runtime.
Problem start after raising server side events from javascript. I succeed to fire proper event from javascript as per suggetion from other thread. Still I am not able to reference specific control at server side event. It always reference to control of last user control placed on page.
In my senerio I am firing calander's selected change event by buttons click event from javascript. The event fires as I want, but always it reference to last usercontrol's Calander.
Firing server side events from jabvascript is one step towards performance of user control.
Please suggest me.

On button click event call function of specific button and find calendar by id.

Related

Button in CustomControl added in OnClick doesn't postback until second click

I have the following scenario:
UserControlA contains a <asp:Button id="bSomeid" onClick="AddItem" /> with some code to an item to a shopping basket in AddItem.
UserControlB contains some LinkButton's that dynamically add a selection of UserControlA to the page in the OnClick event.
This is all done in an UpdatePanel. It is a little more complicated but I have pruned the information to what I believe is causing the problem, I will add more information if necessary.
The problem I have is that it takes 2 clicks for the AddItem event to trigger after I have added the items to the page after clicking the LinkButton.
I understand why this is happening - it is to late in the page cycle to register events for the next post back in the onclick - but can anyone think of a way around this? Can I force an event to be triggered on the next postback? I have tried to think of a way to run my code in page_load but I requuire access to the sender in the onClick.
Using .NET 4.0.
EDIT
I managed to find a way to get the link button sending the request in the Page_Load (using Request.Form["__EVENTTARGET"];) so I moved my code to the Page_load event. It still requires 2 clicks so I am assuming it isn't something to do with the onClick being registered to late.
Are there any other general things to check that could cause a button to require 2 clicks to post an event properly?
If your suspicion about being late in page life cycle is true then you can try using ScriptManager.RegisterAsyncPostBackControl method to register dynamically added controls in the link button click - considering that your button is within user control, you need to add public method into UserControlA that would actually register the button bSomeid1 and link button click from UserControlB would actually call the A control's method.
EDIT :
Another cause for button click not happening can be that button being dynamic control is not added in the page hierarchy when post-back happens (or it gets added very late in the page life cycle when the post back data is already processed). A really full-proof solution should add dynamic controls back to the page hierarchy in page_load it-self (and strictly maintaining same controls ids within hierarchy). If that's not possible then you can sniff the request (Request.Form) to detect the post-back.
In your case, you should ascertain if the button is indeed causing the post-back on each click. If yes, what is the POST data (Request.Form) for the first request - what is the __EVENTTARGET value on the first click (and post-back)? That should start your trouble-shooting.
On the other hand, a simple work-around could be to use html anchor element (you can still use link button) and have a javascript handler in the click event that would set some hidden variable and then submit the form (you can simulate the click on hidden button to trigger ASP.NET client side submit pipeline) . Now the hidden variable value can be used on the post-back to determine which link button has been clicked.
"Are there any other general things to check that could cause a button to require 2 clicks to post an event properly?"
Does it require two clicks on the control, or does it take accept a single click elsewhere on the screen, and then fire first time with a single click on the control?
I have my own (similar) issue with the Updatepanel where the first (expected) trigger does not fire and it seems that a single click elsewhere, and then the subsequent triggers fires first time (which totals 2 clicks)
[edit] Since you are working on this ATM, it may help me as well. Do you have a textbox with a trigger event on it? I do, and if I leave this blank (so that it does not fire) then there is no need for a second click.

Why event bubbling and why not directly subscribe the click event?

I was going through an article on event bubbling in asp.net and came to know that although it is possible to subscribe to the click event of a user control's button from the containing page, "doing so would break some of the object oriented rules of encapsulation". A better idea is to publish an event in the user control to allow any interested parties to handle the event.
My question is that exactly how does a direct subscription to the button's click event from a containing page would break the object oriented rules of encapsulation?
Apologies if its a dumb question. :|
Thanks!
The Button is supposed to be encapsulated by the UserControl.
If the Page binds directly to events on the button, then the page is now dependent on the inner workings of the UserControl.
The Page should be consuming the UserControl, not the UserControl's button. If the author of the UserControl later wants to remove the button and use some fancy new method of firing its "Submit" event, your page could be broken because the button may no longer exist.
For that matter, if the owner of the UserControl decides in v1.1 to rename the button from btnSubmit to SubmissionButton, it could break your page, as well.
Better to consume the UserControl and let it be concerned with its own inner workings.
The idea is that the button of the control is an implementation detail of the UI of the control. If you republish the click event you could reimplement that button as an ImageButton, LinkButton, etc.
I think it's OK to attach an event handler at the page level to the button if the button is a permanent fixture of the UI. It saves a lot of event code, especially with a lot of buttons.

Please help me understand AutoPostBack property of an ASP.NET control

I'm learning about ASP.NET, mainly by following through a book, but also making an effort to actually do things along the way. But, I came across an explanation about list controls which I don't understand. This is what it says:
"[in the context of the Smart Tasks panel]...the last option sets the AutoPostBack property of the control. With this option checked, the control will submit the page it's contained in back to the server as soon as the user chooses a new item from the list"
Can you explain this statement for me? Thanks in advance for your help.
For normal client controls (such as a list control with AutoPostBack set to false), when a user chooses an item in the list, the browser does not communicate with the server. There's no network traffic and no delay for your user before they see the results of the choice, but there's also no opportunity to do anything in your server code, like calculate dependent values. If you want to do anything to the screen in response to the choice, you have to use a client-side script.
When AutoPostBack is set to true, selecting an item in the list sends a message to the server (via an HTTP POST). ASP.NET then executes whatever code you have attached to the list's changed event, rebuilds the page, and sends the revised page to the client.
If you set AutoPostBack="true" on a control, when it's value changes, it will automatically postback to the server.
For example if you wanted a dropdown that when changed displayed different data in a table below or something, you might want to postback get the new value so your page could refresh the data.
This is opposed to style of the dropdown and a button beside it you click to postback, so instead of change value, click the button, you can just change the value with AutoPostBack="true".
A ListBox has a SelectedIndexChanged event that you can handle to detect when the selected item in a ListBox has changed. You'd configure it like this:
<asp:ListBox ID="ListBox1" runat="server" OnSelectedIndexChanged="ListBox1_SelectedIndexChanged"/>
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// Do something
}
With AutoPostBack="false" (the default), that event handler doesn't actually happen on the server in "real time". The user has to perform an unrelated action to submit (POST) the form, such as clicking a button, to make that event fire on the server.
If you want to take "real time" action on that event, you set AutoPostBack="true" which makes the form automatically submit every time the selected item is changed.
The benefit - you get "real time" notification of events. The drawback - the page talks a lot more to the server, so each click costs bandwidth and causes client "lag".
Further reading: http://www.dotnetspider.com/resources/189-AutoPostBack-What-How-works.aspx
When a user selects a ListItem (or whatever the collection item is), the page should automatically submit the web form to the server with a POST event.
here's the wikipedia page on HTTP POST events
http://en.wikipedia.org/wiki/HTTP_POST
The responsibility of an asp.net control contained in a Page is to render a part of the html that the user will end up seeing in his browser. Some controls support the AutoPostBack property. What it does is that it makes the control emit some extra javascript that will submit the form whenever the value of that control is changed, so that you can react to this on the server side.
Basically AutoPostBack is used so that whenever there is some change in the controls text or anyother change in the controls property, the page is submitted to the server.
Posting the page means, the page is submitted to the server. Suppose i use a textbox and i make its AutoPostBack = "true", now i write some text into it and click outside the textbox, then the page will refresh.
This refresh indicates that your value which you entered into the textbox has been submitted to the server.
The postback is handled by ASP.NET server. AutoPostBack will automatically post back your page to the server.
Add an event Handler. This will give you a better picture.
In your case of DropDownList: Add an eventhandler: double click the DropDownList, it will route you to an eventhandler:
Write something in that event handler let us say : Response.Write("message");
The page will refresh and you will see your message, this means the page was posted to the server and the server has executed your event handler and displayed you the message.
I hope this was usefull

ASP.NET Dynamic Page Controls: Is it possible to bind events AFTER Page.Load?

I have a site that I am currently working on in ASP.NET 2.0 using the usual WebForm stuff and ASP.NET AJAX 1.0. Is it possible to bind an event to a dynamically created control after the Page.Load event?
I have a table <td> element that I am dynamically creating similarly to this code:
' Create Link Button
lnk.ID = String.Format("lnkDetails_{0}", dr("Id"))
lnk.Text = dr("Name").ToString()
lnk.CommandArgument = dr("Id").ToString()
AddHandler lnk.Click, AddressOf DetailsLink_Click
cName.Controls.Add(lnk)
This this code is looped over for each row in a database (and of course more cells are added to the table, including an ImageButton with an event. The events work flawlessly when I execute this code during events leading up to and including Page.Load. I need to be able to fill this table with current data, which is updated during a btnClick Event elsewhere on the page, which occurs after this Page_Load event, so I am populating with old data. If I change this code to Page.LoadComplete, events stop working.
This data is a summary display of various components of an application, things like somebody's name, which when updated on a 'detail' form, updates the database by partial postback (a requirement), then it needs to show the update in this 'summary' section after an update. Currently it takes 2 postbacks to actually see the change in the 'summary' section, so effectively the summary is 1 step behind the changes (clear as mud?)
What would be the best way for me to populate this table with current data (which is available during/after Page.LoadComplete), but still have an event fire when a link is clicked (the event causes an UpdatePanel to display the 'detail' form).
I also have jQuery at my disposal and the usual ASP.NET AJAX methods, also javascript is a requirement for the website, so I do not need to degrade for unsupported browsers.
This is my first ASP.NET web application and need some help figuring out the best way to make this happen (I'm well versed in PHP, Django and the usual ways to do web forms - things like having multiple forms on one page o_O).
Update:
There really isn't a good way to bind control events to controls after Page_Load. The overall architecture of the pages is there is one ASP.NET form encompassing the entire page, there is only 1 aspx page. I am using master pages (however it doesn't have any obvious implications to my issue).
The page is split into a left and right 'pane', the left is a summary of all the data (in an update panel), the right 'pane' has 6 'tabs' implemented each as their own user control, each with several form fields and an update button all in it's own UpdatePanel.
An update on any of these tabs only refreshes the summary panel (UpdatePanel.update()) and its own panel. The 'refreshing' and event binding of dynamic controls of the summary from the db happens during Page_Load and the Update Button event updates db data. (The control event happens after Page_Load). I want to avoid doing a double post to get the summary to update, any thoughts are helpful.
You need to postback the whole page after your data changes in the 'btnClick Event elsewhere on the page'. It sounds like you have an UpdatePanel and it sounds like this is catching the postback of your btnClick event handler. Put the btnClick outside the UpdatePanel or change its triggers so that your btnClick forces a postback/refresh of your data. Or, redesign your table so it's AJAXly-refreshed when you click on btnClick, it's hard to get you more details without knowing more about the structure of your page and controls.
Good luck!
You can bind to an event whenever you want. It's just a simple event after all. But not all places might be suitable because you have to take into account when the event fires. And in most cases this happens between Page_Load and Page_PreRender. That includes the click event on a LinkButton. In general, I would recommend to add your dynamically created controls in the Page_Init stage.
You have to add the controls before Page.Load in order to maintain ViewState between postbacks, so use the OnInit event handler for that.
But once they're added, you should be able to bind event handlers (such as OnClick) at any point during or after the Page.Load... for example in your grid's ItemDataBound (or something like) or in the Page.PreRender.

Can't get my event to fire

When loading a page for the first time (!IsPostback), I am creating a button in code and adding it to my page, then adding an event handler to the click event.
However, when clicking the button, after the page reloads, my event handler does not fire.
Can anyone explain why?
#Brad: Your answer isn't complete; he's most likely doing it too late in the page lifecycle, during the Page_Load event.
Okay, here's what you're missing.
ASP.NET is stateless. That means, after your page is rendered and sent to the browser, the page object and everything on it is destroyed. There is no link that remains on the server between that page and what is on the user's browser.
When the user clicks a button, that event is sent back to the server, along with other information, like the hidden viewstate field.
On the server side, ASP.NET determines what page handles the request, and rebuilds the page from scratch. New instances of server controls are created and linked together according to the .aspx page. Once it is reassembled, the postback data is evaluated. The viewstate is used to populate controls, and events are fired.
This all happens in a specific order, called the Page Lifecycle. In order to do more complex things in ASP.NET, such as creating dynamic controls and adding them to the web page at runtime, you MUST understand the page lifecycle.
With your issue, you must create that button every single time that page loads. In addition, you must create that button BEFORE events are fired on the page. Control events fire between Page_Load and Page_LoadComplete.
You want your controls loaded before ViewState information is parsed and added to controls, and before control events fire, so you need to handle the PreInit event and add your button at that point. Again, you must do this EVERY TIME the page is loaded.
One last note; page event handling is a bit odd in ASP.NET because the events are autowired up. Note the Load event handler is called Page_Load...
You need to add the button always not just for non-postbacks.
If you are not reattaching the event handler on every postback, then the event will not exist for the button. You need top make sure the event handler is attached every time the page is refreshed. So, here is the order of events for your page:
Page is created with button and event handler is attached
Button is clicked, causing a postback
On postback, the page_load event skips the attaching of the event handler becaue of your !IsPostback statement
At this point, there is no event handler for the button, so clicking it will not fire your event
That is because the event binding that happens needs to be translated in to HTML. This postback that happens if bound to the page between OnInit and OnLoad. So if you want the button to bind events correclty make sure you do the work in OnInit.
See the Page Life Cycle explaination.
http://msdn.microsoft.com/en-us/library/ms178472.aspx

Resources