ClientScript.IsStartupScriptRegistered() from Web Control

J

Jonathan Wood

I'm designing a control that will render some additional HTML content
exactly once per page, regardless of the number of instances of the control
on that page.

Thanks to Mr. Niver's suggestions, I got this working by calling
Page.ClientScript.IsStartupScriptRegistered() from my control's Load event
and writing that additional HTML content from the control only when
IsStartupScriptRegistered() returns false.

This seemed to be working just fine from a Web User Control. But I'm now
moving my control to a regular Web control. The first problem is that the
Control has no Load event. One of my books shows a control initializing
itself in the OnInit() override so I tried my code there:

protected override void OnInit(EventArgs e)
{
// ...
_createHiddenField = false;
if (!Page.ClientScript.IsStartupScriptRegistered("OrderCartRequest"))
{
Page.ClientScript.RegisterStartupScript(this.GetType(),
"OrderCartRequest", "function dummy() {}", true);
_createHiddenField = true;
}
// ...
}

I placed five instances of this control on a page and set a breakpoint in
the code above. I see that Page.ClientScript.IsStartupScriptRegistered()
returns false when it is called each of the five times from each instance of
my control. Obviously, I expect false to be returned only for the first
instance of the control.

Can anyone see what I'm missing?

Thanks.

Jonathan
 
W

William Niver

So you went from an *.ascx file to a compiled server control?

If so, pop yer code into the "Protected Overrides Sub CreateChildControls()"
Method

Sample:

Protected Overrides Sub CreateChildControls()
MyBase.Controls.Clear()
Dim Div_Main As New HtmlGenericControl("div")
MyBase.Controls.Add(Div_Main)
RenderHiddenField(Div_Main)
End Sub

Private Sub RenderHiddenField(ByRef container As Control)
'check for registration here. If not registered, add it to the
container (which is Div_Main)
Dim hdn_Field As New HiddenField
hdn_Field.ID = "hdn_Field"
container.Controls.Add(hdn_Field)
End Sub

Hope that helps!

William
 
J

Jonathan Wood

Hi William,
So you went from an *.ascx file to a compiled server control?

Yup. I'm liking the separate assemblies. Reminds me more of the olden
days... said:
If so, pop yer code into the "Protected Overrides Sub
CreateChildControls()" Method

Well, I had a few questions about why you were doing it this way but I still
must be doing something wrong as I didn't even get that far.
ClientScript.IsStartupScriptRegistered() is still returning false for each
control and a hidden field is being created for each control.

I don't know if I'm missing something, or if ClientScript just doesn't work
from this location...

protected override void CreateChildControls()
{
// base.CreateChildControls();

Controls.Clear();
HtmlGenericControl div = new HtmlGenericControl("div");
Controls.Add(div);
RenderHiddenField(div);
}

protected void RenderHiddenField(Control div)
{
// Encrypt our view state for added security
// Page.RegisterRequiresViewStateEncryption();

if (!Page.ClientScript.IsStartupScriptRegistered("OrderCartRequest"))
{
Page.ClientScript.RegisterStartupScript(this.GetType(),
"OrderCartRequest", "function dummy() {}", true);

HiddenField hidden = new HiddenField();
hidden.ID = "OrderCartRequest";
div.Controls.Add(hidden);
}
}

Thanks.

Jonathan
 
W

William Niver

try:

If (Not Me.Page.ClientScript.IsStartupScriptRegistered(Me.Page.GetType,
"OrderCartRequest")) Then

instead of:

If (Not Me.Page.ClientScript.IsStartupScriptRegistered("OrderCartRequest"))
Then

Take care!

William

PS

I'm not a programmer... but I did stay at a Holiday Inn Express last night!
*grin*
 
J

Jonathan Wood

That was it! Although, I really can't say why.

I'll need to tweak this now that I'm back to reality. If you don't mind, I
had a couple of questions about your last code.

* Why are you clearing the control collection?
* Does it matter that you aren't calling base.CreateChildControls()?
* Why do you need the containing div? Why not just add it to the control?

Other than that, you've been a terrific help. I've obviously got a lot more
reading to do but I've learned a lot over the past week and you've helped me
move forward!

Jonathan
 
W

William Niver

1) Why am I clearing teh control Collection?

Force of habit. It only really becomes an issue when I make extremely
complex controls. There are points when setting properties or returning
events that I'll use a combination of:

ChildControlsCreated = False
EnsureChildControls

To force teh control to remake itself based on those new values. If I
didn't clear the control first, I'd get duplicated controls on the page.
I haven't found an issue with using it on more simple controls, so it stuck
as habit.

If I added a literalcontrol("HelloWorld") in CreateChildControls and then
called CreateChildControls or EnsureChildControls (you shouldn't ever call
CreateChildControls Directly), I'd wind up with two literals that said
"Hello World".

2) Calling MyBase,CreateChildControls()

Yer already *in* MyBase.CreateChildControls *grin*... why would I call it
again?
You'll get that with all the base overrides. If you Override Render, by
default it will pop in MyBase.Render(stuff).
You are overriding because you generally don't want to do the default
things, so ya change them. When I override Render, I generally change it
to:

MyBase.RenderContents(stuff)

3) The Containing Div is not required, it's once again, force of habit.

I often unessessarilly apply lessons I've learned from creating complex
compiled server controls to more simple ones, expecting that they will grow
more complex over time and will benefit from being contructed as if they
will be complex from the start.
 
J

Jonathan Wood

Okay, that's making sense to me now. Now that things are actually working,
I've tweaked the heck out of the original code. I now have a drop-in image
button that automatically creates a hidden field, and when it's clicked, it
writes encrypted product data to that hidden field, before being posted to
the shopping cart page. And my shopping cart page correctly displays the
info, can process a credit card payment, and generate an authorization code
for any of my shareware products!

I still have a lot of work, refining these steps but it's coming along
nicely.

Thanks again for all your help.

Jonathan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top