Eric’s adventures in Sharepoint, technology, and life.
Email icon Home icon
  • Admin page in the Employee Training template

    Posted on May 8th, 2009 Eric 1 comment

    This week my focus was to start testing a software upgrade but that got hijacked due to database issues. So I took the opportunity to finish the final features of a customized Employee Training template that we deployed to handle workshop registrations. The last few hurdles I was working on were usability issues to take it from ok with some workarounds to functional as is.

    I created a Administration page for the admins to manage some functions that they’d need to do. Mainly see a list of upcoming workshops, who is attending, being able to email 1 or all users and being able to export the roster to make sign in sheets. We also have a broken iCal function right now but that will be covered when that gets fixed.

    The data view web part on the page gets information for the courses being offered and when the filled seats is clicked, it passes the courseid variable into the registration list to get the users. Nothing too magical here. But wait, we’ve got a phone number field that is displaying all sorts of jibberish like ,#Domain\user,department,etc. Will looking at this user profile, they don’t have a phone number listed in their Sharepoint profile. Easy fix with some XSLT. I found the td that outputs the phone number and changed it to the following.

    
    
      Not Listed
      
      
      
    
    

    Nothing too hard there.

    CSV export. I thought this was going to be impossible or at least very difficult. A little Googling and I found a great, easy to use jQuery solution called table2CSV. Shout out to Kunal Babre, this script rocks! Used option 1 for this scenario. I created a sample page in SPD and added 2 buttons to the page, copied the HTLM and slapped it into a Content Editor Web part. I added an onclick reference to the jQuery function and presto, a popup window with comma delimited data for the list! Wow, great 2 problems solved with little coding, great for us code stupid people.

    Now comes the email requirements. I needed help from Tony Miller, colleague here and our go to guy for jQuery, to help with this. Again we went back to SPD and added an email id on the td that generates the email address for the registrant list. Now we have our selector to grab this information. One major problem though, all the fields are being displayed as rich text, if we stet them to plain text in the SPD data view options, it returns nobr span mumbo jumbo. So we did some more jQuery embedded in a content editor web part.

    $('td.RegList nobr span a').each(function (i) {
    		$(this).parent().html($(this).text())
    	});
    

    What this does is strip all the HTML in the Registrant table, defined by another id we tacked onto the tds, and returns it’s text value. Good, now we can use the information better.

    I added an additional column to the registration list that will hold the hyperlink so that the admins in 1 click can email an individual registrant. Now with some more jQuery, we can fill in that value. We assigned that td an id of MailtoLink so the function would know where to output the information.

    $('td.MailtoLink').each(function (i) { 
            $(this).html('<a href="mailto:' + 
                   $(this).parent().children('td.email').text() + 
    '?subject=Upcoming Workshop' + '">E-Mail Registrant</a>')
            });

    Boom, hyperlink fills the table cell and we are almost done.

    The last bit was to create a mail all users option. I had to turn to Paul Grenier, a moderator over at Stump the Panel on EndUserSharepoint.com. Great information in STP and on the site. Bookmark and RSS it, the content is amazing. Paul came back with some psuedo code and some jQuery to get it working. It can be found here.

    Tony and I had to make some tweaks to get it working. We removed the validation step from it since the information wasn’t manually input, it came from Sharepoint and Sharepoint provided it as an email address. Our final code loos like this, and is attached to the other button, named EmailButton, I created.

    $('#EmailButton').click(function() {
       var validEmails = [];
       var emailstr;
         $(".email").each(function(i) {
         validEmails.push($(this).text());
        });
       var url = 'mailto:' + validEmails.join(';') + '?subject=My%20Subject';
       var emailwin = window.open(url, "EmailWindow");
       emailwin.close();
      });
    }); 

    This process has been a lot of work but has been extremely rewarding. The feedback I’m receiving from the group this is designed for has been so positive and they are very excited. What more can you ask for than for people who are excited to use Sharepoint? Many thanks to Tony, Paul, Laura, and the Twitterverse that has helped with some of these issues.

    Post to Twitter Post to Plurk Plurk This Post Post to Yahoo Buzz Buzz This Post Post to Delicious Delicious Post to Digg Digg This Post Stumble This Post

  • Modifying Employee Training template

    Posted on April 8th, 2009 Eric 2 comments

    In my last blog post, I mentioned I was starting to dislike the fab 40 templates. This post describes how we (myself and my colleague Tony Miller) fixed an inherent issue with one of these templates. This post goes into steps done after following these three blog posts:

    Here is some background on the template if you aren’t familiar. The site is designed so that an instructor can add courses they wish to teach to a list. Users come into the site and see the courses available and click a link to go to the Dispform to register. However there is a glaring security issue here. The navigational bar is present for users to delete a course! If a permission level is created to stop them from deleting items, then they can’t unregister for a course. This bar also contains a function to export the item to Outlook.

    ms-toolbar

    ms-toolbar

    So what do we do to fix it? I hope that’s why you’re reading.

    The first thing I did was to create a calculated column in the course list that creates an iCal hyperlink. I created the function as =CONCATENATE(”https://MyDomain/sites/cferegistration/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List=%7B242652E5%2D0492%2D4C2F%2D8B37%2D06C9A59B0020%7D&CacheControl=1&ID=”,ID,”&Using=event.ics”). Easy enough. I then used a little of Paul Grenier’s jQuery magic to clean that up. Functionality restored for the users. Now to get it on the Dispform.

    Here I opened Sharepoint Designer and opened the Dispform associated with the Courses list. I added @iCal, iCal to the XSL data fields at the top of the transform. Then I added

    <tr style="display: none">
    	<td width="190px" valign="top" class="ms-formlabel">
    		<H3 class="ms-standardheader">
    			<nobr>Export to Outlook</nobr>
    		</H3>
    	</td>
    	<td width="400px" valign="top" class="ms-formbody">
    		<xsl:value-of select="@iCal/>
    	</td>
    </tr>

    an thought I’d be golden. well, I was wrong. It created a nightmare of a URL and needed a way to make a nice hyperlink so users could just click it and save the item. After about an hour of trying all sorts of things, Tony realized that Sharepoint was using XSL version 1.0. With this in hand we were able to utilize a replacement function to clean out the amp; values and create a nice hyperlink.

    We added

    <xsl:template name="replace-substring">
      <xsl:param name="original"/>
      <xsl:param name="substring"/>
      <xsl:param name="replacement" select="''"/>
      <xsl:variable name="first">
        <xsl:choose>
          <xsl:when test="contains($original, $substring)">
            <xsl:value-of select="substring-before($original, $substring)"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$original"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:variable name="middle">
        <xsl:choose>
          <xsl:when test="contains($original, $substring)">
            <xsl:value-of select="$replacement"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text></xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:variable name="last">
        <xsl:choose>
          <xsl:when test="contains($original, $substring)">
            <xsl:choose>
              <xsl:when test="contains(substring-after($original, $substring), 
                                       $substring)">
                <xsl:call-template name="replace-substring">
                  <xsl:with-param name="original">
                    <xsl:value-of select="substring-after($original, $substring)"/>
                  </xsl:with-param>
                  <xsl:with-param name="substring">
                    <xsl:value-of select="$substring"/>
                  </xsl:with-param>
                  <xsl:with-param name="replacement">
                    <xsl:value-of select="$replacement"/>
                  </xsl:with-param>
                </xsl:call-template>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="substring-after($original, $substring)"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text></xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:value-of select="concat($first, $middle, $last)"/>
    </xsl:template>

    to the top of the transform after the following code.

    <xsl:variable name="dvt_1_automode">0</xsl:variable>

    Then we changed the values being displayed by altering the output code to:

    <tr>
    	<td width="190px" valign="top" class="ms-formlabel">
    		<H3 class="ms-standardheader">
    			<nobr>Export to iCal</nobr>
    		</H3>
    	</td>
    	<td width="400px" valign="top" class="ms-formbody">
    		<xsl:variable name="iCalLink">
    		<xsl:call-template name="replace-substring">
    		<xsl:with-param name="original" select="@iCal"/>
    		<xsl:with-param name="substring" select="string('amp;')"/>
    		<xsl:with-param name="replacement" select="string('')"/>
    		</xsl:call-template>
    		</xsl:variable>
    		<a href="{$iCalLink}">Export to iCal</a>
    	</td>
    </tr>

    Now we had a working hyperlink in our item details.

    Whew, almost done! Last cleanup item is to remove the toolbar so users cannot delete items. We cranked up Firefox and Firebug and found the toolbar easily enough. A few console trial and errors and we had removed it. Instead of putting it into a CEWP like I normally would, I just added it to the page head on the dispform. That code is:

    <script type="text/javascript">
     
    $(function() {
    	$('table[@id$=toolBarTbl].ms-toolbar').remove();
    });
    </script>

    Save, refresh and viola! the dispform now looks like the below image. This might not have been the easiest method to do this, and I’d be happy to hear other ways of doing it.

    dispform.aspx

    dispform.aspx

    Post to Twitter Post to Plurk Plurk This Post Post to Yahoo Buzz Buzz This Post Post to Delicious Delicious Post to Digg Digg This Post Stumble This Post