Last post Oct 12, 2007 08:57 AM by LisburnLad
Sep 14, 2006 06:27 PM|bdemarzo|LINK
I was glad to see that membership controls were added to the latest beta release. However, I did notice that all of them (with one exception) still put a TABLE wrapper around the content when using a templated control. It happens on the Login and PasswordRecovery
controls, which generate output like this:
<div class="AspNet-Login"><table id="ctl00_content_LoginForm" cellspacing="0"
cellpadding="0" border="0" style="border-collapse:collapse;">
<!-- actual content from LayoutTemplate here -->
Although I like the effort of the table-less designs, I prefer forms that use tags like FIELDSET and LEGEND, and that can be designed to more closely mirror the other forms on my sites, hence my desire to use templates. Why do the Login and PasswordRecovery
controls continue to add the TABLE wrapper? It seems it something more internal to the .Net Framework that the current CSS adapters aren't filtering out, because there are definitely no TABLE tags being created by the adapters.
Ironically, the CreateUserWizard did not add a table wrapper around the CreateUserWizardStep -- but it did add it around the CompleteWizardStep.
I did some stepping through of code and stack traces to see if I could find anything different; the only thing of interest was that the CreateUserWizard called the CreateChildControls method during the Init phase, whereas the Login and PasswordRecovery called
it during the PreRender phase (apparently the Wizard class does this via EnsureChildControls). Does't explain why the TABLE is around the Completed step and not the Create step.
Is there something I'm missing, or am I looking for functionality (i.e. no TABLEs around templated controls) that isn't here yet?
Sep 14, 2006 09:56 PM|Russ Helfand|LINK
Well stated. And much appreciated.
I've duplicated the problem here and I see exactly what you are talking about. I'll add it to the to-do list to fix in the next update.
Sep 15, 2006 09:23 AM|bdemarzo|LINK
Thanks, Russ! I guess I'll go back to my
control hack that removes TABLE (and related tags) via regular expressions. :)
Since my post yesterday, I tinkered some more. For the life of me I can't find any place where the TABLE is added to the control hierarchy. I looked at the Control.Controls collection at the Render() phase of the adapter, and there were no TABLE (or related)
tags to be seen. Very weird.
Sep 15, 2006 01:29 PM|Russ Helfand|LINK
Please allow me to allow to try to help you to fix this in the adapter kit, instead.
The adapters that handle the membership controls follow a similar pattern in their implementation. Let's look at the LoginAdapter as an example,
http://www.asp.net/CSSAdapters/srcviewer.aspx?inspect=%2fCSSAdapters%2fMembership%2fLogin.aspx. In particular, I want you to look at line 125 where the template container is being rendered. I'm considering changing that from:
foreach (Control c in container.Controls)
It would be helpful if you could try that fix out locally and let me know if it works well for you. Remember that the other membership control adapters are doing something similar in many cases so we'll need to make this fix in a few files, not just LoginAdapter.cs.
And, of course, we'll ultimately want to do it equally in VB and C#. I noticed from your article on the reg expression solution that you gave a C# example so I figured you were a C#-sort-of-person so I've given the proposed code to you in C#, naturally.
Good luck, however you end up working around this for now. Best regards,
Sep 15, 2006 04:08 PM|bdemarzo|LINK
Your suggestion did the trick for the Login control.
I used a similar approach to the CreateUserWizard adapter. Since this adapter only added the table in the Completed step, I made the following change in the RenderContents() method (around line 181):
if (activeStep.StepType == WizardStepType.Complete)
foreach (Control c in activeStep.Controls.Controls.Controls.Controls.Controls)
For the PasswordRecovery control, there's three places to change -- each instance of the RenderControl() method in the RenderContents() method should be commented out and replaced by the
foreach (Control c in passwordRecovery.UserNameTemplateContainer.Controls)
foreach (Control c in passwordRecovery.QuestionTemplateContainer.Controls)
foreach (Control c in passwordRecovery.SuccessTemplateContainer.Controls)
That's some weird behavior, but it works, and it doesn't seem to break any of the functionality.
Sep 15, 2006 04:26 PM|Russ Helfand|LINK
Thanks for the additional detail. It will help others who run into what you ran into.
I'll make sure we fix it in the next rev of the kit.
It sounds like you are now able to use the adapters for your project. That's great. Best of luck and regards,
Sep 15, 2006 04:44 PM|bdemarzo|LINK
With this, I'll throw the adapters into one of my lesser projects to see how it works. If all goes well, they'll become a permanent part of my web projec template. :)
Thanks for the quick replies and follow-up!
Sep 19, 2006 09:50 AM|MattW|LINK
Thanks for the tips guys. I added a basic adapter for the WIzard control to the CSS Friendly adapters and was haveing the same problem when the StepType = Step.
The same technique has fixed it [Yes]
Sep 20, 2006 01:58 PM|bdemarzo|LINK
A little update on this.
It works great in Firefox. In IE, when you click the Log On or Register or Recover Password button, IE does nothing.
The only difference in the source available to each browser is in the <form> tag. Note the bold area below. Firefox has this:
IE has this:
Nice feature. I'll see what else I can find out.
Sep 20, 2006 02:54 PM|bdemarzo|LINK
Sep 20, 2006 03:20 PM|bdemarzo|LINK
... well, not really. The generated source is identical for both pages now, but still nothing working in IE. No reported script errors in IE, either.
So you understand what it does/doesn't do in IE... It will do client-side validation when the command buttons are clicked, but it will not post back when there are no client side errors. I confirmed the problem exists with the same code on multiple servers,
and from different desktops (all running XP SP2 with IE6).
I tried putting an onClientClick="return true;" on the command button: skips validation (expected), no postback.
I tried turning off ViewState: no postback.
Obviously, there's something weird that's not working in IE. Looks like it's back to my control hack... :(
Sep 20, 2006 03:30 PM|bdemarzo|LINK
Problem found. What was it? Nothing to do with the adapters, so ignore any further reading if you don't care to know what the difference in behavior between Firefox and IE was caused by.
The things that broke IE: A PayPal donation script on the page, which uses a <FORM> tag. IE apparently breaks with the nested form tags. Moving the server-side form so it doesn't overlap these fixed the problem.
Oct 08, 2006 05:51 PM|Russ Helfand|LINK
I have fixed the code in the Login and PasswordRecovery adapters per the discussion above. I've got test pages that show the problem and demonstrate that the fix works so I'm confident about that part of the game.
However, I've not touched the CreateUserWizard adapter because, frankly, I've not been able to repro the problem. And, because the suggested code is a bit odd. I'd like to explore the CreateUserWizard case further.
Here is what I've tried as a test case:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<form id="form1" runat="server">
<asp:CreateUserWizard ID="CreateUserWizard1" runat="server" ActiveStepIndex="1">
Complete! Your account has been successfully created.
<asp:Button ID="ContinueButton" runat="server" CausesValidation="False" CommandName="Continue" Text="Continue" ValidationGroup="CreateUserWizard1" />
When I run that page in IE using the unmodified CreateUserWizard adapter I don't see the table appear. Also, if I use the suggested code (with the deeply nested de-referencing of Control) I actually end up crashing when I run this test page because at
some point that nest of controls hits a null.
Can anyone provide a test case (page) that I can run locally (so please don't post pages that use all sorts of databases, etc. that I won't have, ha ha) to demonstrate the problem with templating CreateUserWizard and using the kit's adapter? If we can't
come up with such a test case together I'm going to fix the problem in Login and PasswordRecovery for the next rev of the kit but will not attempt any modification to the template code in the adapter for CreateUserWizard.
Sound fair, folks?
Nov 08, 2006 12:12 PM|Frank F. Smith|LINK
Try templating both steps in the CreateUserWizard control. I have observed that the
first templated step is fine (no single-cell table wrapper). Second (or subsequent) templated steps get the single-cell table added in RenderContents(). A fix similar to that described up-thread works, though I included a test for control type
Table as I drill down the control hierarchy past the inserted single-cell table.
Oct 12, 2007 08:57 AM|LisburnLad|LINK
I'm still getting the problem of the Complete step containing tables (and this is using the most up to date source). For your simple sample of the CreateUserWizard I get the following output:
<div class="AspNet-CreateUserWizard" id="CreateUserWizard1"><table cellspacing="0" cellpadding="0" border="0" style="height:100%;width:100%;border-collapse:collapse;">
Complete! Your account has been successfully created.
<input type="submit" name="CreateUserWizard1$CompleteStepContainer$ContinueButton" value="Continue" id="CreateUserWizard1_CompleteStepContainer_ContinueButton" />
However, this only happens when the "Complete" step occurs after first completing the initial create user step - so in the example you give you would need to remove the "ActiveStepIndex="1" " from the CreateUserWizard line - going straight to the CompleteWizardStep
doesn't produce this behaviour & the code appears as it should, with no tables present.