Use JavaScript to enable formatting of Data View UI controls

andy Hi, Andy Lewis here again.  Today I'm here to talk about how to work around a certain type of challenge you might run into when trying to customize the user experience (UX) of a form in a SharePoint application.

When I began trying to make the leap from generic web development into SharePoint development, I found I needed to get used to the fact that I no longer had direct control of some of the key building blocks of the UX: the HTML controls. In SharePoint, the HTML controls are emitted out of server-side controls. You don't have direct control of the markup that is sent to your customer's web browser.

Note: In this article, some of the material that explains how to perform the more basic tasks is hidden from view by default if you have JavaScript turned on. If you want to print this article with all the material included, click here: Show All.

My users need more pixels!

As I began getting used to working within the context of SharePoint, one challenge I faced was figuring out how to make even simple adjustments to the UX, such as modifying the width and the height of a user interface (UI) control.  Simply put, I wanted to make my customers more comfortable by giving them more pixels!

Modify the size of a text-value field

For some fields, their presentation is fairly easy to adjust.  For example, in Modify the lengths of List Form Fields, John Jansen showed how to use a little CSS to modify the width of the textbox field used to edit the Title value of a SharePoint list.

While playing around in code view, I noticed another option.  The SharePoint:formfield tag accepts an attribute called DisplaySize.  If you add this attribute to the tag (for example DisplaySize="100") in your custom form, then you can also make a text value field (such as the standard Title field), longer. (This attribute does not work for all SharePoint list column types.)

But let's move on to how to make a customization that is a bit more challenging.

Expand size of the lists for a multi-value lookup column

I was recently working on a custom form that included a multi-value lookup field.  SharePoint renders the UX for this kind of field in the form of two select list controls and two button controls to move items between the two lists.

list_form_web_part_multi-value_lookup

The catch is that these controls are wrapped inside other HTML tags, one of which blocks CSS from working because it has a hardcoded style in it. The structure that is sent by the server to the web browser looks something like like this if you edit the source in SharePoint Designer and selected one of the select controls:

<span> <table-ms-long> <tr> <td.ms-input> <div> <select>

While working on the application I was building, I was feeling really motivated to make the two select controls bigger because my users would be choosing from a long list of items, some of which would be very wide.  In short, I wanted to be able to offer the customer wider and taller controls like these:

data_form_web_part_multi-value_lookup_custom

I expect that this is probably a common UX enhancement that site owners want to make, which is why I decided to write this article.

The site

To follow the examples below, you need to create a Team Collaboration site that includes:

  • A custom list called Projects
  • A Tasks list (included by default in a new Team site) that has a multi-value lookup column that looks up the Title from the Projects list.

Create custom NewForm for the Tasks list

Important: Before you modify any of the three core list forms (DispForm, EditForm, or NewForm), you must always remember one rule: Never delete the ListFormWebPart object.   If you do, you may break your list! In the steps below, I'll explain how to hide this form and replace it with your own custom form.

  1. Create the select-container style that defines the width and height of the select controls the user uses to modify values in the multi-value lookup column:

    1. On the File menu, point to New, and then click CSS.

    2. Add the following code to the new CSS file:

       .select-container div {
         width:300px;
         height:150px;
      }
      
    3. On the File menu, click Save and then use the Save dialog box to save the file as shared_styles.css in the root directory of your site.

  2. Create the removeLocalStyleAttributes() function that you will use to remove the hardcoded width and height style attributes that block your select-container style from working correctly:

    1. On the File menu, click New, click JavaScript, and then click OK.

    2. Add the following code to the new JavaScript file:

       function removeLocalStyleAttributes() {
         var coll = document.body.getElementsByTagName("div");
      
         for(x=0;x < coll.length; x++)
         {
            if(coll[x].className == "select-container") { 
               var collDivControls = coll[x].getElementsByTagName("DIV");
      
               for(y=0;y < collDivControls.length; y++)
               {
                  collDivControls[y].style.width = null;
                  collDivControls[y].style.height = null;
               }
            }
         }
      }
      
    3. On the File menu, click Save and then use the Save dialog box to save the file as shared_functions.js in the root directory of your site.

  3. In the Lists/Tasks folder, open NewForm.aspx.

  4. Hide and close (do not delete! ) the WebPartPages:ListFormWebPart object. How?

    1. In Design view, right-click the WebPartPages:ListFormWebPart object and then choose Web Part Properties from the properties menu.
    2. Expand the Layout group.
    3. Check the Close the Web Part and Hidden checkboxes.
    4. Note: the WebPartPages:ListFormWebPart object is still visible in SharePoint Designer, but it will be hidden to customers of your site.
  5. Insert a new WebPartZone at the top of the inside of the asp:Content PlaceHolderMain tag. How?

    1. In Code view, find this asp:Content tag: <asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">. Place the cursor immediately after this asp:Content tag.
    2. On the Insert menu, click SharePoint Controls, and then click Web Part Zone.
    3. Switch to Design view to see the new WebPartZone.
  6. In the new WebPartZone you just created, insert a New Item Form DataFormWebPart that includes the Projects field and any other fields you need in the form. How?

    1. In Design view, select the WebPartZone you just created.
    2. On the Data View menu, click Insert Data View.
    3. Click the link that appeared in the middle of the Data View: Click a data source in the Data Source Library, and then click show Data.
    4. In the the Data Source Library task pane, in the SharePoint Lists group, click the Tasks list, and then click Show Data.
    5. Press and hold down the CTRL key as you select the following fields from the Data Source Details task pane: Assigned to, Title, Priority, Status, % Complete, Description, Start Date, Due Date, and Projects.
    6. Click Insert Selected Fields as, and then click New Item Form.
  7. In Code view, add the following asp:Content tag to the page:

     <asp:Content contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server">
    
       <link rel="stylesheet" type="text/css" href="../../shared_styles.css" 
          mce_href="../../shared_styles.css"> 
    
       <script src="../../shared_functions.js" mce_src="../../shared_functions.js" 
          type="text/javascript"></script>
    
       <script type="text/javascript">
          _spBodyOnLoadFunctionNames.push("removeLocalStyleAttributes");
       </script>
    
    </asp:Content>
    
  8. In Code view, in the XSL code of the DataFormWebPart, find the SharePoint:formfield tag for the Projects field and wrap it with a div tag that has select-container as the value of its class attribute:

     <td width="75%" class="ms-vb">
       <div class="select-container">
       <SharePoint:FormField runat="server" id="ff5{$Pos}" ControlMode="New" 
          FieldName="Projects" __designer:bind="{ddwrt:DataBind('i',concat('ff5',$Pos),
          'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Projects')}" />
       </div>
       <SharePoint:FieldDescription runat="server" id="ff5description{$Pos}" 
          FieldName="Projects" ControlMode="Edit" />
    </td>
    

Closing

Thanks for taking the time to read this article.  What is your favorite JavaScript tip?  If you have a blog article about it, please post a comment and link to your article.

I'd be interested in hearing your opinion on a subject I've been wondering about for a while.  You will notice that in some of my articles, including this one, I offer what some might call "remedial" instructions, but I hide them behind a JavaScript "How?" widget to keep the text from getting bogged down, especially for more experienced customers who don't need the extra help.

The question on my mind is this: How many of you actually find these "How?" instructions useful?  I sometimes feel tempted to save myself the fairly significant amount of time required to enumerate these steps.  And yet, I'm not sure that a statement like this is going to be helpful enough for many folks: In the new WebPartZone you just created, insert a new DataFormWebPart New Item Form that includes the Projects field. What do you think?

New job

Finally, I'm going to be transitioning to a new role here at Microsoft.  I just started working for a team that produces user education content for Visual Studio Team System.  I want to thank the SharePoint Designer product team for so many things.  They invited me to participate here on this blog, and they have given me support, guidance, and feedback on my work.  And of course, special thanks to you for reading and participating with your comments and sometimes your very useful corrections. 

Starting a new job always makes me think about how I've been doing my work, and what things I want to try doing differently.  So I'm using this change as a kick in the pants to myself to put up my own shingle and set up a blog (finally; I am such a late adopter to this trend!). As of this writing, there is not much there, but I will endeavor to add more to the blog and keep it fresh in the future.

Andy