locked
Webparts RRS feed

  • Question

  • User-1390805452 posted
    A suggestion for the next release.
    It would be nice to have all the webpart, webpartzone, catalog, editor etc. rendered with friendly CSS as well.
    Thanks and keep up the good work.

    Mick
    Thursday, May 4, 2006 12:11 PM

All replies

  • User-1660928712 posted
    I really second that
    Thursday, May 4, 2006 5:18 PM
  • User-383693083 posted
    Hi,
    it will be really great to have a clear WebParts!!! Please, think about it...

    Thank you
    Friday, June 9, 2006 3:29 PM
  • User-534056067 posted

    It's already on the radar, so to speak, though I don't have any code to share yet.

    As always, this kind of clear guidance is much appreciated. 

    Friday, June 9, 2006 4:02 PM
  • User-534056067 posted

    Would anyone like to share their "vision" of the markup and CSS they'd like to see for web parts and their related controls?  I'd love to get a better sense of what people see as the most egregious problems with the markup rendered today.  And, by contrast, what ought to be rendered instead.

    Friday, June 9, 2006 4:16 PM
  • User-383693083 posted

    Would anyone like to share their "vision" of the markup and CSS they'd like to see for web parts and their related controls?  I'd love to get a better sense of what people see as the most egregious problems with the markup rendered today.  And, by contrast, what ought to be rendered instead.



    Hi,
    okey, i'll try to make a simple "vision", how can WebParts look like without tables. Where can i send it to you than?
    Saturday, June 10, 2006 10:03 AM
  • User-2097903674 posted

    My main objection to the current web part rendering is the use of tables.

    Has there been any further progress on this?

    A good first step would be to at least replace the table mark-up from the read-only/view mode which site visitors will see, and then worry about the editing modes later on. This would at least mean that members of the public visiting a site wouldn't see something riddled with tables.

    I'm willing to give this a go, but have a feeling that only someone with access to the Microsoft source code would be able to do this reliably?

    Any help/ideas would be much appreciated,

    Tom
     

    Wednesday, January 17, 2007 4:53 AM
  • User-2097903674 posted

    I've had a go based on Russ Helfand's excellent post.

    WebPartZoneAdapter.cs

    using System;
    using System.IO;
    using System.Text.RegularExpressions;
    using System.Web;
    using System.Web.UI;

    namespace CSSFriendly
    {
    public class WebPartZoneAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter
    {
    protected override void RenderBeginTag(HtmlTextWriter writer)
    {
    StringWriter sw = new StringWriter();
    HtmlTextWriter hw = new HtmlTextWriter(sw);
    base.RenderBeginTag(hw);
    hw.Flush();
    hw.Close();
    string origTag = sw.ToString();
    string newTag = origTag;
    //string newTag = Regex.Replace(origTag, "\\s*style=[\"'][^\"']*[\"']", "", RegexOptions.Multiline | RegexOptions.IgnoreCase); writer.Write(newTag); } protected override void RenderEndTag(HtmlTextWriter writer)
    {
    StringWriter sw = new StringWriter();
    HtmlTextWriter hw = new HtmlTextWriter(sw);
    base.RenderEndTag(hw);
    hw.Flush();
    hw.Close();
    string origTag = sw.ToString();
    string newTag = origTag;
    //string newTag = Regex.Replace(origTag, "\\s*style=[\"'][^\"']*[\"']", "", RegexOptions.Multiline | RegexOptions.IgnoreCase); writer.Write(newTag); } protected override void RenderContents(HtmlTextWriter writer)
    {
    StringWriter sw = new StringWriter();
    HtmlTextWriter hw = new HtmlTextWriter(sw);
    base.RenderContents(hw);
    hw.Flush();
    hw.Close();
    string origTag = sw.ToString();
    string newTag = origTag;
    //string newTag = Regex.Replace(origTag, "\\s*style=[\"'][^\"']*[\"']", "", RegexOptions.Multiline | RegexOptions.IgnoreCase); writer.Write(newTag); } } }
    Default.aspx
    <%@ Page Language="C#" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <title>ASP.NET 2.0 CSS Friendly Control Adapters 1.0</title>
    </head>
    <body>
    <asp:WebPartManager ID="WebPartManager1" runat="server">
    </asp:WebPartManager>
    <asp:WebPartZone ID="WebPartZone1" runat="server">
    <ZoneTemplate>
    Hello
    </ZoneTemplate>
    </asp:WebPartZone>
    </body>
    </html>

    CSSFriendlyAdapters.browser

    <adapter controlType="System.Web.UI.WebControls.WebParts.WebPartZone"
    adapterType="CSSFriendly.WebPartZoneAdapter" />

    But the  base.RenderEndTag(hw); is causing an error: "A PopEndTag was called without a corresponding PushEndTag."

    Wednesday, January 17, 2007 6:45 AM
  • User-534056067 posted

    Cool stuff.  Let me see if I can help you overcome the error you reported. Consider going with something like this for the adapter code. I'm not 100% it will work for your purposes but my testing seems to indicate that it fix the problem...

    using System;
    using System.IO;
    using System.Text.RegularExpressions;
    using System.Web;
    using System.Web.UI;
    namespace CSSFriendly
    {
        public class WebPartZoneAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter
        {
            protected StringWriter sw = null;
            protected HtmlTextWriter hw = null;

            public WebPartZoneAdapter()
            {
                sw = new StringWriter();
                hw = new HtmlTextWriter(sw);
            }

            protected override void RenderBeginTag(HtmlTextWriter writer)
            {
                base.RenderBeginTag(hw);
                hw.Flush();
                string origTag = sw.ToString();
                string newTag = origTag;
                //string newTag = Regex.Replace(origTag, "\\s*style=[\"'][^\"']*[\"']", "", RegexOptions.Multiline | RegexOptions.IgnoreCase);
                writer.Write(newTag);
            }
            protected override void RenderEndTag(HtmlTextWriter writer)
            {
                base.RenderEndTag(hw);
                hw.Flush();
                hw.Close();
                string origTag = sw.ToString();
                string newTag = origTag;
                //string newTag = Regex.Replace(origTag, "\\s*style=[\"'][^\"']*[\"']", "", RegexOptions.Multiline | RegexOptions.IgnoreCase);
                writer.Write(newTag);
            }
            protected override void RenderContents(HtmlTextWriter writer)
            {
                base.RenderContents(hw);
                hw.Flush();
                string origTag = sw.ToString();
                string newTag = origTag;
                //string newTag = Regex.Replace(origTag, "\\s*style=[\"'][^\"']*[\"']", "", RegexOptions.Multiline | RegexOptions.IgnoreCase);
                writer.Write(newTag);
            }
        }
    }

    Thursday, January 18, 2007 2:22 PM
  • User-2097903674 posted

    Thanks Russ, that gets rid of the error.

    I've managed to use the Regex to change the rendered output, now I just need to find time to go through it more thoroughly and to check it doesn't break any functionality.

    I'll post code here as soon as I've made some progress.
     

    Monday, January 22, 2007 4:24 AM
  • User-384517966 posted

    Not really a vision, just some things I was thinking about...

    1. More so called unobtrusive javascript.
    2. All controls covered (CheckBoxList is a table!)
    3. Somehow offer a better package with all stuff in a DLL, including javascript (more like the recently released Ajax Extensions)
      1. Is the GAC the right place for it?
      2. Is it possible to have everything (including javascript and CSS) in one dll, but still let us style the controls?
    4. Move the project to Codeplex (it did the Ajax Control Toolkit good)
    5. A weblog on the CSSAdapters site
    Anyway, keep up the good work. You do what Microsoft should have done in the first place. I still can't believe they shipped a web framework in november 2005 with so many tables in it...
    Sunday, January 28, 2007 4:20 PM
  • User-384517966 posted

    Oh and one more thing:

    to prevent a battle of the window.onload event handlers either you guys should add your IE6 specific hover script to already existing eventhandlers, or give instructions to us how to do that, because if the cssfriendly scripts execute after mine, they will override any onload events I had set.

    Thanks! 

    PS: another reason to look into the Ajax javascript classes, they offer this functionality. 

    Sunday, January 28, 2007 4:43 PM
  • User955313812 posted

    Hello Folks,

    Thanks for the great ideas on creating WAI compliant pages. I've just had to create a MOSS2007 Site which had to be AA compliant and it proved most exhausting. here is my version of the webpartzoneadapter that worked for me. Please note: this adapter is only used for the output of the contents of the webpartzone and does not support interactions. But using Regex I strip out all the nasty tables that are not needed for output purposes.

     

    using System;
    using System.IO;
    using System.Text.RegularExpressions;
    using System.Web;
    using System.Web.UI;
    namespace CSSFriendly
    {
        public class WebPartZoneAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter
        {
            protected StringWriter sw = null;
            protected HtmlTextWriter hw = null;

            public WebPartZoneAdapter()
            {
                sw = new StringWriter();
                hw = new HtmlTextWriter(sw);
            }

            protected override void RenderBeginTag(HtmlTextWriter writer)
            {//don't render the table tag
            }
            protected override void RenderEndTag(HtmlTextWriter writer)
            {//don't render the table end tag
            }
            protected override void RenderContents(HtmlTextWriter writer)
            {
               base.RenderContents(hw);
    string origTag = sw.ToString();
    string html = Regex.Replace(origTag , @"<[/]?(table|tr|td|[ovwxp]:\w+)[^>]*?>", "", RegexOptions.IgnoreCase);           
    writer.Write(html);
    writer.Write(Control.Controls.Count);
            }
        }
    }


     

    Tuesday, March 6, 2007 8:36 PM
  • User2025654956 posted

    I'm having a bit of a problem with Russ' example.  When I do the example above it prints out two of the same web part.  For example, if I throw in a calendar into the web part zone, it will print two calendar web parts on the page.  It looks like it's adding in an extra table and such and I have no idea why.  I'm simply printing out exactly what the base class renders so I have no clue why this is happening.  When I remove the adapter it only prints 1 calendar.

    Does anybody have a similar problem or know a solution?

    Thanks!

    Shawn

     

    Wednesday, April 4, 2007 12:07 AM
  • User-2097903674 posted

    I've created a complete example which almost works, but still isn't quite right. I need to find a way of stopping the rendering being overridden when in Design view, but I'm not sure how.

     http://www.tjrobinson.net/temp/CssFriendlyWebPartZone.zip

    Thursday, April 26, 2007 10:20 AM
  • User1088575861 posted

    Hi Guys,

    Is it possible to do this using the Web.config file rather than the .browser ?

    Friday, June 29, 2007 7:04 AM
  • User-534056067 posted

    No. That's the simple answer.

    However, I've provided guidance in the past about how to programmatically manipulate any page's list of adapters. Beware, though, that you can tweak that list for the page only during very limited portions of the page's life cycle (e.g., during only a limited number of page events). First, read this, http://forums.asp.net/t/1105715.aspx. Second, consider how you might modify the code to serve your purposes. You've asked if you can avoid touching the .browser file in the App_Browsers folder. You've implied that you would prefer to use an alternative approach, like adding something to a web.config in a folder you, presumably, have control over. You can't do that but you could use the approach outlined in the forum posting I referred to in order to add or remove adapters from the set that the current page is about to use, thus effectively accomplishing what a .browser file is meant to do.

    Of course you'd need to modify the given code a bit. It's original purpose as written is to disable a bunch of adapters for a page. Instead you might want the initialization code to create adapters and add them to the page's list and then remove those when the page is unloaded. I've never tried that, frankly, but it seems plausible to do.

    I'll be very curious to hear what your experience is if you try this approach. Please do write back and good luck to you.

    Friday, June 29, 2007 1:10 PM
  • User1088575861 posted

    Thanks for the help. Your answer helped me convince my seniors that using the .browser file is the best and easiet way. I have now implemented it and it look great (with a little CSS).

    Wednesday, July 11, 2007 6:57 AM
  • User-577735880 posted

    Hi Folks,

            I have the all the examples given here regarding tableless webparts, but ended in disappointment. Even though the code given by alexdean is working, it has its own drawbacks say, if we try to add a datagrid or gridview etc which generates tables are also removed when added as a webpart. here i've given a simple solution for this. i hope it might work properly for all. The rest of the things should be done via CSS.

     

    using System;
    using System.IO;
    using System.Text.RegularExpressions;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls.WebParts;
    using System.Collections;

    namespace CSSFriendly
    {
        public class WebPartZoneAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter
        {
            private WebControlAdapterExtender _extender = null;

            #region Extender
            private WebControlAdapterExtender Extender
            {
                get
                {
                    if (((_extender == null) && (Control != null)) ||
                        ((_extender != null) && (Control != _extender.AdaptedControl)))
                    {
                        _extender = new WebControlAdapterExtender(Control);
                    }

                    System.Diagnostics.Debug.Assert(_extender != null, "CSS Friendly adapters internal error", "Null extender instance");
                    return _extender;
                }
            }
            #endregion

            /// PROTECTED       
            #region OnInit
            protected override void OnInit(EventArgs e)
            {
                base.OnInit(e);

                if (Extender.AdapterEnabled)
                {
                    // Some Code RegisterScripts etc
                }
            }
            #endregion

            #region RenderBeginTag
            protected override void RenderBeginTag(HtmlTextWriter writer)
            {//don't render the table tag
                if (Extender.AdapterEnabled)
                {
                    WebPartZone wp = Control as WebPartZone;
                    if (wp != null)
                    {
                        if(wp.LayoutOrientation==System.Web.UI.WebControls.Orientation.Horizontal)
                            Extender.RenderBeginTag(writer, "AspNet-WebPartZone-Horizontal");
                        else if (wp.LayoutOrientation == System.Web.UI.WebControls.Orientation.Vertical)
                            Extender.RenderBeginTag(writer, "AspNet-WebPartZone-Vertical");
                    }
                }
                else
                {
                    base.RenderBeginTag(writer);
                }
            }
            #endregion

            #region RenderEndTag
            protected override void RenderEndTag(HtmlTextWriter writer)
            {
                if (Extender.AdapterEnabled)
                {
                    Extender.RenderEndTag(writer);
                }
                else
                {
                    base.RenderEndTag(writer);
                }
            }
            #endregion

            #region RenderContents
            protected override void RenderContents(HtmlTextWriter writer)
            {
                if (Extender.AdapterEnabled)
                {
                    WebPartZone wpz = Control as WebPartZone;
                    if (wpz != null)
                    {
                        writer.Indent++;
                       
                        writer.WriteLine();
                        writer.WriteBeginTag("div");
                        writer.WriteAttribute("id", wpz.ID);                   

                        if (!String.IsNullOrEmpty(wpz.CssClass))
                        {
                            writer.WriteAttribute("class", wpz.CssClass);
                        }

                        writer.Write(HtmlTextWriter.TagRightChar);
                        writer.Indent++;
                       
                        WebPartCollection  wpColl = null;

                        ///////////////////// GENERATE WEBPARTS /////////////////////////////

                        if (wpz.WebParts.Count > 0)
                        {
                            wpColl = new WebPartCollection(wpz.WebParts);

                            foreach (WebPart wp in wpColl)
                            {
                                writer.WriteLine();
                                writer.WriteBeginTag("span");
                                if (!String.IsNullOrEmpty(wpz.CssClass))
                                {
                                    writer.WriteAttribute("class", "WebPart");
                                }
                                writer.Write(HtmlTextWriter.TagRightChar);

                                wp.RenderControl(writer);
                                writer.WriteEndTag("span");
                                writer.Indent++;
                            }
                            writer.WriteEndTag("div");
                        }                   

                        writer.Indent--;
                        writer.WriteLine();
                    }
                }
                else
                {
                    base.RenderContents(writer);
                }

            }
            #endregion
        }
    }
     

    i will appretiate any further improvements on this.

    Best Regards, 

    Karthik. 

    Monday, September 17, 2007 8:37 AM
  • User1462465203 posted

    Hi you all,

    I have read all of your posts and I am very impressed of your work. I am doing an e-learning asp.net application and I want to meet WAI-AA requirements. One of them is that the website must work without javascript. I have found out how to minimize a webpart without javascript using a submit button, but I can't render this button in the webpart's header. When I render the button in the webpart's header, the server did not notice the click.

    The code that minimizes the webpart

     

            void boton_Click(object sender, EventArgs e)
            {
                Button boton = (Button)sender;
    
                ((TemplatedWebPartZone)Zone).PublicRaisePostBackEvent("minimize:" + boton.CommandArgument);
                if (true) throw new Exception("we");
    
            }

     
    boton.CommandArgument is the webpart's ID

    I create the buttons in the render method of the webpartzone. Do I have to add them to a Control collection? What I am doing wrong?

    Thanks for your answers and sorry for my bad English.

    Friday, December 28, 2007 7:11 PM
  • User1893902719 posted

    Hi Russ,

    Appologies if this is a bit out of context (nothing to do with webparts), but I tried the above adapter on a "System.Web.UI.WebControls.Calendar"

    and it rendered like this:

     <table id="ctl00_Main_SingleDayInput" class="calendarControl">

    </table>

    got any tips? :-) 

    Cheers.

    Murray 

    Sunday, February 10, 2008 11:35 PM