Showing posts with label triggers. Show all posts
Showing posts with label triggers. Show all posts

Monday, March 26, 2012

Trigger a panel refresh from javascript/pure html control

Hi,

I have a pure HTML tree control, that is outside of an ajax UpdatePanel. I want to write a JS function that triggers a particular panel to refresh, *as if* I hit a submit button inside of the panel. I don't want to put the HTML tree control inside an Ajax panel, as it will loose it's state (it will return to a completely collapsed state).

Putting a button inside the panel, and then running the JSelement.click() event from my tree control works in IE, but Firefox submits the entire page(the submit event is not captured by the AJAX framework in FF in this case,apparently).

I have looked into the client reference documentation at http://ajax.asp.net/docs/ClientReference/Global/default.aspx, and it seems like there should be a way to trigger a postback/panel refresh, but I have not found a way.

The PageRequestManager does not help, since it only monitors existing page requests. I need to invoke a page request, and run something like

PageRequest.Invoke('MyUpdatePanel');

or

var ajaxpanel = document.getElementById('AjaxPanelClientID');
ajaxpanel.update();

A related suggestion:

It would be nice if the UpdatePanel supported client side triggers, not just server side triggers. Consider the following hypothetical code:

<ajax:UpdatePanel ID="ajxUpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<!-- CONTENT -->
</ContentTemplate>
<Triggers >
<ajax:AsyncPostBackTrigger ClientTriggerFunction="MyCustomTrigger" OnTrigger="MyCustomTrigger_ontrigger" />
</Triggers>
</ajax:UpdatePanel>

Then the system would automatically generate the JS function (with the appropriate .NET ajax framework calls that I don't need to know about), so I can call it anywhere on the page, from multiple HTML controls if needed.

<input type="button" value="MyHTMLButton" onclick="MyCustomTrigger('argstring');">

The system should enable a code-behind event handler where I can put my server side code:

protected void MyCustomTrigger_ontrigger(object sender, AjaxClientTriggerEventArgs e) {
//run some server side .NET code here
switch(e.ClientArgString){
...
}
}


You can trigger an asynchronous post back by invoking the __doPostBack function. Just pass in the ID of the control that's either inside an update panel or is marked as a trigger for one. Here's an example:

<asp:UpdatePanel ID="up" runat="server">
<ContentTemplate>
<asp:Button ID="myButton" runat="server" OnClick="myButton_Click" Text="Click me!" />
<asp:Label ID="myLabel" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<input id="myOtherButton" type="button" value="No, click me!" />
<script type="text/javascript">
function pageLoad() {
$addHandler($get('myOtherButton'), 'click', triggerAsyncPostBack);
}
function triggerAsyncPostBack(e) {
__doPostBack('<%= myButton.UniqueID%>', '');
}
</script>

One thing to watch out for is that the first parameter to __doPostBack needs to be the full ID of the control. If you're using master pages, your control IDs will be longer than they appear. Use the UniqueID property to get the full ID or the event handlers for your control won't run on the server.

Also, if you have event validation turned on (the default), you'll get an exception if you don't pass in a correct event argument as the second parameter to __doPostBack. For button controls, it should be the empty string. For other controls, it might be different, but you'll have to experiment to find out.

Hope this helps.


Thank you Jason,

That is the behaviour I was looking for, and it works in Firefox as well as IE. I knew about the _doPostBack function in general, but I did not know the syntax to call it.

Where is the best place to find documentation and syntax for the built-in ASP.NET and AJAX JS functions and calls? For example, I did not know about $get or $addHandler functions.

(I am familiar with similar functions from the prototype.js library).

Thanks again :-)


Another related discovery that is slightly more elegant (I am probably repeating what some already know...but I think its great :-)

Is is not necessary to use a button to trigger the post back inside the panel. I updated a hidden input field with a value, and then submitted thehidden field iteself with __doPostBack, and it worked great. I needed a hidden field to pass in a unique ID anyway, so the panel would know how to refresh itself.

Inside the UpdatePanel:

<input id="txtGroupID" type="hidden" runat="server" onserverchange="txtGroupID_ServerChange" />

JS code:

txt = $get("<%=this.txtGroupID.ClientID %>");
txt.value = somevalue;
__doPostBack("<%=this.txtMatGroupID.UniqueID %>","");



Douglas Smith:

Where is the best place to find documentation and syntax for the built-in ASP.NET and AJAX JS functions and calls? For example, I did not know about $get or $addHandler functions.

The ASP.NET AJAX documentation does document all of these functions. You'd have to know where to look, though. All of the $-prefixed functions seem to be documented in the Sys.UI namespace here:

http://ajax.asp.net/docs/ClientReference/Sys.UI/default.aspx

Browsing through the source code helps find the undocumented stuff.


That will trigger an asynchronous post back, but no event will be raised on the server with that control as the target. You probably want to execute some code to modify the controls inside the update panel or there'd be little point in triggering the asynchronous post back. That's why I used a button control in the example I gave you. If all you want to do is trigger the asynchronous post back and don't care about raising a specific event on the server, you could use the ID of the update panel control as the event target. To me, that would be stating the intention of what you're trying to do a little clearer.

If you don't want to use a button but do want to raise an event on the server, you can use any control that implements IPostBackEventHandler as the event target. Those controls have a RaisePostBackEvent method that gets invoked when a post back is received with their ID as the event target. For button controls, they raise their Click event in that method. That's where your code gets to do its stuff. You could easily create an "empty" custom control that didn't render anything, but could be used as the event target. (I tried using the page control for this, but there's code that prevents you from registering the page as an asynchronous post back trigger.)

It'd be nice if the UpdatePanel control itself implemented IPostBackEventHandler and raised some sort of custom event on the server that let you do this without having to write much custom code. You could simulate this a bit by putting some code inside one of the event handlers on your page and checking to see if the ScriptManager control's AsyncPostBackSourceElementID is the ID of the UpdatePanel control you used as the event target. If so, execute your custom code.

Hope this helps.

trigger is causing the user controls OnInit to fire

I have a TextBox inside an UserControl which triggers an update panel on TextChanged. Works really well, but I noticed a problem. When AJAX makes the call back to the server to execute the TextChanged event, it is actually firing the UserControl's overridden OnInit beforehand. Is this normal behavior? I would think that for a page, OnInit should only get called once - when the page is created. There is a good deal of initialization code in my OnInit that really should not be executed again if it does not have to. Is there a way to make the UpdatePanel trigger not fire OnInit?

AJAX postbacks are executed at the server like normal postbacks (the entire page lifecycle is processed from the beginning), so Page.IsPostback = True for AJAX postbacks.

Saturday, March 24, 2012

Triggering partial update on text box losing focus

Hi,

I have a form on which I want a user to be able to enter a post code and, when the user tabs out of the field, triggers the population of a drop down list which contains the suburbs the postcode relates to, so the user can then select the suburb.

I have the drop down list in an Update Panel with partial rendering turned on but I can't figure out how to trigger it being refreshed when the control loses focus. I think I need to link it to the OnBlur event using javascript but I'm stuck at that point. Any ideas appreciated...

Thanks,

SimonOK, it was me being dippy. I didn't need to get clever and start hooking client side events, I just needed to set the Render property to "Always" and it fires whenever the text box loses focus.

S

Triggering Update Panel from Dynamically Built Triggers

I have a page which has two content areas (Left, Center). The Left hand content contains two repeaters, both of which have an imagebutton who's itemcommand triggers an update of the content in the Center area. The Center Area has an update panel in it. The triggers are dynamically generated because the repeaters are in panels, and I needed to use the findcontrol() command to get access to them.

Code works great on my laptop (localhost), gives an error when I move it to the server. Error is:

Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing this request on the server. The status code returned from the server was: 500.

Here's my UpdatePanel:

<asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Repeater ID="rMain" DataSourceID="srcMain" OnItemCommand="rmain_itemCommand" runat="server"> <ItemTemplate> <asp:Label ID="lblTitle" Text='<%#Eval("Description")%>' runat="server" CssClass="verorangeHeader" /><asp:Label ID="ProductID" runat="server" Text='<%# Eval("idProduct") %>' Visible="false"></asp:Label><asp:Label ID="lblSKU" runat="server" Text='<%# Eval("Sku") %>' Visible="False" /><br /><br /> <table border="0" cellpadding="1" cellspacing="1"> <tr> <td > <asp:Label ID="lblDetails" Text='<%#Eval("Details")%>' runat="server" CssClass="ver11bluebold" /> </td> <td ><img src='<%# formatPhoto(Eval("ImageURL")) %>' /></td> </tr> <tr> <td colspan="2" align="right" valign="top">Priced from: <asp:Label ID="lblPrice" Text='<%# formatPrice(Eval("Price")) %>' runat="server" CssClass="verorange" />   <asp:ImageButton ID="btnSpecifications" ImageURL="images/btn_specifications.gif" runat="server" /><asp:ImageButton ID="btnPhotoGallery" ImageURL="images/btn_photo-gallery.gif" runat="server" /><asp:ImageButton ID="btnBuyNow" ImageURL="images/buy-bm-clear.gif" runat="server" CommandName="Update" /></td> </tr> </table></ItemTemplate></asp:Repeater></ContentTemplate></asp:UpdatePanel>

Here's the code that creates the triggers:

Private Sub Page_Init(ByVal senderAs Object,ByVal eAs EventArgs)Handles MyBase.Init'Add TriggersDim ap1As AsyncPostBackTrigger =New AsyncPostBackTrigger()Dim ap2As AsyncPostBackTrigger =New AsyncPostBackTrigger() ap1.ControlID = pnlProduct1.FindControl("rY5").UniqueID ap1.EventName ="ItemCommand" ap2.ControlID = pnlProduct2.FindControl("r52").UniqueID ap2.EventName ="ItemCommand" UpdatePanel1.Triggers.Add(ap1) UpdatePanel1.Triggers.Add(ap2)End Sub

Any suggestions?

Jennifer

Take a look at this post...http://forums.asp.net/p/1139950/1831145.aspx

-Damien


Got it fixed. It was actually related to a bug in my Master Page!

Thanks for the help!

Jennifer


To fix this problem, you can add the follow code in your web.config

<system.web>
<pages validateRequest="false">
</system.web>.

Triggers Across Content Control

I've seen this posted a few times but no concrete solution or identification of the problem. I have 2 content section. The first one has buttons that should trigger an update in the second content. The second content has an UpdatePanel with the trigger definition. But I get the following error:

The ControlID property of the trigger must reference a valid control.

This is the code:

<

asp:ContentID="Content3"ContentPlaceHolderID="MainContentHeaderHolder"Runat="Server">
<strong>Property Details :: Options</strong>
<div>
<asp:ButtonID="btnNewResident"Text="[New Resident]"OnClick="ViewResidentPanel"runat="server"/>
</div>
</asp:Content>
<asp:ContentID="Content4"ContentPlaceHolderID="MainContentHolder"Runat="Server">
<atlas:UpdatePanelID="upNewRecordPanels"runat="Server">
<ContentTemplate>
......
</ContentTemplate>
<Triggers>
<atlas:ControlEventTriggerControlID="btnNewResident"EventName="Click"/>
<atlas:ControlEventTriggerControlID="btnNewContactNumber"EventName="Click"/>
<atlas:ControlEventTriggerControlID="btnNewAuthorizedGuest"EventName="Click"/>
</Triggers>
</atlas:UpdatePanel>
</asp:Content>

Is there a solution or is this a bug or by design?

{Bump}

Any thoughts from anyone on this? Is it by design that you cannot cross content sections or does it need to be done a different way?


Hi
I bumped into the same problem. It makes some kind of sense, because the controls in the other content control will be loaded in a different container and from what I've seen the UpdatePanel cannot find it.
One solution would be to edit the control id to its UniqueID:
<atlas:ControlEventTriggerControlID="MainContentHeaderHolder$btnNewResident"EventName="Click"/>
or
<atlas:ControlEventTriggerControlID="ctl00$MainContentHeaderHolder$btnNewResident"EventName="Click"/>

In both cases the error disappears, but i didn't test if the trigger gets fired. An alternative would be to add the trigger from the code using the UniqueId (easier if you later need to modify the control herarchy).

Anther solution (the one i used) would be to relate the trigger to a control that gets changed inside the UpdatePanel, like a panel.Visible - you probably have one that changes, otherwise you wouldn't need to update it. Although the controls inside the content template of the update panel do not appear as choices in the designer, you can add the trigger manually in source view.

I hope this helps
Vlad

Triggers

Hi to all.

So, I create buttons in a usercontrol after it i want to create triggers on this buttons in page. Is it possible?

I tried to do something like this on page

private

void FindButton(Control control)

{

foreach (Control phin control.Controls)

{

if (ph.Controls.Count > 0)

FindButton(ph);

if (phisCMSLinkButton)

{

ControlEventTrigger cet =newControlEventTrigger();

cet.ControlID = ph.ID;

cet.EventName =

"Click";

((

UpdatePanel)this.FindControl("UPContent")).Triggers.Add(cet);

}

}

}

I got an error

The ControlID property of the trigger must reference a valid control.

Exception Details:System.InvalidOperationException: The ControlID property of the trigger must reference a valid control.

Can anyone help me? :)

I'm getting the same error when trying to set my triggers to buttons inside of a Gridview. I'm still looking for the answer, but thought I'd post here in case someone came across and knew the answer for both of us.


No one knows why does it happens ?
Did anyone find out how to reference a gridview button in atlas?

for gridview or datagird : you just put an update panel around the grid markup code, hence you don't need to use Triggers to trap event. code like this:

<

atlas:UpdatePanelID="upd1"runat="server"><ContentTemplate>

<asp:GridView ...>...</asp:GridView>

</

ContentTemplate></atlas:UpdatePanel>

Ok, that all. just format your grid as you want, the update panel around the grid will help you control the event from button, hyperlink button... inside the grid and, of course, you don't need to use Triggers here.

Extending idea from those above, if you put the update panel right after the form tag, and so you don't need to trigger any events. Like this:

<form runat="server">
<atlas:UpdatePanel....>
<ContentTemplate>
...your markup code ...
</ContentTemplate>
</UpdatePanel>
</form>


tuantran:

for gridview or datagird : you just put an update panel around the grid markup code, hence you don't need to use Triggers to trap event. code like this:

<

atlas:UpdatePanelID="upd1"runat="server"><ContentTemplate>

<asp:GridView ...>...</asp:GridView>

</

ContentTemplate></atlas:UpdatePanel>

Ok, that all. just format your grid as you want, the update panel around the grid will help you control the event from button, hyperlink button... inside the grid and, of course, you don't need to use Triggers here.

Extending idea from those above, if you put the update panel right after the form tag, and so you don't need to trigger any events. Like this:

<form runat="server">
<atlas:UpdatePanel....>
<ContentTemplate>
...your markup code ...
</ContentTemplate>
</UpdatePanel>
</form>

What if you have more than one update panel? How do I reference the GridView from a separate update panel?


Please copy and paste here the mark-up code of your .aspx in that you have some seperate update panel and brieftly explain your request. I will try to find a correct solution if I can.

Regards

Triggers

Can you provide a short example, or point me in the direction, of how to use the "ControlEventTrigger" - I think I have the "Control ValueTrigger" figured out - responds to a value of a control changing (right?), but I'm not sure how the EventTrigger is used - I assume it responds to an event...

Thanks,


Ed

Here is an example. The supervisor dropdown gets updated once a manager is chosen.

<asp:DropDownListID="ddlManager"runat="server"DataSourceID="odsManager"DataTextField="Manager"DataValueField="ManagerID"AutoPostBack="True"></asp:DropDownList>

<atlas:UpdatePanelID="p2"runat="server"Mode="Conditional">

<ContentTemplate>

<asp:DropDownListID="ddlSupervisor"runat="server"DataSourceID="odsSupervisor"

DataTextField="Supervisor"DataValueField="Supervisor">
</asp:DropDownList>

</ContentTemplate>

<Triggers>

<atlas:ControlEventTriggerControlID="ddlManager"EventName="SelectedIndexChanged"/> </Triggers>

</atlas:UpdatePanel>


A sample of using ControlEventTrigger is included in the ASP.Net Atlas First Look webcast (Nikhil Kothari)

Download ASP.NET "Atlas" First Look demo video

Hope this helps...


Thank you Nta and dip!
Hi,

what is the magic behind a ControlEventTrigger? well, suppose that you are using the SelectedIndexChanged event of a DropDownList as a trigger, like in the example posted by Nta.

What the trigger does is attaching an event handler to the SelectedIndexChanged event. When you make a selection in the ddl, the ddl does a postback, the SelectedIndexChanged event fires and the handler attached by the trigger is executed.

When the trigger's handler is executed, the corresponding UpdatePanel is forced to perform an update.

triggers for programmatically added controls

Hi!

I almos get crazy in here :-)

I have a Button and an UpdatePanel with a table in it. When the Button is pressed, the UpdatePanel fills up with MANY programmatically auto generated LinkButtons:

example:

void mybutton_Click(object sender, EventArgs e)

 {
LinkButton mylinkbutton =new LinkButton();
mylinkbutton.Text ="hallo";
mylinkbutton.ID ="mylinkbutton";
mylinkbutton.Click +=new EventHandler(mylinkbutton_Click);
mycell.Controls.Add(mylinkbutton);
}

where mycell is part of the Updatepanel and mybutton is a AsyncPostBackTrigger of the UpdatePanel.

The problem is the EventHandler of the several link buttons (mylinkbutton_Click). The Event doesnt get fired.

I already tried tons of solutions like

ScriptManager.RegisterAsyncPostBackControl(mylinkbutton);

within the mybutton_Click. Didnt work...

This page (http://ajax.asp.net/docs/tutorials/UsingUpdatePanelControls.aspx) tells me that I have to place the .RegisterAsynPostBackControl in the Page_Load() function, but how should I do this at runtime?

Any ideas? need help!

TIA

J

Try this:

ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(mylinkbutton)

Thanks a lot, but I already tried that!

I use a usercontrol and therefore call the postbackcontrol like that:

ScriptManager.GetCurrent(Parent.Page).RegisterAsyncPostBackControl(mylinkbutton);

But it still doesnt work :(

i do it like that:

void mybutton_Click(object sender, EventArgs e) { LinkButton mylinkbutton =new LinkButton(); mylinkbutton.Text ="hallo"; mylinkbutton.ID ="mylinkbutton"; mylinkbutton.Click +=new EventHandler(mylinkbutton_Click); mycell.Controls.Add(mylinkbutton); ScriptManager mymanager = ScriptManager.GetCurrent(Parent.Page); mymanager.RegisterAsyncPostBackControl(mylinkbutton); }

Microsoft says that I should call RegisterAsyncPostBackControl() in Page_Load() but I cannot write it there because I dont know my LinkButtons at design time! :-(

any ideas?

thx Joe


Hi,

like every dynamic controls, your LinkButtons must be recreated on every postback (either synchronous or asynchronous).

When you click one of the dynamic LinkButtons, you fire an asynchronous postback but the corresponding control doesn't exist on the server side, because you've created it in a handler (mybutton_Click) that now doesn't get called.

Triggers functionality

when is the triggers functionality to be used? when isAsyncPostBackTrigger andPostBackTrigger used? what does their arguments mean?

You can use thePostBackTrigger to specify a control inside the UpdatePanel that should do a postback (not a asynchronous postback.)

You use theAsyncPostBackTrigger to define a control and optional event of the control that should do a asynchronous postback and refresh the UpdatePanel. You can for example use theAsyncPostBackTrigger when you have controls outside of the panel and want them to refresh the panel.

Triggers for UpdatePanel

I am just learning how to use the UpdatePanel control, so please be patient with me.

I think I understand the concept of wiring ControlID/EventName combinations to the UpdatePanel's collection of triggers.

It seems fairly straight forward if you are wiring up a standard Button control, but in my case, I would like to wire a button control embedded in a user control or DataGrid control. I attempted to expose the button as a public property of the user control and tried to wire it up ("UserControl.MyButton" and "Click"), but I get the

"A control with ID 'WebUserControl1.MyButton' could not be found for the trigger in UpdatePanel 'UpdatePanel1'. "

error message.

I also would like to do the same with a button embedded in a datagrid, but that seems to be a tall order.

Thanks much in advance.

It seems strange at first but you can add the usercontol/datagrid (the button's parent control) as a trigger for the updatepanel. Maybe that is enough for you.

(You can also force the updatepanel to refresh in the server side: you handle your button click event server side and then simple call the update method of any updatepanel to your taste)


stmarti:

It seems strange at first but you can add the usercontol/datagrid (the button's parent control) as a trigger for the updatepanel. Maybe that is enough for you.

(You can also force the updatepanel to refresh in the server side: you handle your button click event server side and then simple call the update method of any updatepanel to your taste)

Could you give me an example of what the code ought to look like? I am not following you. Thank you.


hello.

well, just pass the id of the grid instead of passing the id of the button you've defined on the template.


Thanks. Works.

Triggers for update panel

I have a web page (aspx) that has on it 2 controls (ascx) - one of the controls has an update panel with functionality for it etc. - I want to trigger the update function from the second control that has a linkbutton on it.

Is this possible?

TIA

Yes. Update panel has Triggers element which can be used as follows
 <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <Triggers> <asp:AsyncPostBackTrigger ControlID="lnkButton" EventName="Click"/> </Triggers> </asp:UpdatePanel>

It would seem so - but if the trigger and the update panel are in different ascx files they can not see each other - even if those ascx files exist as controls on the same aspx page

You can explicitly call Update method of another UpdatePanel like this:

UpdatePanel1.Update() ;

Assumption: LinkButton is in UpdatePanel2 and the above code is written in event handler for LinkButton click event.

Generally, you have this kind of scenario in Master-Detail relationship. There is tutorial onhttp://ajax.asp.net site about this.


Okay I dont think you are looking at what the question says - because this doesnt work - unless you can point me to the specific tutorial I cant find the one you are talking about

here is a simple picture that diagrams what I am trying to do

Page1.aspx has two controls on it - both controls are ascx files (Control1.ascx and Control2.ascx)

Control1.ascx has an image button that when clicked is to trigger the UpdatePanel on Control2.ascx

Example