tags:

views:

117

answers:

1

I'm new to writing custom controls. I have MyCustomControl.cs and in my Render method I want to render out about 50 lines of JavaScript. What's the best way to do this, use the writer?

protected override void Render(HtmlTextWriter writer)
        {
            writer.write(@"<script type....rest of opening tag here");

            writer.Write(@"
                            function decode(s)
                            {
                                return s.replace(/&amp;/g, ""&"")
                                .replace(/&quot;/g, '""')
                                .replace(/&#039;/g, ""'"")
                                .replace(/&lt;/g, ""<"")
                                .replace(/&gt;/g, "">"");
                            };"
            );

I plan on having around 6 more writer.Write to write out some more sections here. Is that the best approach to actually perform the writing of JavaScript in this manor?

or should I use ClientScript.RegisterClientScriptBlock? So what's the best practice or common way people are writing javascript from a custom control? (I'm not talking about a user control here!!, custom control/Class!)

I also want to keep any indentation for readability once it's spit out/rendered on the client when viewing source.

A: 

The answer I'm providing is just taking regular postbacks into account. All the below can be applied using the ScriptManager and its respective methods to do the same.

There's a couple of ways to do it. You can load a web resource and reference it

// The Scripts namespace in this case would actually be a physical folder in your YourNamespace.CustomControlsNamespace
// namespace.
// Also the /Scripts/YourJavaScriptFile.js needs to have it's Build Action property set to Embedded Resource
[assembly: WebResource("YourNamespace.CustomControlsNamespace.Scripts.YourJavaScriptFile.js", "text/javascript")]
namespace YourNamespace.CustomControlsNamespace
{
    public CustomControl()
    {
     ...
    }

    ...

    protected override OnPreRender(EventArgs e)
    {
     ...

     Type type = typeof(CustomControl);
     string scriptUrl = Page.ClientScript.GetWebResourceUrl(type, "Acuity.Web.UI.WebControls.Scripts.accdaterange.js");
     string key = "yourKey";


                if (!Page.ClientScript.IsClientScriptIncludeRegistered(type, key))
                {
                    control.Page.ClientScript.RegisterClientScriptInclude(type, key, scriptUrl);
                }

                ...
    }

    ...
}

You could also reference an external script in your custom control.

namespace YourNamespace.CustomControlsNamespace
{
    public CustomControl()
    {
     ...
    }

    ...

    protected override OnPreRender(EventArgs e)
    {
     ...

     Type type = typeof(CustomControl);
     string scriptUrl = Page.ResolveClientUrl("~/yourScriptsFolder/yourExternalScript.js");
     string key = "yourKey";


                if (!Page.ClientScript.IsClientScriptIncludeRegistered(type, key))
                {
                    control.Page.ClientScript.RegisterClientScriptInclude(type, key, scriptUrl);
                }

                ...
    }

    ...
}

Depends how you want to package it. The advantage of the embedded resource is that you're guaranteed that this script is always with the assembly that your custom control is in. You will most likely have to add some inline JavaScript to wireup your custom control. Try and do this as little as possible. You can do this using Page.ClientScript.RegisterClientScriptBlock(...). You also want to avoid hard-coding what the auto-generated client Ids are in your scripts. They should be passed in as parameters to client-side objects.

Also, once all looks good, you should compress/minify you external JavaScript files. I use YuiCompressor from Yahoo! but there are several others out there.

You should also invest some time into looking at using a JavaScript framework such as jQuery to do a lot of the grunt work. That's it for now. I might add some more later, but these are my words of wisdom for now.

nickyt
we won't need postbacks. I 'm just spitting out jQuery and some regular JavaScript as well as an array of values. I'll use those array of values to make JSON calls back to an .ashx handler in order to get some data to populate that jQuery control.
CoffeeAddict
and in this case I want to keep the jQuery inside this .cs, not in a .js
CoffeeAddict
thanks for the info. So looks like RegisterClientScript works fine with custom controls.
CoffeeAddict
any word on keeping the spacing and formatting so when the JavaScript is rendered, it's not just one big long line?
CoffeeAddict
@coffeeaddict. Unless it's for debugging purposes, you want to avoid spacing and formatting. You want to render as little JavaScript everytime, hence my mentioning YuiCompress. However, if you want to add spacing and formatting, use \t (tab) and \n (newline) in your string/Stringbuilder that you use for registering your client script blocks. For the external JavaScripts, the formatting is however you typed it. But once again, I would strongly recommend compression/minification for when you roll out to production.
nickyt