Decoupling javascript from UserControls

  • Thread starter Thread starter Ole Viaud-Murat
  • Start date Start date
O

Ole Viaud-Murat

Hi,

i'm developing a relatively large user-control based ajax enabled
asp.net 3.5 application and am wondering if it is somehow possible to
decouple the javascript portions from the UserControls.

Often i need to create client-ids within those scripts, so i need a
reference to the server-controls in the control.

What i want to do is extract all javascript from the UserControls in
order to centralize them into libs and make them more cacheable (for
the browser).

Has someone done that before or could point me to the right direction
or resources? Should a ScriptManager be used for that? What is the
recommended pattern to accomplish a clean separation?

thanks in advance
with regards
Ole
 
Hi,

i'm developing a relatively large user-control based ajax enabled
asp.net 3.5 application and am wondering if it is somehow possible to
decouple the javascript portions from the UserControls.

Often i need to create client-ids within those scripts, so i need a
reference to the server-controls in the control.

What i want to do is extract all javascript from the UserControls in
order to centralize them into libs and make them more cacheable (for
the browser).

Has someone done that before or could point me to the right direction
or resources? Should a ScriptManager be used for that? What is the
recommended pattern to accomplish a clean separation?

thanks in advance
with regards
Ole

One way to do this would be to create new classes that derive from other
classes and override the emit methods. You can then either alter the
scirpt or completely overwrite it.

But, you should question the wisdom of that route, as much of the script
is not emitted (and less in newer versions of AJAX than older, showing
it is getting cleaned up). Much of the AJAX framework is already in
libraries (which are called with "dynamic" names rather than pulled from
the application tree).

My personal feeling is see if there is a framework out there (jQuery?)
that does what you want, rather than completely reinventing the wheel.

Watch out if you go down a route where you code a lot, as the new
simplifications coming forth in .NET 4.0 will force you to rewrite your
code if you want to take advantage of them. Thus far the code seems very
backwards compatible, but if you code under the old model, you could
personally be stuck with the old model.

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
(e-mail address removed):











One way to do this would be to create new classes that derive from other
classes and override the emit methods. You can then either alter the
scirpt or completely overwrite it.

But, you should question the wisdom of that route, as much of the script
is not emitted (and less in newer versions of AJAX than older, showing
it is getting cleaned up). Much of the AJAX framework is already in
libraries (which are called with "dynamic" names rather than pulled from
the application tree).

My personal feeling is see if there is a framework out there (jQuery?)
that does what you want, rather than completely reinventing the wheel.

Watch out if you go down a route where you code a lot, as the new
simplifications coming forth in .NET 4.0 will force you to rewrite your
code if you want to take advantage of them. Thus far the code seems very
backwards compatible, but if you code under the old model, you could
personally be stuck with the old model.

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog:http://gregorybeamer.spaces.live.com

*******************************************
|      Think outside the box!             |
*******************************************- Zitierten Text ausblenden -

- Zitierten Text anzeigen -

Thank you so far.

But i dont understand you completely. I'm neither planning to change
the ajax js libs nor to the load-behaviour of those.

In some of our UserControls there are javascript blocks, for example
to handle certain events of commercial controls eg. the SelectedItem
Change of a ComponentArt ComboBox.

The problem is, that those js blocks are scattered throughout the html
response that is sent to the browser. And i want all of the JS to be
loaded from files, to remove them from the UserControl-Markup, to make
them cacheable for the client and to centralize all JS source.

I guess the main problem is, that i'm using constructs like

var el = $get('<%= tbSomeControl.ClientID %>');

Probably i should try to remove those Server-Side Client-ID generation
and get those a different way.

I dont know if i understood you wrong or if my question was unclear,
perhaps you know now what i mean?

For now, we have to stick to asp.net 3.5 in Forms mode, though we
consider using asp.net MVC in the near future.
 
"Ole Viaud-Murat" wrote
I guess the main problem is, that i'm using constructs like

var el = $get('<%= tbSomeControl.ClientID %>');

Probably i should try to remove those Server-Side Client-ID generation
and get those a different way.

I dont know if i understood you wrong or if my question was unclear,
perhaps you know now what i mean?

I get the impression that you want your JS to be in external .js files, yet
still be able to reference the server-generated IDs. If so, you can have
your server-side code emit a simple bit of JavaScript that merely writes out
variables into a JS section before your imported JS code needs to reference
those variables, e.g.

JavaScriptSection.Text=String.Format("var inputBox='{0}';",
inputBox.ClientId)

(where JavaScriptSection is a Literal, appropriately decorated with <script
type=....> and the "//<![CDATA[" xhtml-compliance thing. Or there's some
ClientScriptManager.RegisterClientScriptBlock (q.v.) thing you can use,
which provides the correct decoration automatically.)

and then in your JS files refer to the required entity with
Document.GetElementById(inputBox).

I'm not saying that's the right way to do it, but it's a possibility, and it
works.

OTOH, and it wouldn't be the first time I'm completely wrong, there is some
call you can make from the external JS file to let the scriptmanager know
that your script is loaded - I saw it in one of those instructional videos
listed in the Start page in VS2008. Someone else please comment on this, but
ISTR you can then use some $get functionality to reference elements by their
ID as it is written the aspx page, and it will convert it to the ID emitted
by the server.

Andrew
 
"Ole Viaud-Murat"  wrote
I guess the main problem is, that i'm using constructs like
var el = $get('<%= tbSomeControl.ClientID %>');
Probably i should try to remove those Server-Side Client-ID generation
and get those a different way.
I dont know if i understood you wrong or if my question was unclear,
perhaps you know now what i mean?

I get the impression that you want your JS to be in external .js files, yet
still be able to reference the server-generated IDs. If so, you can have
your server-side code emit a simple bit ofJavaScriptthat merely writes out
variables into a JS section before your imported JS code needs to reference
those variables, e.g.

JavaScriptSection.Text=String.Format("var inputBox='{0}';",
inputBox.ClientId)

(where JavaScriptSection is a Literal, appropriately decorated with <script
type=....> and the "//<![CDATA[" xhtml-compliance thing. Or there's some
ClientScriptManager.RegisterClientScriptBlock (q.v.) thing you can use,
which provides the correct decoration automatically.)

and then in your JS files refer to the required entity with
Document.GetElementById(inputBox).

I'm not saying that's the right way to do it, but it's a possibility, andit
works.

OTOH, and it wouldn't be the first time I'm completely wrong, there is some
call you can make from the external JS file to let the scriptmanager know
that your script is loaded - I saw it in one of those instructional videos
listed in the Start page in VS2008. Someone else please comment on this, but
ISTR you can then use some $get functionality to reference elements by their
ID as it is written the aspx page, and it will convert it to the ID emitted
by the server.

Andrew

Ok, thanks a lot to you both.

After having written my second post i realized, what i am doing. And
before all what i am doing wrong.

I now separate the js from the usercontrols and avoid ClientID
generation in the markup and set vars as you mentionend in the Render
() event by using ScriptManager.RegisterStartupScript
(). The external js files have to be finished by a call to
Sys.Application.notifyScriptLoaded(). Within those scripts i use $get
() to get a reference to the elements and it works fine. That reduced
the Response Size that's sent to the browser by almost 500 lines of js
code. and if i'm not wrong, those 500 lines are now cached.

The feature that you mentioned being able to use a simple $get() on
the markup-id would be very handy - i guess you have to register the
scripts / blocks through ScriptManager.Include("script", typeof
(control)) so it can establish the complete offset to the element.

And in almost all of the cases i can pass the id as a parameter to the
functions. Though It gets a bit annyoing when you have to reference
elements that are placed inside of FormView-Templates.

However thanks a lot for your hints and help.
I'm not saying that's the right way to do it, but it's a possibility, andit
works.
What is the right way to accomplish these tasks?

with kind regards
Ole
 
Thank you so far.

But i dont understand you completely. I'm neither planning to change
the ajax js libs nor to the load-behaviour of those.

In some of our UserControls there are javascript blocks, for example
to handle certain events of commercial controls eg. the SelectedItem
Change of a ComponentArt ComboBox.

The problem is, that those js blocks are scattered throughout the html
response that is sent to the browser. And i want all of the JS to be
loaded from files, to remove them from the UserControl-Markup, to make
them cacheable for the client and to centralize all JS source.

I guess the main problem is, that i'm using constructs like

var el = $get('<%= tbSomeControl.ClientID %>');

Probably i should try to remove those Server-Side Client-ID generation
and get those a different way.

I dont know if i understood you wrong or if my question was unclear,
perhaps you know now what i mean?

For now, we have to stick to asp.net 3.5 in Forms mode, though we
consider using asp.net MVC in the near future.

If you are using third party controls, it gets more difficult. Some of
hte libraries use external files already, but many emit JavaScript, as
you have pointed out.

Can you consolidate? Certainly, but the calls are still going to be
emitted unless you can control the output (exposed or deriving your own
class from theirs, and it is possible neither will be supported).

I am not sure I see anything wrong with $get() except perhaps
maintainability.

Good luck on this one, as I am not sure there is an easy solution,
especially if you are attempting to consolidate numerous libraries. It
also sounds very custom.


--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
Back
Top