views:

443

answers:

5

My problem is in regards to calling a server-side event (e.g. DeleteClicked) from dynamically generated html/javascript on the client. I have an existing page on my website that is deeply rooted in .net. The page lifecycle is pretty complex and there are dozens of events that can be fired from the page.

We want to start taking advantage of some JQuery functionality and add additional links and buttons after the page has already loaded. For example, we would like to display a little hover-over graphics on certain images. The little hover-over graphics would provide functionality like delete, edit, etc. I would like to tie the click events on these client-side creations to server-side events without having to thrash (or bypass) the whole page lifecycle.

So far the only solution I can think of is to implant hidden asp.net controls throughout the page have the client-side code manually force a click() on the hidden control. Unfortunately I don't think this is acceptable as I won't necessarily know all of the events that may need to get called at the time I load the page. I'm also not a fan of sending down tons of markup to the client that isn't necessarily needed.

Does my question make sense? Any help would be greatly appreciated!

A: 

If you go the hidden control route, and you don't know all of the events that MAY need to get called on a particular load, then you will have to load ALL of the hidden buttons that could possibly be needed. In that way, you'll always be sure to have a control you can fire that will post back to the server.

You could also have just one 'click' controller that checks parameters to see what it has to perform, but that's quite clunky.

Alternately, you could expose web methods from your server side code which can be called asynchronously from your javascript. This way you can perform the actions without needing event handlers on controls.

For example:

    /// <summary>
    /// Deletes the 'something'.
    /// </summary>
    /// <param name="id">The unique id of the 'something' to delete.</param>
    [WebMethod(true)]
    public void DeleteSomething(string id) {
     //Insert business logic
    }

Take a look into WebMethods (or AJAX as others have mentioned), and I think you'll find it fits your solution.

Jay S
The problem with using WebMethods is that it could be changing the underlying data to which my page is bound. If I then fire an event off of an asp.net control (after other AJAX called and hit a WebMethod) the event could be invalid because the control may not be there any longer. I need a way for my dynamic html/javascript to use the regular page lifecycle. WebMethods are "real AJAX" and bypass the page lifecycle.
jakejgordon
If you hook up an 'onsuccess' javascript handler to your web method call, you can then update your controls using javascript/jquery after the event has successfully completed via the webmethod. You can also hook up the failed javascript handler so that if the call fails you can perform whatever cleanup is necessary.
Jay S
This might be getting warmer... The only obvious problem I can see is that we would essentially have to do 2 requests to the server to process one of these actions--one to perform the WebMethod action and onsuccess we would basically have to reload the page (or the appropriate update panels).
jakejgordon
In my own experience, I've had to update the display using the javascript directly accessing the DOM objects, which is quite a pain, but has saved the extra server hit. It does sound like your best bet is to actually do a proper postback inside of an update panel using hidden controls. That way you can gain all of the lifecycle benefits, without having to write javascript to update the whole display based on the actions taken by the user. If you know the superset of actions possible, this should be doable. If not, perhaps you can provide an example.
Jay S
We are currently experimenting with changing all of the business logic to be called via WebMethods and using the .net page only to retrieve the data from the DB and then redraw the page. This does in fact require us to make two requests so we are checking out how badly this will affect performance... and how difficult it will be to do this.
jakejgordon
+1  A: 

If you really want to embrace this, you should look at it in a slightly different way.

  1. All the logic that performs the "Delete" should be in a class that can be re-used
  2. Your ASPX page can then call that class to perform the delete wherever that occurs now
  3. Your jQuery can call a web service using an AJAX request and the web service can reference the same class as your ASPX page.

Not only do you get code-re-use by doing things this way, but it means you can test your code without using the UI too.

Sohnee
I have the delete logic factored out and also know how to use WebMethods--but I don't think that will solve my problem. This is a copy of my comment to another answer: The problem with using WebMethods is that it could be changing the underlying data to which my page is bound. If I then fire an event off of an asp.net control (after other AJAX called and hit a WebMethod) the event could be invalid because the control may not be there any longer. I need a way for my dynamic html/javascript to use the regular page lifecycle. WebMethods are "real AJAX" and bypass the page lifecycle.
jakejgordon
+1  A: 

While jQuery would be the more lightweight (and sexier) solution, have you thought about slapping in a few UpdatePanels on the page? It's not ideal, but it's a relatively painless way to add ajax functionality to an existing form without too much additional coding.

If you have your heart set on jQuery, you can either go the WebMethod route which keeps all of the functionality within a single page, or even create new .aspx pages which jQuery will call to perform certain actions (e.g. if you have a side-bar containing contacts, this can be moved to a new Ajax/Contacts.aspx page and you can then edit it via jQuery calls).

Chris Pebble
I'm pretty sure that the functionality we are adding is way too sexy for update panels. We do actually have a few UpdatePanels on the page already but the problem is still the same. See the other comments I added to the other answers. Thanks for your help still.
jakejgordon
A: 

Unfortunately, we didn't find a great solution for this. It seems like the only way to mix .net events and JQuery AJAX effectively is if the elements you are updating are either 100% JQuery or 100% .net events. For example, if you are dynamically adding some sort of object like a picture with a set of links (e.g. edit and delete) then the links should either both use manual AJAX (i.e. JQuery calling a WebMethod) and then update the DOM using JQuery; OR both links should call a .net event in an update panel. If you try to make one link JQuery and the other link a .net event then you'll get issues where .net doesn't know that the DOM has been updated by JQuery and your events could get hosed up. It would be very difficult to predict what are the appropriate IDs to set in your DOM so that .NET doesn't get confused (if you are using JQuery). When .NET 4.0 comes it this should get a lot easier since you'll have the option to manually specify the control IDs instead of .NET producing it's own crazy IDs.

jakejgordon
A: 

What about mixing in the classic <%=Control.ClientId%> server side markup into the JS? It is a bit messy, but maybe an option to tide you over until .NET 4.0.

Paul Daly