Categories
SharePoint 2013

Vuetify Expansion Panel in SharePoint

I have had the pleasure of doing a lot with the VUE.js framework and I have created tons of videos on using Vue.js with SharePoint. I recently created a video on using Vuetify with SharePoint. Vuetify is a ‘Material Design Component Framework’ made for VUE. Check out the UI components. There are a plethora of components that can be leveraged and used in SharePoint. Here’s a video on using the ‘Expansion Panel‘ I created recently. Below is the code used in the video:

<head>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@1.5.14/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify@1.5.14/dist/vuetify.min.css" />
</head>
<body>
<div id="app">
<v-app id="inspire">
<v-expansion-panel inset focusable>
<v-expansion-panel-content lazy
v-for="(item,i) in expansion"
:key="i"
>
<template v-slot:header>
<div>{{item.Title}}</div>
</template>
<v-card>
<v-card-text>{{item.Details}}</v-card-text>
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>
</v-app>
</div>
<script type="text/javascript" src="/sites/demos/mdemos/webpart/expansion/expansionPanel.js"></script>
view raw expansion.html hosted with ❤ by GitHub
new Vue({
el:"#app",
data: {
expansion: []
},
created: function(){
this.getListData();
},
methods: {
getListData: function(){
var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('expansion list')/items";
var vm = this;
axios.get(endPointUrl).then(function(response){
vm.expansion = response.data.value;
})
.catch(function(error){
console.log(error);
})
.then(function(){
console.log("Always executes")
})
}
}
})
view raw expansion.js hosted with ❤ by GitHub
Categories
NINTEX SharePoint SharePoint 2013

Nintex – Assign Flexi Task

I have heard so many good things about NINTEX that I was excited when I finally had the chance to use it in place of SharePoint designer.  My task was to create a document approval workflow.  Here’s a diagram showing the process.

User uploads document  –> Notificaion sent to Chief –> Chief approves, disapproves –> Notification sent to AD –> AD approves, disapproves –> Notification sent to ED –> ED approves, disapproves

Creating the above process with Nintex was not a problem.  The problem was creating a reminder email to be sent.  When a notification is initially sent, the recipient will have two days to review the document and approve.  If the recipient hasn’t taken any action after two days, another notification should be sent.  I struggled with this for a few days googling (lots of different solutions) but was finally able to resolve this issue, thanks to a colleague.  He recommended using ‘flexi-task’ which worked great.  See images below.

With Nintex workflow open, select Assign Flexi task

AssignFlexiTaskIcon

Once you have dragged it to the workflow canvas, click the chevron next to the Assign Flexi task and select Configure from the list of options.

flexiTaskConfigure

When the configuration settings open up, in the Action tab add the Assignees name.

flexiTaskAction

Click on the Task Notification icon button and add any CC or BC and any message you want to be read on the initial email when a task is assigned.

flexiTaskNotification

Then click on the Reminders icon.  Add how many reminders you want to send out, 1 in my case.  Add the number of days between reminders, 2 for me.

flexiTaskReminder

Click Save and that’s it.

Hope this helps.

Thanks and please leave a comment and/or feedback below.

Categories
SharePoint SharePoint 2013

DOM still applies in SharePoint

There’s so much to remember when dealing with the DOM, especially when in SharePoint.  I am writing this post so I don’t forget and go searching “again”.  Here’s the scenario,  I needed to get data from a list and populate an html dashboard that will be rendered to a SharePoint page.  I use REST API and jQuery AJAX to retrieve my data so I can place it in the right place.  Below is my initial code and the error I was receiving.

    var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('dashboard')/items";

    var fieldStaff=document.querySelector("#fieldStaff");    

$.ajax({
    url: endPointUrl,
    type: "GET",
    headers: {
    "accept": "application/json;odata=verbose"
},
}).success(function (data) {
               fieldStaff.appendChild(data.d.results[0].FieldStaff);
});

The code produced the following error:
Uncaught TypeError: Failed to execute ‘appendChild’ on ‘Node’: parameter 1 is not of type ‘Node’.

It’s complaining that the parameter, data.d.results[0].FieldStaff is not a node, which means I need to make it a node.  But how?  After a little digging, I remembered that every HTML webpage gets parsed into a tree like structure of node objects and everything becomes a node(elements, text, etc.), so the value of data.d.results[0].FieldStaff must be a node.  The code below shows how I turned it into a node using the DOM API document.createTextNode().

    var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('dashboard')/items";
var fieldStaff=document.querySelector("#fieldStaff");    

$.ajax({
    url: endPointUrl,
    type: "GET",
    headers: {
    "accept": "application/json;odata=verbose"
},
}).success(function (data) {
      /*Make returned data a DOM Node*/
     var fieldStaffTextNode = document.createTextNode(data.d.results[0].FieldStaff);
     fieldStaff.appendChild(fieldStaffTextNode);

});

Error gone!

Thanks for reading!  Happy coding.

Categories
SharePoint SharePoint 2013

Add functionality to SharePoint form using DOM API

Recently I was faced with the need to add validation to a SharePoint list form.  Our environment was SharePoint 2013 on-prem so our only option was InfoPath and I refused to go down that road.  So I reverted back to what any developer would do.  I used plain old vanilla JavaScript and DOM development.  Here’s the scenario:

I had a SharePoint list that had 4 content types with different fields and each content type needed to have certain fields hidden as it went through a document approval process.  Here’s an image of what one of the 4 content type approval forms looks like.  In this blog, I will show you how to use DOM traversal to add functionality to a form.

approvalWorkflow.png

In the above form, Chief Document Approve? has the following options in the drop down (Approval, Approval with Feedback, Final Approval, Further Discussion Needed).  The functionality that needed to happen was that if Approval with Feedback or Further Discussion Needed was selected, then Chief Feedback multi-line box would show, if not it will be hidden.

When a new form is initially opened, the Chief Document Approve? drop down would be blank, which means that the Chief Feedback multi-line box would need to be hidden by default.   I will show you how to accomplish this but first, here’s what the DOM of Chief Feedback looks like.  As you can see in the image below, the textarea’s (Chief Feedback) parent is the span tag which is inside of a td tag which is inside of a tr tag.  So the textarea tag has three parents as seen below.

domElement

Now that we know what the DOM looks like, we can use this new reference to hide the Chief Feedback box.  See code below.


var chiefFeedback = document.querySelector("[title='Chief Feedback']");
chiefFeedback.parentNode.parentNode.parentNode.style.visibility = "hidden"; 

As you can see from the first line, we get a reference to our textarea box by referencing it by its title using the querySelector DOM API.  Once we have that reference, we reference the whole row (tr) by traversing all the way up to the parent from the textarea box.  That’s why we have the three parentNode from chiefFeedback.  Once we have that we use style.visibility = ‘hidden’ to hide the whole row.  But that’s only half the battle.  We want the feedback box to show if the drop down selection is Approval with Feedback or Further Discussion Needed and be hidden if not selected.

What we would need to do to accomplish our next task is to attach an onchange event to the drop down so that when there is a selection, we can check for what it is and take the appropriate action.   See code below on how to accomplish this.  There’s enough comments to understand what’s going on.

   /*Get a reference to the chief approve drop down box*/
   var chiefApprove = document.querySelector("[id^='ChiefDocumentApproval']");

   /*Attach an onchage event to drop down*/
   chiefApprove.onchange = function(){

   /*Grab the selected value*/
   var aValue = chiefApprove.options[chiefApprove.selectedIndex].value;

   /*Show and hide feedback field based on the selected value*/
   if(aValue == "Approval with Feedback" || aValue == "Further discussion needed")
     {

     /*Show box*/
     chiefFeedback.parentNode.parentNode.parentNode.style.visibility = "table-row";
     }else{

    /*Hide box*/
    chiefFeedback.parentNode.parentNode.parentNode.style.visibility = "hidden";
     }

   }

I hope this makes sense and can help you.  Happy SharePoint Client Side Coding! 🙂  Please leave a comment if you like this post.

Categories
SharePoint SharePoint 2013

SharePoint Group Setting causes error

I have been dealing with a bit of nuisance in the past couple of days that has been driving me crazy.  I have an InfoPath form that is used to request resources and sent to the proper approvers for approval. Because there can be multiple approvers, I added them to a SharePoint group I created and I used SharePoint designer workflow to route the email to the group.

Here’s the problem I have been having, my workflow ends up “pending” and the notification doesn’t get sent.  I get the cryptic error seen below:

RequestorId: 26acf292-541b-6524-0000-000000000000. Details: An unhandled exception occurred during the execution of the workflow instance. Exception details: System.ApplicationException: HTTP 401 {“Transfer-Encoding”:[“chunked”],”X-SharePointHealthScore”:[“0″],”SPClientServiceRequestDuration”:[“31″],”SPRequestGuid”:[“26acf292-541b-6524-9427-35217de6a338″],”request-id”:[“26acf292-541b-6524-9427-35217de6a338″],”X-FRAME-OPTIONS”:[“SAMEORIGIN”],”MicrosoftSharePointTeamServices”:[“15.0.0.4512″],”X-Content-Type-Options”:[“nosniff”],”X-MS-InvokeApp”:[“1; RequireReadOnly”],”Cache-Control”:[“max-age=0, private”],”Date”:[“Tue, 07 Jun 2016 18:33:38 GMT”],”Server”:[“Microsoft-IIS\/8.0″],”WWW-Authenticate”:[“NTLM”],”X-AspNet-Version”:[“4.0.30319″],”X-Powered-By”:[“ASP.NET“]} at Microsoft.Activities.Hosting.Runtime.Subroutine.SubroutineChild.Execute(CodeActivityContext context) at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)

I was finally able to get help from my colleague who faced the same issue before.  It had to do with how my group was set up.  When I created the group and arrived at the “Group Settings” section, “Who can view the membership of the group?”, I selected ‘Group Members’ which was wrong.  It needed to be ‘Everyone’. See below
groupSetting

 

With that change, my workflow started working and notifications were being sent.

I hope this post can save somebody the headache that I had.