Web Application Design (part 1)

June 11, 2008 at 3:42 pm 10 comments

Sorry I’ve been away from posting for so long. I’ve been working on a large web application and the design and implementation is taking up a lot of my ‘blogging’ time. But, I use this blog as my notes to remind me how I did certain things, so I need to update it with some new tricks before I completely forget them…

I’ve been adding JavaScript into my projects for a while now, and I’ve started to get a good feel for what I can and can’t do in SharePoint. The following series of tips are very basic and can be accomplished by novice SharePoint designers with ease. If you have any questions, or suggestions to improve my rudimentary code, feel free to post a comment so everyone can learn from the discussions.

The application I am designing requires users to create ‘codes’ for use in drop-down lists. The codes are stored in a custom list which contains only two columns: Code Name (Title) and Active (checkbox). For this series of posts we are going to create a simple list of Customer Statuses. The web application stores Customer Data and the status field in the Customer Data is a lookup to the values in the Customer Status list. The users can therefore add or change codes the drop-down without having to fiddle with SharePoint. The logic used in these examples can be applied to almost any kind of custom list: employee lists, inventory lists, issue tracking lists etc.

I want one page where the user can see the current items in a list, edit the existing items, and create new items in the list. I realise that this can be accomplished by using the DispForm.aspx, NewForm.aspx, and EditForm.aspx but, I want to maintain only one form.

Note: I have started using my own custom masterpage and designing my aspx pages from scratch. I don’t know if these instructions will be affected by placing the forms in an existing SharePoint page, for example – adding a display list to the NewForm.aspx page. I don’t think that it will, but please let me know if it does.

Step One: Display the current contents of the list

Pre-requisite: Create a custom list and populate it with a couple of items.

The primary objective of the page I am creating is to show users the current items in the list, in our example I want to show the users which Customer Status codes already exist in the list. Let’s start by creating a Multiple Item Data View Web Part and place it on the page. I’m pretty sure I’ve covered this in a previous topic but here’s quick recap:

  1. Click anywhere on the page, outside of any existing Web Parts, and insert a Data View.
  2. Click on the Data View and then select the Customer Status list from the datasource library and then click Show Data.
  3. Hold CTRL and select the fields you want to add.
  4. Click on the Insert Selected Fields As button and select Multiple Item View.

The grid (table) will appear on the page and display the contents of the list.

Step Two: Add a an Edit Form

We want the users to be able to click on an item in the grid and be able to edit the item on the same page. Let’s add a Single Item Form Data View.

  1. Locate the end tag for the previous Web Part: </WebPartPages:DataFormWebPart>
  2. Insert a <br /> (to create some space) after the end tag.
  3. Insert a Data View after the <br /> tag.
  4. Click on the Data View and then select the Customer Status list from the datasource library and then click Show Data
  5. Hold CTRL and select the fields the user can edit
  6. Click on the Insert Selected Fields As button and select Single Item Form.

The new form will appear on the page and show the first item in the Customer Status list.

Step Three: Connect the Forms

If you recall, from the previous step, we want the user to be able to click an item in the first grid and have that set the item that can be edited in the edit form. We are going to create a Web Part Connection.

  1.  Right-click a label field, in the edit form we created in Step Two, and select Web Part Connections from the pop-up menu.
  2. When the Web Part Connections Wizard dialog box opens, select Get Parameters From in the drop-down list and click Next.
  3. Verify the radio button for Connect to Web Part on this Page is selected and click Next.
  4. Verify the target Web Part is Customer Status and the target action is Send Row of Data To and click Next.
  5. Click on the Create New Parameter option in the Inputs to Customer Status column.
  6. Name the new parameter “PassedID” and click OK.
  7. Select the ID column from the Columns in Customer Status column in the same row as the PassedID parameter. You are associating the ID column in the display grid with the PassedID parameter in the edit form.
  8. Click Next.
  9. Verify that the Create a Hyperlink On option is set to the Status column.
  10. Select the Indicate Current Selection Using checkbox and select Status from the pop-up list.
  11. Click Next.
  12. Click Finish.

IMPORTANT: I have found a possible bug in SharePoint Designer. In my installation (could just be me), when I have completed the creation of the Web Part Connection sometimes the connection is still not “active”. You can verify the connection was created properly by right-clicking a field in the edit form and selecting Web Part Connections from the pop-up. If the connection was created properly, it will appear in a list. If it was not created properly, the web part connection wizard will launch again. I sometimes find that I have to run the wizard twice (just clicking Next all the way through it the second time) to get the connection to “activate”.

Now that you have the connection established, we need to create a filter on the edit form.

  1. Select the edit form and select Dataview > Filter from the file menu.
  2. Create a filter: ID equals [PassedID]
  3. Click OK

Okay, we now have a grid that shows all of the items in the Customer Status List and if the user clicks on the Status it can be edited in the edit form just below the grid. SharePoint creates a hyperlink on the Status field and highlights the currently selected field.

Step Four: Hyperlink on the Row not the Column

In our current example, the user has to click the Status to change the current item in the edit form. I want to change it so the user can click anywhere in the row and update the edit form. Here is where things get a little scary for beginners. I’m going to try to explain this as clearly as possible because learning this trick is important to gaining control over SharePoint pages.

SharePoint uses HTML tables to structure the layout of the forms and pages. HTML tables always follow the same pattern:

  • The table always begins with the <table> tag and ends with the </table> tag.
  • Each row in the table starts with <tr> and ends with a </tr>. The term “tr” stands for table row.
  • Each column in a row starts with a <td> and ends with a </td>. The term “td” stands for table data cell (I know it’s not very intuitive!!).
  • SharePoint uses XSL to create the table dynamically. SharePoint specifies the value of the first row and the XSL creates as many rows as needed to contain all of the data.

Once we understand these four truths, we can begin to control the way SharePoint behaves (Don’t worry if they seem confusing right now, once we delve into the code it will start to make more sense). If you set the view in SharePoint Designer to SPLIT the screen, you can see the code and the design at the same time. Click on the first Status field in the display form and you can see the code that creates the field. In our example, SharePoint has placed the hyperlink tag <a> inside of the column <td> tag, here’s the code directly from SharePoint (with my comments in red italics):

<tr> (create a row in the table – we’re going to need this tag very soon)
   <xsl:if test=”position() mod 2 = 1″> (everything between the XSL tags is programming stuff)
    <xsl:attribute name=”class”>ms-alternating</xsl:attribute>
   </xsl:if>
   <xsl:if test=”$dvt_1_automode = ‘1’” ddwrt:cf_ignore=”1″>
    <td class=”ms-vb” width=”1%” nowrap=”nowrap”>
     <span ddwrt:amkeyfield=”ID” ddwrt:amkeyvalue=”ddwrt:EscapeDelims(string(@ID))” ddwrt:ammode=”view”></span>
    </td>
   </xsl:if>(end programming stuff)
   <td class=”ms-vb”> (this is the first column the user can see – in our case the Status column)
    <a target=”_self”> (this is the hyperlink we are looking for)
    <xsl:attribute xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” name=”href”>
     <xsl:variable name=”cursel”>dvt_curselkey={
      <xsl:call-template name=”dvt.gencurselkey”>
       <xsl:with-param name=”RowPath” select=”.” />
      </xsl:call-template>
      }</xsl:variable>
     <xsl:variable xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” name=”fields”>@ID=<xsl:value-of select=”ddwrt:ConnEncode(string(@ID))” /></xsl:variable>
     <xsl:text>javascript:</xsl:text>
     <xsl:value-of select=”ddwrt:GenFireConnection(concat(‘g_fed65d2c_6c05_48ed_b84a_0ddc96bdc324*’,$fields),string($cursel))”></xsl:value-of>
    </xsl:attribute>
    <xsl:attribute name=”style”>
     <xsl:if test=”$CurrentRowKey = $dvt_curselkey”>font-weight: bold;</xsl:if>
    </xsl:attribute>
    <xsl:value-of select=”@Title” />
    </a> (this is the end of the hyperlink tag) </td> (this is the end of the column)
   <td class=”ms-vb”>
    <xsl:choose>
     <xsl:when test=”@Active=’1′ or msxsl:string-compare(string(@Active),’Yes’,”,’i’)=0 or msxsl:string-compare(string(@Active),’True’,”,’i’)=0″>Yes</xsl:when>
     <xsl:otherwise>No</xsl:otherwise>
    </xsl:choose>
   </td>
   </tr> (this is the end of the row)

I want to break the hyperlink code down a little more for you. Here is the contents of the <a> (hyperlink) tag explained in more detail:

<a target=”_self”> (start the hyperlink, but when clicked just reload the current page: target = self)

(This section contains the Web Part Connection Code – very simply put, when I get clicked send the value of the ID field in the current row to the edit form)
<xsl:attribute xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” name=”href”>
     <xsl:variable name=”cursel”>dvt_curselkey={
      <xsl:call-template name=”dvt.gencurselkey”>
       <xsl:with-param name=”RowPath” select=”.” />
      </xsl:call-template>
      }</xsl:variable>
     <xsl:variable xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” name=”fields”>@ID=<xsl:value-of select=”ddwrt:ConnEncode(string(@ID))” /></xsl:variable>
     <xsl:text>javascript:</xsl:text>
     <xsl:value-of select=”ddwrt:GenFireConnection(concat(‘g_fed65d2c_6c05_48ed_b84a_0ddc96bdc324*’,$fields),string($cursel))”></xsl:value-of>
    </xsl:attribute>

(This section contains the highlight code – set the currently clicked item to bold font)
    <xsl:attribute name=”style”>
     <xsl:if test=”$CurrentRowKey = $dvt_curselkey”>font-weight: bold;</xsl:if>
    </xsl:attribute>

(This is the data field to display)
    <xsl:value-of select=”@Title” />

    </a>(end the hyperlink)

I hope all of that “random” code makes a little more sense now. By recognising the basic tags in the code, we can locate and manipulate individual columns and rows. We wanted to move the <a> tag so that the hyperlink affects the whole row in the grid. The next section of code shows you the altered code and I will highlight what I moved:

<tr>
<a target=”_self”>
    <xsl:attribute xmlns:xsl=”
http://www.w3.org/1999/XSL/Transform” name=”href”>
     <xsl:variable name=”cursel”>dvt_curselkey={
      <xsl:call-template name=”dvt.gencurselkey”>
       <xsl:with-param name=”RowPath” select=”.” />
      </xsl:call-template>
      }</xsl:variable>
     <xsl:variable xmlns:xsl=”
http://www.w3.org/1999/XSL/Transform” name=”fields”>@ID=<xsl:value-of select=”ddwrt:ConnEncode(string(@ID))” /></xsl:variable>
     <xsl:text>javascript:</xsl:text>
     <xsl:value-of select=”ddwrt:GenFireConnection(concat(‘g_fed65d2c_6c05_48ed_b84a_0ddc96bdc324*’,$fields),string($cursel))”></xsl:value-of>
    </xsl:attribute>

   <xsl:if test=”position() mod 2 = 1″>
    <xsl:attribute name=”class”>ms-alternating</xsl:attribute>
   </xsl:if>
   <xsl:if test=”$dvt_1_automode = ‘1’” ddwrt:cf_ignore=”1″>
    <td class=”ms-vb” width=”1%” nowrap=”nowrap”>
     <span ddwrt:amkeyfield=”ID” ddwrt:amkeyvalue=”ddwrt:EscapeDelims(string(@ID))” ddwrt:ammode=”view”></span>
    </td>
   </xsl:if>
   <td class=”ms-vb”>
        <xsl:attribute name=”style”> (we didnt need to move the style code)
     <xsl:if test=”$CurrentRowKey = $dvt_curselkey”>font-weight: bold;</xsl:if>
    </xsl:attribute>
    <xsl:value-of select=”@Title” />
    </td>
   <td class=”ms-vb”>
    <xsl:choose>
     <xsl:when test=”@Active=’1′ or msxsl:string-compare(string(@Active),’Yes’,”,’i’)=0 or msxsl:string-compare(string(@Active),’True’,”,’i’)=0″>Yes</xsl:when>
     <xsl:otherwise>No</xsl:otherwise>
    </xsl:choose>
   </td>
   <td class=”ms-vb”>
    <xsl:value-of select=”ddwrt:FormatDate(string(@Created), 1033, 5)”/>
   </td>
   <td class=”ms-vb”>
    <xsl:value-of select=”@Author” disable-output-escaping=”yes”/>
   </td></a> (the location of this tag is very important – before the </tr> but AFTER the </td> )
  </tr>
 
As you can see in the example code, I have moved the <a> tag from the inside of the column ( <td> ) to the inside of the row ( <tr> ). If I save and preview this page, I can now click anywhere in the row to change the value in the edit form.

Note: the mouse pointer doesn’t change to reflect the row is a hyperlink but we will correct that in the next step.

Step Five: Change Mouse Pointer on Hover

Changing the mouse pointer when over an item is a very useful JavaScript tip. Users recognise links on a web page from the underline or from the mouse pointer changing when over the link.

If you recall the code I showed you in Step Four, I noted that we would need the <tr> tag. Locate the <tr> tag (the easiest way is to switch to split view and click the first row in the display form). Add the following code to the <tr> tag:

<tr onmouseover=”this.style.cursor=’hand'”>

All I’ve done here is tell the browser to initiate the JavaScript on the row. The JavaScript (onmouseover) activates when the mouse pointer is over the item, in this case the row. The values in the quotes tell the JavaScript to change the cursor (mouse pointer) to the hand. Insert the code in your page and preview the page. When you move the mouse over a row in the display form, it will change to a ‘hand’ cursor and your user knows that they can click there.

As you might have already guessed, you can use this little trick in a lot of other situations.

Step Six: Add Some Usability

When I look at the forms we have just created I’m happy with the functionality but, I am not so impressed with the usability. If the list contains 200 items, how do you expect the user to see the little bold highlight on the currently selected row? I want to add some custom code to the forms to improve the usability.

Highlight the Row

There are two types of highlight that I like to use when displaying a grid full of data. If the grid has the edit form on the same page, I want the currently selected row to be highlighted. If the grid links to an edit form on a different page, I want the row to highlight when the mouse pointer moves over it.

In our example, the edit form is on the same page so I want the row to highlight when the user clicks it. If you were paying attention in Step Four, you might have seen that this functionality already exists in a slightly modified format:

    <xsl:attribute name=”style”>
     <xsl:if test=”$CurrentRowKey = $dvt_curselkey”>font-weight: bold;</xsl:if>
    </xsl:attribute>

The XSL code sets the style on the column when it is the currently selected item. As is, it gives the Status field a tiny little bold affect. Let’s tinker with the code a little:

    <xsl:attribute name=”style”>
     <xsl:if test=”$CurrentRowKey = $dvt_curselkey”>background-color: #ffffe0;</xsl:if>
    </xsl:attribute>

As you can see, I only changed the style value in the XSL code. The code now sets the background of the selected column to be a nice pale yellow color. You can specify any color you want and you can also change almost any style you want. Here are some examples:

   border: 1px solid red; (set the border of the selected column to red)
   text-decoration: underline; (underline the text in the selected column)

You should experiment with the different combinations of CSS style attributes and values. If you tested and previewed the change, you are probably wondering why only one column is affected. The code for the style is contained with the <td> tag so it affect only the single column. If you copy and paste the style code into each of the columns – it will affect all of the columns. You can’t move the style code up to the row without messing up the web part connection – so for now you have to copy and paste it. Here is the sample code:

<tr>
<a target=”_self”>
    <xsl:attribute xmlns:xsl=”
http://www.w3.org/1999/XSL/Transform” name=”href”>
     <xsl:variable name=”cursel”>dvt_curselkey={
      <xsl:call-template name=”dvt.gencurselkey”>
       <xsl:with-param name=”RowPath” select=”.” />
      </xsl:call-template>
      }</xsl:variable>
     <xsl:variable xmlns:xsl=”
http://www.w3.org/1999/XSL/Transform” name=”fields”>@ID=<xsl:value-of select=”ddwrt:ConnEncode(string(@ID))” /></xsl:variable>
     <xsl:text>javascript:</xsl:text>
     <xsl:value-of select=”ddwrt:GenFireConnection(concat(‘g_fed65d2c_6c05_48ed_b84a_0ddc96bdc324*’,$fields),string($cursel))”></xsl:value-of>
    </xsl:attribute>

   <xsl:if test=”position() mod 2 = 1″>
    <xsl:attribute name=”class”>ms-alternating</xsl:attribute>
   </xsl:if>
   <xsl:if test=”$dvt_1_automode = ‘1’” ddwrt:cf_ignore=”1″>
    <td class=”ms-vb” width=”1%” nowrap=”nowrap”>
     <span ddwrt:amkeyfield=”ID” ddwrt:amkeyvalue=”ddwrt:EscapeDelims(string(@ID))” ddwrt:ammode=”view”></span>
    </td>
   </xsl:if>
   <td class=”ms-vb”>
    <xsl:attribute name=”style”>
     <xsl:if test=”$CurrentRowKey = $dvt_curselkey”>background-color: #ffffe0;</xsl:if>
    </xsl:attribute>
    <xsl:value-of select=”@Title” />
    </td>
   <td class=”ms-vb”>
   <xsl:attribute name=”style”>
     <xsl:if test=”$CurrentRowKey = $dvt_curselkey”>background-color: #ffffe0;</xsl:if>
    </xsl:attribute>

    <xsl:choose>
     <xsl:when test=”@Active=’1′ or msxsl:string-compare(string(@Active),’Yes’,”,’i’)=0 or msxsl:string-compare(string(@Active),’True’,”,’i’)=0″>Yes</xsl:when>
     <xsl:otherwise>No</xsl:otherwise>
    </xsl:choose>
   </td></a></tr>

In our example, we only have two columns showing. If you have multiple columns, all you need to do is locate the starting tag for each column: <td class=”ms-vb”> and place the style code snippet directly after it.

To sum up, we now have a single aspx page that contains a grid displaying of all of the items in a custom list with an edit form directly below the grid. The user can click anywhere in a row in the grid and the selected row is highlighted and the edit form updates to show the selected item. The user can then edit the item in the edit form and click save and see the changes in the display grid.

In the next part, I will add a New button to the page which will hide the edit form and show a new item form which will allow users to add new items to the display grid from the same aspx page.

Advertisements

Entry filed under: SharePoint Designer, SharePoint Tips and Tricks, Web Application. Tags: , , , , , , , , .

Logging Workflows for Troubleshooting Web Application Design (part 2)

10 Comments Add your own

  • 1. Web Application Design (part 2) « Splitting Shares  |  June 11, 2008 at 7:15 pm

    […] part 1, I covered the steps for creating and customising the display and edit forms for a custom list on a […]

    Reply
  • 2. SPbb  |  August 14, 2008 at 8:17 pm

    I wonder if you can give me an idea on how to highligh the datalist selected row? by just clicking or mouse over?

    Thanks

    Reply
  • 3. SPbb  |  August 15, 2008 at 3:39 pm

    Hi,

    This post looks interesting!

    I’m a newbie with Sharepoint. Do you mind to make it detailed a little bit? Like what Datalist/Columns to be created? Screenshot would be great..

    Thanks alot!

    Reply
  • 4. SPbb  |  August 18, 2008 at 4:18 pm

    Hi,

    this line of code don’t work, why?

    background-color: #ffffe0;

    I’m using:
    WSS3.0 SP1
    Sharepoint Designer

    Any help is very much appreciated!

    Reply
  • 5. SPbb  |  August 18, 2008 at 9:33 pm

    Can anybody send me a working template for this one? I did’nt able to make it to run.. 😦

    HELP!

    Thanks

    Reply
  • 6. ThiNg  |  August 18, 2008 at 9:51 pm

    Here come some answers… All of the posts look like they were submitted by the same person? SPbb?

    I will Copy and Paste the question and then answer:

    Q: I wonder if you can give me an idea on how to highligh the datalist selected row? by just clicking or mouse over?

    A: I think that what you are asking is covered in the post. You use SP Designer to add a conditional style to the row and then you modify the code from there. Send me specifics and I will help in more detail.

    Q: I’m a newbie with Sharepoint. Do you mind to make it detailed a little bit? Like what Datalist/Columns to be created? Screenshot would be great..

    A: I’ve definitely been told that I need to add screen shots to my blog posts. As soon as I have time, I will be adding them to the blogs. I wouldn’t mind creating a test scenario as much of the stuff used in my examples would belong to my current employer 🙂 I think I will take the time, soon, to create a temporary test application and then I can publish the data/screenshots.

    Q:this line of code don’t work, why? background-color: #ffffe0;

    A: This line of code has to be inside of the other sharepoint code, in order to call the CSS code you need to enclose it in the XSL markup:

    background-color: #ffffe0;

    Note: Pay careful attention to the opening and closing tags when you edit.

    Q:Can anybody send me a working template for this one? I did’nt able to make it to run..

    A: I guess this comes back to my other answer of providing a more detailed explanation. I will create a fake web application with fake data and post the step by step with screenshots as soon as I can.

    Thanks for reading – and being so patient!!

    Reply
  • 7. SPbb  |  August 19, 2008 at 3:11 am

    Thanks a lot Thing..

    The part that make me confused was on creating the datalist part, how many datalist to create and the field with that list.

    🙂 I’m kind of beginner of SP…. SORRY FOR THAT!

    Reply
  • 8. SPbb  |  August 19, 2008 at 4:12 pm

    Hello ThiNG,

    How many lists I need to create for this project? and what are fields. Do you mind to guide me to do that?

    🙂 PLEASE! thanks

    Reply
  • 9. SPbb  |  August 19, 2008 at 7:22 pm

    ThiNG,

    I made it to work!

    THANKS MAN!

    KEEPUP THE GOOD WORK and WISH YOU LUCK!

    Reply
  • 10. Mel Pama  |  August 19, 2009 at 10:36 pm

    What does this actually do

    test = “$dvt_1_automode = ‘1′” ddwrt:cf_ignore=”1″

    I know what the first part is but why

    ddwrt:cf_ignore=”1”

    thanks,

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed



%d bloggers like this: