Stump the Panel » Business Problem Statements: SharePoint Designer Workflow Solutions

Calculated challenge of the day- any brave souls up for it?

(37 posts)
  • Started 3 weeks ago by NancyCentury
  • Latest reply from Nelson
  1. NancyCentury
    Member

    It's odd- this works on my actual project list, but for some reason, certain porjects have no values in the Today's date column and in the Indicator column.

    I have no idea why these would be blank!I deleted the projects an re-added them, and got the same result. :-(

    Posted 1 week ago #
  2. NancyCentury
    Member

    I could not resolve why certain projects did not display the Today's Date value or an indicator; I reverted back to my original format to avoid the wrath of my users.

    Posted 1 week ago #
  3. NancyCentury
    Member

    Dessie- I wanted to add that even on my test list, this error appeared. It seemed to be specific for certain due dates. The due dates that "failed' on my live Project List were the same due dates that 'failed' on the test list.

    Perhaps it's a script issue, or something else tield to the calculations? If the script looks at due date and sets the "Today" value off that, and someting is wrong with that relationship, would it therefore follow that the 'today's date' and 'indicator' columns would result in blanks?

    Due dates in the 8/1/09 - 8/9/09 range failed, FYI; also a due date in the 9/4/09 area IIRC.

    Posted 6 days ago #
  4. Nancy,
    I too would like for a bullet-proof way to include "Today" within a calculated column without the need for hacks, scripts, workflows, or coded solutions (I've got my request in to be included in the SharePoint 2010 Beta...so we'll see if they decided to include this finally).

    For the usage of images rather than the bullet graphic in the resulting display, replace the "to be rendered" div html to an image instead:

    Current:


    "<DIV style='font-weight:bold; font-size:24px; color:red;'>•</DIV>";

    Replace with:


    "<IMG src='/_layouts/images/kpidefault-0.gif' />"

    Replace each of the corresponding colors with their equivalent kpi graphic.
    Since we will already know the value to be displayed (calculated through the script), all we have to do is tell it to use images instead of a bullet.

    For the problem with the empty fields when using dates in the range of 1-9 (this will occur on any month), that was my bad. For some reason on the version of the script I posted last time, I didnt include the section to test for days less than "10" (internal dates will always have a 2-digit month and 2-digit day). Since this wasn't included, the displayed date will always evaluate to false when comparing it to the internal date.

    The fix for this is below:


    <script type="text/javascript">
    //--Christophe's Render HTML script-->
    var theTDs = document.getElementsByTagName("TD");
    var i=0;
    var TDContent = " ";
    while (i < theTDs.length)
    {
    try
    {
    TDContent = theTDs[i].innerText || theTDs[i].textContent;
    if ((TDContent.indexOf("<DIV") == 0) && (TDContent.indexOf("</DIV>") >= 0))
    {
    theTDs[i].innerHTML = TDContent;
    }
    }
    catch(err){}
    i=i+1;
    }
    //-->

    //--Working with Today's Date-->
    var d = new Date();
    //Today's date (current date)
    var todaysDate = parseInt(d.getMonth()+1).toString()+"/"+d.getDate().toString()+"/"+d.getFullYear().toString();
    var tbls = document.getElementsByTagName('table'); //All tables

    for(var i=0; i<tbls.length; i++) //Loop through all tables
    {
    if(tbls[i].id != "") //Only look at tables with ID's
    {
    if(tbls[i].getAttribute('summary') != "") //The table we want will have a "Summary" attribute
    {
    var nobrs = tbls[i].getElementsByTagName('nobr'); //All Date fields (Due Date column) in our table
    for(var x=0; x<nobrs.length; x++) //Loop through date fields
    {
    var divs = tbls[i].getElementsByTagName('div'); //All divs in our table
    for(var z=0; z<divs.length; z++) //Loop through all divs
    {
    /****Section that formats date as "mm/dd/yyyy"********/
    var nobDate = new Date(nobrs[x].innerText || nobrs[x].textContent);
    var mm = nobDate.getMonth()+1;
    if(mm<10)
    {
    mm="0"+mm;
    }
    var dd = nobDate.getDate();
    if(dd<10)
    {
    dd="0"+dd;
    }
    var yyyy=nobDate.getFullYear();

    var dueDate = mm + "/" + dd + "/" + yyyy;
    /*****************************************************/

    //Compare "Due Date" value with DIV "Class" name (looking at "Today's Date" column)
    if(dueDate+"Today" == divs[z].className)
    {
    //Set DIV value to current date
    divs[z].innerText = todaysDate;
    divs[z].textContent = todaysDate;
    }
    //Compare "DIV" id with "Due Date" column (this will be the "Indicator" column)
    else if(divs[z].id == dueDate)
    {
    var tDate = new Date(todaysDate); //Current Date
    var temp = nobrs[x].innerText || nobrs[x].textContent;
    var dDate = new Date(temp); //Due Date
    var one_day=1000*60*60*24 //Millisecond value for date comparison
    var dateCalc = Math.ceil((tDate.getTime() - dDate.getTime())/one_day); // date difference

    if(dateCalc > 0) //Due date is in the past
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<DIV style='font-weight:bold; font-size:24px; color:red;'>•</DIV>";
    }
    else if(dateCalc == 0) //Due date is today
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<DIV style='font-weight:bold; font-size:24px; color:red;'>•</DIV>";
    }
    else if(dateCalc == -1) //Due date is tomorrow
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<DIV style='font-weight:bold; font-size:24px; color:yellow;'>•</DIV>";
    }
    else if(dateCalc == -2) //Due date is in 2 days
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<DIV style='font-weight:bold; font-size:24px; color:yellow;'>•</DIV>";
    }
    else if(dateCalc == -3) //Due date is in 3 days
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<DIV style='font-weight:bold; font-size:24px; color:yellow;'>•</DIV>";
    }
    else //Due date is in the future and is not critical (more than 3 days out)
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<DIV style='font-weight:bold; font-size:24px; color:green;'>•</DIV>";
    }
    }
    }
    }
    }
    }
    }
    </script>

    Try this version and see if it fixes the problem (it should).

    - Dessie

    (**Edited to include section for cross-browser support - forgot it again.)

    Posted 4 days ago #
  5. NancyCentury
    Member

    Dessie,
    Those corrections look like a winner! I am on my feet clapping for you!

    What I was surprised to find- was that once the "today's date" field was in place and displaying the correct current date value, I then could remove that column from the view and the indicator still worked! This was an unexpected bonus since I might not always want that date value to be taking up list space.

    Thanks so much!! :-)

    Posted 3 days ago #
  6. NancyCentury
    Member

    Adding:
    I decided it would be cool to have a tooltip message when a user hovered over the indicator icon that corresponded to the relationship of the due date to the current date.

    I amended the script as follows:

    **********

    'if(dateCalc > 0) //Due date is in the past
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<img style='float:left;' src='/_layouts/images/kpidefault-2.gif'title='Due date has passed' />";
    }
    else if(dateCalc == 0) //Due date is today
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<img style='float:left;' src='/_layouts/images/kpidefault-2.gif'title='Due date is TODAY' />";
    }
    else if(dateCalc == -1) //Due date is tomorrow
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<img style='float:left;' src='/_layouts/images/kpidefault-1.gif'title='Due date is TOMORROW' />";
    }
    else if(dateCalc == -2) //Due date is in 2 days
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<img style='float:left;' src='/_layouts/images/kpidefault-1.gif'title='Due date is in 2 days' />";
    }
    else if(dateCalc == -3) //Due date is in 3 days
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<img style='float:left;' src='/_layouts/images/kpidefault-1.gif'title='Due date is in 3 days' />";
    }
    else //Due date is in the future and is not critical (more than 3 days out)
    {
    document.getElementById(divs[z].id).parentNode.innerHTML = "<img style='float:left;' src='/_layouts/images/kpidefault-0.gif'title='Due date is more than 4 days away' />"
    '
    **********

    Thanks again for all your help.

    Posted 3 days ago #
  7. Awesome!! Glad to hear it works (it was a tough/fun one to figure out).

    - Dessie

    Posted 3 days ago #
  8. NancyCentury
    Member

    I hope someone else can use it too!

    Posted 3 days ago #
  9. Nelson
    Member

    Hello Nancy,
    This was a valuable effort. I'm wanting to present this to my project management team - can you please tell me all the fields/columns you have on your list and if you were able to get the images instead of the dots.

    Thank You.

    Posted 2 days ago #
  10. NancyCentury
    Member

    Wow, did you read through all this? amazing!

    I did get images, and not only images- images with a specific mouseover message when the user hovers over the image, which reflects the status of the project in relation to the due date.

    Dessie is truly remarkable for what he did here. that cannot be overstated.

    As far as all my columns, fields etc....

    I would have to work on that when I have a chunk of time. :-)

    Beyond this specific effort, which only tacked the singular issue of "how to get 'TODAY' (date value) dynamically available and leveragable by other fields/formulas", a lot more was involved in my list to get the users what they wanted.

    Briefly- the project list was created off the 'issue tracking' list type. I created a content type for that list which presents the user with 8 required fields to complete when adding a new project:
    -Title
    -Description
    -Line of business (choice field, site column)
    -Assigned to (allowing multiple users)
    -Priority
    -% complete ( a choice column forcing selections 0% (default), 10%, 25%, 50%, 75%,90%, 100%)
    -Due date
    -Notes (append-only text field)

    The goal was to reduce as much as possible the ability of the users to change critical fields. Therefore, there are MANY hidden columns (calculated and non-calculated types) to drive other values while disallowing user interaction.

    For example, "status" is hidden from the content type, defaulting to "in progress". The user can only update status by changing the % complete value.

    When the user finally changes % complete to 100%:
    - Status field changes to Complete
    - A hidden "end date" field populates with the current date
    - A hidden "actual days" field calculates number of days it took to complete (= [start date]-[end date])
    - a hidden "completion result" field displays (text) either EARLY or LATE by comparing 'actual days' to 'target days' ('Target days =[due date]-[start date], another hidden value)
    - A WF runs which copies the item to a separate Archive list.

    There is also an associated document library w/ a lookup field to the project title from the project list.

    When the user clicks the project title, they wanted to see not only the project data but any associated documents as well. To accomplish this, I created a custom display form that includes a web part with the project document library in it, and a connection between that and the display form to only pull in the documents that share the same project title. I modified this in SPD to change it to an XSLT data view so that I could have the ability to display a message when no matching items were available. Below the doc lib web part is a CEWP that allows the user to upload a doc if they want. This gives them all the functionality they wanted in one place.

    I also had to place a CEWP on that custom dispform that provides instructions to all my Office 2003 users (a lot of them) to make sure they choose the correct "edit" drop-down command to open the docs correctly. (If they don't, they default to a read-only view in Wordwhen opened.) I used the "collapse web parts toggle " script in another CEWP on this dispform to give a cleaner view by allowing the user to open/close the Office 2003 instructional web part as needed.

    Plus a lot more.

    whew.

    Documenting all this may take a while!

    Posted 2 days ago #
  11. Nancy,

    Please, if you have time, download the 30-day trial version of Camtasia and create a screencast of all you've implemented based on this thread. It would be a fantastic addition to the EUSP archives.

    Thanks!

    Blessings,
    Jim Bob

    Posted 2 days ago #
  12. Nelson
    Member

    Thanks Nancy -- That's a great start for me.

    Posted 2 days ago #

RSS feed for this topic

Reply

You must log in to post.