SharePoint: Extending the DVWP � Part 14: Putting PreSaveAction() to Work with jQuery

Author: Jim Bob Howard

Now that we know how to press PreSaveAction() into service on the DVWP and have employed jQuery to create some variables, let’s write our variables out to an audit list.

New Audit Records Using SharePoint Web Services

Marc’s library offers a quick way to record the changes to our audit trail, using UpdateListItems.

First, write the old (or From) record…

    $().SPServices({
        operation: "UpdateListItems", // The Cmd below causes this to be an insert
        async: false,
        listName: "FTE Change Audit", // The 'Display Name' of audit list I've created
        updates: "<Batch OnError='Continue' PreCalc='TRUE'>" +
                "<Method ID='1' Cmd='New'>" +
                    "<Field Name='FromTo'>From</Field>" + // Field Name is the 'Static Name' of the list column
                    "<Field Name='Title'>" + txtOldName + "</Field>" +
                    "<Field Name='Location'>" + txtOldLoc + "</Field>" +
                    "<Field Name='Group'>" + txtOldGrp + "</Field>" +
                    "<Field Name='Position'>" + txtOldPos + "</Field>" +
                    "<Field Name='WorkShift'>" + txtOldShift + "</Field>" +
                    "<Field Name='FTE'>" + txtOldFTE + "</Field>" +
                    "<Field Name='EffDate'>" + txtEffDate + "</Field>" +
                    "<Field Name='ChangeType'>" + txtChangeType + "</Field>" +
                "</Method>" +
            "</Batch>",
        completefunc: function(xData, Status) {
        }
    });

…then repeat the process for the new (or To) record. Change the FromTo value to To; notice we’re using the same EffDate for both of them (your requirements may vary). ChangeType can be set automatically or calculated based on what has changed.

All Together Now

Edit as you have need, but here’s how my PreSaveAction() looks:

  function PreSaveAction() {
     var txtChangeType = "Update";
 
     var txtNewName = $("input[name*=$ff1_]").val();
     var txtOldName = $("span[id*=_ff9_]").text();
 
     var txtNewPos = $("input[name*=$ff3_]").val();
     var txtOldPos = $("span[id*=_ff11_]").text();
 
     var txtNewShift = $("select[name*=$ff4_]").val();
     var txtOldShift = $("span[id*=_ff12_]").text();
 
     var txtNewFTE = $("input[name*=$ff5_]").val();
     var txtOldFTE = $("span[id*=_ff13_]").text();
 
     var txtNewGrp = $("input[name*=$ff2_]").val();
     var txtOldGrp = $("span[id*=_ff10_]").text();
 
     var txtNewLoc = $("input[name*=$ff6_]").val();
     var txtOldLoc = $("span[id*=_ff14_]").text();
 
     var txtEffDate = $("input[name*=$ff7_]").val();
 
     $().SPServices({
          operation: "UpdateListItems",
          async: false,
          listName: "FTE Change Audit",
          updates: "<Batch OnError='Continue' PreCalc='TRUE'>" +
                    "<Method ID='1' Cmd='New'>" +
                         "<Field Name='FromTo'>From</Field>" +
                         "<Field Name='Title'>" + txtOldName + "</Field>" +
                         "<Field Name='Location'>" + txtOldLoc + "</Field>" +
                         "<Field Name='Group'>" + txtOldGrp + "</Field>" +
                         "<Field Name='Position'>" + txtOldPos + "</Field>" +
                         "<Field Name='WorkShift'>" + txtOldShift + "</Field>" +
                         "<Field Name='FTE'>" + txtOldFTE + "</Field>" +
                         "<Field Name='EffDate'>" + txtEffDate + "</Field>" +
                         "<Field Name='ChangeType'>" + txtChangeType + "</Field>" +
                    "</Method>" +
               "</Batch>",
          completefunc: function(xData, Status) {
          }
     });
 
     $().SPServices({
          operation: "UpdateListItems",
          async: false,
          listName: "FTE Change Audit",
          updates: "<Batch OnError='Continue' PreCalc='TRUE'>" +
                    "<Method ID='1' Cmd='New'>" +
                         "<Field Name='FromTo'>To</Field>" +
                         "<Field Name='Title'>" + txtNewName + "</Field>" +
                         "<Field Name='Location'>" + txtNewLoc + "</Field>" +
                         "<Field Name='Group'>" + txtNewGrp + "</Field>" +
                         "<Field Name='Position'>" + txtNewPos + "</Field>" +
                         "<Field Name='WorkShift'>" + txtNewShift + "</Field>" +
                         "<Field Name='FTE'>" + txtNewFTE + "</Field>" +
                         "<Field Name='EffDate'>" + txtEffDate + "</Field>" +
                         "<Field Name='ChangeType'>" + txtChangeType + "</Field>" +
                    "</Method>" +
               "</Batch>",
          completefunc: function(xData, Status) {
          }
     });
     return true;
};
  

Other Uses

What can you do with the PreSaveAction()?

  1. Field validation – making sure the data you’re about to write to the database is going to make sense, e.g.
    1. End date comes after Start date
    2. A date range is at least X days (or no more than X days)
    3. A person is already (or not yet) on a list
    4. If some optional fields become required based on other data filled in
    5. ad infinitum
  2. Add "Did you mean…?" functionality
    1. "…to make a change, but not update the Effective date?"
    2. "…to set this date in the future?"
    3. "…this person whose name is similar?"
    4. "…for this to be a transfer? or a termination?"
    5. ad infinitum
  3. Write to an audit trail
  4. Confirm delete
  5. Look up information to store in this item
  6. YOUR idea…

Want more?

Shoban Kumar, Wael Abbas, and Edin Kapic, along with EUSP authors Michael Greene and Marc Anderson (individually, and in conversation) offer some other ideas for using the PreSaveAction().

Next time: What do user-managed drop-down lists have to do with the DVWP? Well, they’re just good practice whether you’re using the DVWP or not. But, if you want to use cascading dropdowns on your DVWP, you’ll need to plan ahead. We’ll start walking through that plan and point out pitfalls along the way.

Four articles from now, you’ll have cascading dropdowns on your DVWP. And your list owner will manage the content and the relationships from SharePoint lists.

Author: Jim Bob Howard

Jim Bob Howard is a web designer / webmaster in the healthcare industry. He has been working with SharePoint since March 2009 and enjoys sharing what he has learned. He is a moderator and frequent contributor to Stump the Panel, and answers SharePoint questions on Twitter (@jbhoward) and via email (jimbobhoward@gmail.com).

[tweet]

4 thoughts on “SharePoint: Extending the DVWP � Part 14: Putting PreSaveAction() to Work with jQuery”

  1. […] form variables, and then add a few more. And we’ll add more variables that we can use with jQuery and the PreSaveAction() for form validation or writing to an audit […]
  2. SharePoint: Extending the DVWP – Part 25: Using an Audit Trail by Creating List Items with SPServices | EndUserSharePoint.com says:
    […] in Part 14 of this series, "Putting PreSaveAction() to Work with jQuery," I gave a quick snapshot of how you might […]
  3. […] the jQuery to cascade those two, as […]

Comments are closed.