I have a user control that is cached and as part of this control, javascript for loading a swfobject is written to the page. I've tried using ClientScript.RegisterStartupScript to write the javascript to the page, however, when rendered from the cache, the javascript is no longer included. This means the swfobject is not loaded.
Currently I'm writing the script into part of the control's div.InnerHTML, which works, but is there a better way?
No, as far as I know there is no better way.
You can use a Literal or a PlaceHolder instead of a div to put the code in, so that you don't have the extra div, but other than that it can't really be improved. If you want to cache the control, all that it does has to be included in what it renders to the page. When the controls is rendered from the cache the code behind is not executed, so it can't have any side effects outside of the control itself.
Related
I'm having issues getting a control to pass its value back to my server from the browser. Essentially, what I need is a LiteralControl that can be pushed onto the page, modified by some JavaScript, and then pass its entire contents back.
What I'm doing: I'm working with an SVG image. I need to send whatever pre-initialized value (display elements/content) to the browser. Then the user can interact with the image via JavaScript. Whenever they submit the form, I need to get the new/modified image back.
I made a custom control that outputs the SVG element, and allows you to set custom width, height, and viewbox attributes. It has a style element that you can provide content for, and a script element that you can also provide some content for. I've set up a ScriptDescriptor for all the properties that should be modified on the browser. I built an SvgImage.prototype and an SvgImage.descriptors JavaScript class, and registered my namespace and class in JavaScript. My JavaScript is all making it to the browser, but the control isn't added to the Request.Form elements coming back in.
Is there any way to get the control added to the Request.Form elements without creating a hidden field and dumping the content into it?
As I mention in my comment, I am unaware of any native ASP.NET control that would allow you to do this.
All form information posted back to the server has to be (to my knowledge) contained within an <input> control. (As I'm sure you're aware, ASP.NET can only work with standard form processing as supplied by your average browser.)
So I think you're looking at transfering the SVG information into a hidden control (an invisible <textarea> / <asp:TextBox TextMode="Multiline"/> makes most sense) before the post-back takes place.
Another option could be to use AJAX, although if you only want the the information at the point of post-back, you could run into trouble with the timing of it... so I can't see it being much use (but just mentioning it as an option).
I'm retro-fitting a .aspx page with AJAX functionality (using VB, not C#). The codebehind populates the page with data pulled from a web-service. The page has two panels that are populted (with different data, of course) in this way. On a full page refresh, one or both panels might need to be populated. But populating Panel 2 can take a long time, and I need to be able to update panel 1 without refreshing Panel 2. Hence the need for AJAX (right?)
The solution I've come up with still has the old .aspx page with .aspx.vb codebehind, but introduces a Generic Handler (.ashx) page into the mix. Those first two components do the work on the user's first visit or on a full page refresh, but when AJAX is invoked, the request is handled by the .ashx page.
First question: Is this sound architecture? I haven't found a situation online quite like mine. Originally, I wanted to make the .aspx page into the AJAX handler by having the codebehind implement IHttpRequest, and then providing "ProcessRequest" and "IsReusable" methods, but I found I couldn't separate a regular visit to the page from an AJAX request, so my AJAX handlers took over even on the first visit to the page. Second question: Am I right to think that this approach (making the .aspx page do double-duty as the AJAX handler) will never work? Is it impossible to tell whether we're getting a full-page request or a partial-page (AJAX) request?
If the architecture is good, then I need to dynamically generate a lot of HTML in the .ashx file, right? If that is right, should I send HTML back to the client, or should I encode it in some way? I've heard of JSON encryption, but haven't figured out how to use it yet. So, Third question: Is "context.Response.Write" the only pipeline for sending data back to the client? And, if so, should I send back HTML or some kind of JSON-encoded objects?
Thanks in advance.
It sounds as if the page requires some AJAX functionality added to the UI.
Suggest using an UpdatePanel for each web form element that needs to have AJAXy refresh
functionality. That'll save you from having to refactor a bunch of code, and introduce a whole lot of HTML creation on your .ashx.
It'll be more maintainable over the long run, and require a shorter development cycle.
As pointed out by others, UpdatePanel would be a easier way - but you need to use multiple update panels with UpdateMode property set as conditional. Then you can trigger the update-panel refresh using any button on the page (see AsyncPostBackTrigger) or even using java-script (see this & this). On the server side, you may decide what has triggered the partial post-back and act accordingly by bypassing certain code if not needed.
You can also go with your approach - trick here is to capture the page output using HttpServerUtility.Execute in your ashx and write it back into the response (see this article where this trick has been used to capture user control output). Only limitation with this approach is that you can only simulate GET requests to your page and so you may have to change your page to accept parameters via query string. Personally, I will suggest that you create a user control that accept parameters via method/properties and will generate necessary output and then use the control on your page and in ashx (by dynmaically loading it in a temperory page - see this article).
EDIT: I am using jquery to illustrate how to do it from grid-row-view.
$(document).ready(function() {
$("tr.ajax-grid-row").click(function() {
$("#hidden-field-id").val($(this).find(".row-id").val()); // fill hidden filed
$("#hidden-button-id").click(); // simulate button click
});
});
You can place above script in the head element in markup - it is assuming that you have decorated each grid-row-view with css class "ajax-grid-row" and each row will have hidden field decorated with css class "row-id" to store row identifier or the value that you want to pass to server for that row. You can also use cell (but then you need to use innerHTML to get the value per row). "hidden-field-id" and "hidden-button-id" are client ids for hidden field and submit button - you should use Control.ClientID to get actual control ids if those are server controls.
JSON is not for that purpose, it is to pass objects serialized with a nice light weight notation, is you need to stream dinamically generated html using ashx, response.Write is what you have. You may want to take a look at MVC
Or you could use jquery if it's just html, the simpliest would be the load function, or you can look into Ajax with jquery. Since the ashx can be served as any resource it can be used in the load function.
I agree with #p.campbell and #R0MANARMY here. UpdatePanel could be the easiest approach here.
But then like me, if you don't want to go the UpdatePanel route, I don't see anything wrong with your approach. However, generating the html dynamically (entirely) at the back end is not a route I'll personally prefer (for the maintainence reasons). I'd rather prefer implementing a solution that will keep the design separate from the data.
My site master page contains a single <ajaxToolkit:ToolkitScriptManager> declaration so that the few pages in my site that use an UpdatePanel need not include such a declaration. The downside to this approach is that a bunch of useless MS-Ajax JS is being emitted to the client even when it's not being used.
Is there a way to interrogate the page being rendered to see if it contains any controls dependent on the ToolkitScriptManager, and not render it in that case?
Thanks.
I have created a great stand-alone web form in asp.net utilizing many jQuery features and CSS. It works fine. When I re-create it as a web content form as part of a MasterPage, my jQuery and javascript is completely ignored.
I am referencing the pertinent jQuery and CSS in my of the MasterPage. I have a content placeholder at the bottom of the masterpage called "ScriptContent". In my content page, this is where I plug in the various jQuery methods and javascript.
When I view the page source everything is there. However, it's all being ignored so to speak. What am I doing wrong?
Probably the issue is that when your page is loaded as a content page within a masterpage, the ids of all of the elements are altered to reflect what content page they are in. Thus the ids you are using in jquery won't work.
Options I can think of include:
setting the ids used by jquery programatically from asp.net code (using the clientId of the element)
having your jquery selectors reference some other attribute of your element, such as class (which is unfortunately a bit slower)
I would match the source output of the working version against the output of the non-working version.
Obviously, there's something being rendered out from ASP.NET differently. Getting the difference would tell you what.
Since I have no details, I can only guess...but it sounds like you may have left out some $(document).ready() type functionality to kick off your script somewhere.
I've built a ascx control and I would like to be able to keep adding new instances of it using JavaScript instead of having to do a AJAX callback. Is this possible? I am basically building a web form for a query control and should clause X be filled in, I want to generate a control for the next clause below. I would like to learn how to do this without doing a callback.
Thanks
ASCX are server side user controls and, to my knowledge, can only be loaded by a server event. This can be accomplished through a full page postback or using UpdatePanels and ASP.net AJAX.
If you don't want to use these options and stick with a full JavaScript solution, you're looking at probably doing DOM manipulation and dynamically adding straight HTML.
If the ASCX controls don't change their appearance and all you're doing is showing and hiding them, one last alternative could be to load all of them into DIV tags that have their display style set to none. Then when the user clicks on a checkbox or whatever, you can use JavaScript to show that DIV tag containing the next control. This is how many JavaScript tab setups work.