Immediate Solutions for Everyday Business Problems

EndUserSharePoint.com: Extending Issues and Tasks: Part 3

Original Publication Date: Tuesday, October 7, 2008
Filed Under: Libraries and Lists, Paul Grenier, Tips and Tricks
SharePoint User Level: Power User

 

Extending Issues and TasksIf you followed along with parts 1 and 2, you have a link between Issues and Tasks and a way to surface Tasks related to a displayed Issue.  But we’re not done.  Our original question from Stump the Panel has one more requirement:

“not to be able to close an issue unless all its tasks are complete”

Developers with a handle on how SharePoint works might create an Event Receiver that enforces this requirement through a custom workflow.  A SharePoint Designer workflow might also work but I anticipate problems matching multiple Tasks to the Issue being edited.  Besides, we’ve come this far without SPD so let’s keep our work “on the surface.”

SharePoint uses javascript to submit forms

The creators of that script added a “hook” for custom validation called PreSaveAction. This function gets called during the submit action but was never defined so we can create our own.  We have a simple strategy: identify Tasks surfaced through our Linked Tasks web part and stop the submit action if Issue status = ‘Closed’ and number of Tasks > 0.  Translating that “simple” logic into javascript takes patience and testing.

First, we need to get our Linked Tasks web part on the Edit page where the validation will happen.

  1. Navigate to your Issue list and display one of the Issues.
  2. Use the context menu on the Linked Tasks web part to Export it.  Save it locally.
  3. Click Site Actions > Site Settings > Modify All Site Settings then click Web Parts under the Galleries menu.
  4. Click the Upload button in the Web Part Gallery.
  5. Browse to your saved .webpart (CQWP) or .dwp (CEWP) file.
  6. Describe the web part and set the Group and Quick Add Groups to something you will remember, like “Custom.”
  7. Navigate back to your Issues list and Edit one of the Issue records.
  8. Use the “PageView=Shared&ToolPaneView=2”trick we used in Part 2 to expose the Add Web Parts pane.
  9. Click on the Add Web Part.  Find your group under All Web Parts, place a check in the box, then click Add.
  10. Exit edit mode.

Repeat this process for the initShowHide web part, we’ll need both of them.  We now have an EditForm.aspx page with the same functionality as our DispForm.aspx, we can see related Tasks.  Now we need to add our validation script to the page with the name PreSaveAction and adjust our Linked Tasks web part to filter out completed Tasks.

Update the filter on the Linked Tasks web part

(you may want to do this on the DispForm as well):

  1. Navigate to your EditForm.aspx page and open the context menu for the Linked Tasks web part then choose Modify Shared Web Part.
  2. Open the Query section of the configuration pane and scroll down to Additional Filters.
  3. Update the filter to “Task Status is not equal to Completed” then click OK.

Add the PreSaveAction to the EditForm.aspx page:

  1. Navigate to your EditForm.aspx page and enter Edit Mode (use the Linked Tasks web part’s context menu or the PageView trick).
  2. Click Add a Web Part at the top of the Web Part Zone.
  3. Select the Content Editor Web Part and click Add.
  4. Click the Source Editor button in the configuration pane and paste the following:
  5. <script type="text/javascript">
    function PreSaveAction(){
    var findItems = getElementsByClassName(document, "*", "toggleMe");
    var checkSelectVal = getTagFromIdentifierAndTitle("select","","Issue Status");
    if(findItems && findItems.style.display == 'block' && checkSelectVal.value == 'Closed'){
    alert('Incomplete related Task found, please close all related Tasks and try again.');
    return false; // Cancel the item save process
    }
    return true;  // OK to proceed with the save item
    }

    function getElementsByClassName(oElm, strTagName, strClassName){
    var arrElements = (strTagName == "*" && oElm.all)? oElm.all :
    oElm.getElementsByTagName(strTagName);
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
    oElement = arrElements[i];
    if(oRegExp.test(oElement.className)){
      return oElement;
      }
     }
     return null;
    }
    function getTagFromIdentifierAndTitle(tagName, identifier, title) {
    var len = identifier.length;
    var tags = document.getElementsByTagName(tagName);
    for (var i=0; i < tags.length; i++) {
    var tempString = tags[i].id;
    if (tags[i].title == title && (identifier == "" || tempString.indexOf
    (identifier) == tempString.length - len)) {
       return tags[i];
       }
      }
     return null;
    }
    </script>
  6. Click Save, then click OK on the pop-up window.
  7. Expand the Appearance section of the web part configuration pane and change the title to “CheckForOpenTasks.”
  8. Click OK in the web part configuration pane to save all changes.

On A Roll

We satisfied all of the requirements from our original question on Stump the Panel.  However, looking at this, I see room for improvement.  I want to add a link to the DispForm.aspx page that starts a new Task related to the Issue being displayed.  If you have any other suggestions, post them in the comments section and I’ll try to include them in the final installment of this series.

Spread the word...
  • Digg
  • Facebook
  • StumbleUpon
  • Google Bookmarks
  • LinkedIn
  • Reddit

Notify me of comments to this article:


Comments

6 Responses to “EndUserSharePoint.com: Extending Issues and Tasks: Part 3”

  1. Mark on October 7th, 2008 10:28 am

    The whole thing is very impressive and clever, and also very complex! This is Microsoft’s fault, not yours.

    In response to the first part of this, someone referenced Bamboo’s List Integrity web part. I think there is a use case that Bamboo picked up on that your example does not: when am I going to add a task for an issue? When I am looking at an issue.

    What you really need is a way, when a user is looking at an issue in a list/view or in the display form for an issue, to quickly add a task for that issue, with the issue lookup field prepopulated in the task. If I have, say, 1,000 issues in my list (and half are closed), under your approach each time I create a task I have to cull through the list of issues to find the one I want, even though half are closed. Better for me to be looking at a list of open, relevant issues and then decide to add a task for one of those, with the issue prepopulated.

    Can you do that in part 4? :)

  2. AutoSponge on October 7th, 2008 11:05 am

    Mark,

    Thanks, that’s already on the agenda for the closing article, “I want to add a link to the DispForm.aspx page that starts a new Task related to the Issue being displayed.”

  3. SharePoint Daily on October 8th, 2008 7:11 am

    SharePoint Daily for October 7, 2008…

    Top News Stories Microsoft Will Bow In-Memory Analysis, Appliance-Ready Database in 2010 (intelligent…

  4. Links (10/8/2008) « Steve Pietrek - Everything SharePoint on October 8th, 2008 7:27 pm

    [...] EndUserSharePoint.com: Extending Issues and Tasks – Part 3 [...]

  5. Amita on October 24th, 2008 12:15 pm

    I’m trying to figure out what I did wrong here. I closed out an issue that still had an open task related to and didn’t get the error message. Did I miss something?

    -aps

  6. EndUserSharePoint.com: Extending Issues and Tasks: Part 4 | End User SharePoint on February 18th, 2009 9:59 am

    [...] parts 1, 2, and 3,  you built a slick-looking extension of SharePoint’s Tasks and Issues.  If you let the [...]

Leave a Reply