Tuesday, April 10, 2018

Updating a SharePoint Survey View

If you want to update the view of a SharePoint survey, like say add a column to view or change the sort order, you have to open up the view in SharePoint Designer, like All Responses:


then find the "View" xml and update accordingly (sorting is in the OrderBy CAML, and you can add FieldRefs to show more columns, etc.)

<View Name="{D1928BFA-8AFA-4B0D-A5F2-9C5748292299}" Type="HTML" TabularView="FALSE" DisplayName="All Responses" Url="/Lists/Statistics/AllItems.aspx" Level="1" BaseViewID="2" ContentTypeID="0x" ImageUrl="/_layouts/15/images/survey.png?rev=44" ><Query><OrderBy><FieldRef Name="ID" Ascending="FALSE"/></OrderBy></Query><ViewFields><FieldRef Name="DisplayResponse"/><FieldRef Name="Author"/><FieldRef Name="Modified"/><FieldRef Name="Active"/><FieldRef Name="Completed"/></ViewFields><RowLimit Paged="TRUE">30</RowLimit><JSLink>clienttemplates.js</JSLink><XslLink Default="TRUE">main.xsl</XslLink><Toolbar Type="Standard"/></View>

and you'll get an updated view:


Friday, April 6, 2018

SharePoint Designer: Workflow stuck - Invalid Text Value

If you have a workflow that gets stuck in a state where it says:

"Invalid text value.  A text field contains invalid data.  Please check the value and try again"



You likely have more than 255 characters in a "Log to the Workflow History List", which throws this error.


SharePoint Designer Workflow: Passing HTML in url parameters

If trying to pass some html as a url parameter in a link in a SharePoint Designer workflow like below,



if you just add it to a link parameter like so:

&msg=<h2>Thank you [% Current Item:Assigned To %] for approving<br/><br/>You may now close this tab.</h2>


it gets encoded so your < will become %3C, etc.  To get around this, if you create a variable and encode it:


like so:

%3Ch2%3EThank%20you%20[% Current Item:Assigned To %]%20for%20approving%20your%20direct%20reports%20for%20this%20fiscal%20quarter.%3Cbr%2F%3E%3Cbr%2F%3EYou%20may%20now%20close%20this%20tab.%3C%2Fh2%3E


then you can just use the variable in the link and it will display as you'd like it:


&msg=<h2>Thank%20you%20Sean%20Regan%20for%20approving.<br%2F><br%2F>You%20may%20now%20close%20this%20tab.<%2Fh2>


SharePoint Survey: Creating a Friendly Error Message

If you have a SharePoint survey that is set to only allow a single submission per user, if a user tries to submit again they get a nasty system error:

Sorry, something went wrong
You are not allowed to respond again to this survey



To create a more user friendly error message, you can create a new page, add some javascript in it, and display either a friendly message like:




Or if they haven't taken the survey it will redirect them there.  

Simply send out a link to your new page with a (list) path and a (list) title parameter like so:

https://vivity.sharepoint.com/Pages/Survey-Check.aspx?path=/Lists/Survey/NewForm.aspx&title=Survey

The code is in my github below, just link the javascript into a Content Editor Web Part:


And below:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript">

function getParameterByName(name) {
var url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}

function readSurveyVotes(cbSurveyResult)
{
var listTitle = getParameterByName("title");

        var context = new SP.ClientContext.get_current();
        var web = context.get_web();
        var list = web.get_lists().getByTitle(listTitle);
        var viewXml = '<View><Where><Eq><FieldRef Name="Author"/><Value Type="Integer"><UserID Type="Integer"/></Value></Eq></Where></View>';
        var query = new SP.CamlQuery();
        query.set_viewXml(viewXml);
        var items = list.getItems(query);
        context.load(items);
        context.add_requestSucceeded(onLoaded);
        context.add_requestFailed(onFailure);
        context.executeQueryAsync();
        function onLoaded() {
            var voteCount = items.get_count();
            cbSurveyResult(voteCount)
        }
        function onFailure() {
            cbSurveyResult(null);
        }
}

$(document).ready(function() {
var listPath = getParameterByName("path");
var listTitle = getParameterByName("title");

    //Read survey for current user to find out if he have already voted   
    readSurveyVotes(function(votesCount){
        //if voted then display custom message 
        if(votesCount > 0) {
            survey-check-message.innerHTML = "<h2>You already took the " + listTitle + " survey, thank you for checking!</h2>";
        }
        //if not, call original function for opening response form
        else {
            survey-check-message.innerHTML = "<h2>Redirecting to " + listTitle +  " survey...</h2>";
            window.location.href = listPath;
        } 
    });
  
});
        
</script>

<div id="survey-check-message" />

I based my code from the following: