Monthly Archives: August 2018

SharePoint 2013 Hosting Tutorial – How to Setup A Task List in SharePoint 2013?

A SharePoint project task list displays a collection of tasks that are part of a project. A task is a discrete work item that a single person can be assigned. A project is typically a series of activities that has a beginning, middle, and end, and which produces a product or service, such as producing a product demonstration for a trade show, creating a product proposal for stakeholders, or even putting together a corporate morale event.

After you create a SharePoint project task list, you can add tasks, assign resources to tasks, update the progress on tasks, and view the task information on bars that are displayed along a timeline.

In SharePoint 2013, task lists have been dramatically improved. Each task list now has a default view that contains a graphical timeline at the top of the list.  When a new task is created, you have the option of displaying that task on the timeline.  When you click the ellipsis next to a task, a pop up menu gives you the option of adding or removing that item from the timeline.

Click the Settings gear icon. Select Add an App.

sp1 Click the Tasks app. You can find the Tasks app in the list of templates.

sp2 Enter a name for the Tasks app in the Name text box and then click Create. …

sp3 The new My Tasks app appears in the Recent section of the current navigation. …

sp4 Click the app to open it.

sp5

Cheap and Recommended SharePoint 2013 Hosting

ASPHostPortal.com is Perfect, suitable hosting plan for a starter in SharePoint. ASPHostPortal the leading provider of Windows hosting and affordable SharePoint Hosting. ASPHostPortal proudly working to help grow the backbone of the Internet, the millions of individuals, families, micro-businesses, small business, and fledgling online businesses. ASPHostPortal has ability to support the latest Microsoft and ASP.NET technology, such as: WebMatrix, WebDeploy, Visual Studio 2015, .NET 5/ASP.NET 4.5.2, ASP.NET MVC 6.0/5.2, Silverlight 6 and Visual Studio Lightswitch, ASPHostPortal guarantees the highest quality product, top security, and unshakeable reliability, carefully chose high-quality servers, networking, and infrastructure equipment to ensure the utmost reliability.

SharePoint 2013 Hosting Tutorial – How to Add Excerpts to SharePoint?

Blogging and the Internet seem to go hand-in-hand, so it’s only fitting that Microsoft should include a ready-made blogging app as part of SharePoint. It includes most of the things you would expect of a blogging app, but there are some areas where it falls short. How a SharePoint blog displays lists of articles is one of them. It seems to take an all-or-nothing approach of either displaying only the title, date, and byline, as with the categories and archives views, or displaying the entire article text, as with the blog home page. Out of the box, there’s no middle ground.

Today, I want to show you one solution for displaying excerpts (instead of the entire article) in a SharePoint blog. Before I dive in, I want to preface this with a couple of disclaimers. Firstly, I assume that you are comfortable enough with SharePoint 2013 to know how to edit pages and add columns to SharePoint lists. Also, as with programming in general, there are lots of ways to solve this problem. When evaluating this solution for your own use, you should consider your project’s needs, your comfort level with the method described, and your personal preferences.

Step 1: Add an Excerpt column

Before your blog can have excerpts, it needs somewhere to put them. While you could just truncate the contents of the Body column, storing the excerpt separately means that you can give your content authors more control over what’s displayed with minimal effort. Here’s how to set that up:

  1. Navigate to your blog subsite, then go into Site Settings.
  2. Within Site Administration, select the Site libraries and lists, then choose Customize Posts.
  3. Create a column named “Excerpt” with the type Multiple lines of text. You can leave the other options at their defaults or modify them as you see fit, however this article assumes that the Excerpt column allows enhanced rich text.

Now, when you create a new blog post, you should notice an additional Excerpt field at the bottom of the form. That’s great, but it also means yet another box your content authors have to fill in. Who wants to type in the same information twice? And what happens if they forget?

Step 2: Populate the Excerpt field automatically

Let’s save your authors some time by copying the first paragraph of the Body field over to the Excerpt field automatically. Even better, let’s make it so that changes in the Body field get copied over to the Excerpt field as well, unless the author has modified the Excerpt field separately, as we don’t want to undo their changes. Here’s how:

<script>
// Automatically copy the first paragraph from the Body field to the Excerpt field anytime the Body field loses focus, unless the user has edited the Excerpt field.
function PopulateExcerptField() {
    $(document).ready(function() {
        var dirt = '<span id="ms-rterangecursor-start" rtenodeid="1"></span><span id="ms-rterangecursor-end"></span><br>';
        var OldExcerpt = $("div[role='textbox'][id^='Excerpt_']").html().split(dirt).join('');

        $("div[role='textbox'][id^='Body_']").on('blur',function() {
        var excerpt = $("div[role='textbox'][id^='Excerpt_']");

            if(excerpt.html() == OldExcerpt) {
                var firstParagraph = $(this).children('p').first().html().split(dirt).join('');
                excerpt.html('<p>' + firstParagraph + '</p>');
                OldExcerpt = excerpt.html();
            }
        });
    });
}

// Load jQuery if it doesn't already exist
(function() {

    if(typeof jQuery === 'undefined') {
        var headTag = document.getElementsByTagName("head")[0];
        var jqTag = document.createElement('script');
        jqTag.type = 'text/javascript';
        jqTag.src = '//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js';
        jqTag.onload = PopulateExcerptField;
        headTag.appendChild(jqTag);
    } else {
        PopulateExcerptField();
    }
})();

</script>
  1. Save the above gist as “PopulateExcerptField.html” and upload it to the Site Assetslibrary within SharePoint.
  2. Navigate to your blog and go to the Create a Post page.
  3. Edit the page and add a new “Content Editor” web part, which is found under the Media and Content folder.
  4. Hover over the upper-right corner of the Content Editor web part until you see a small triangle or arrow, click on it, and choose Edit Web Part.
  5. Enter the following into the Content Link field: “/SiteAssets/PopulateExcerptField.html”
  6. Click Apply, then in the SharePoint ribbon under the Page tab click Stop Editing.
  7. (Optional) Repeat for the Edit a Post page.

Note that this code relies on JQuery, so I’m loading it from a CDN if it doesn’t already exist. There are better ways to include javascript libraries in SharePoint, but that’s beyond the scope of this article.

Step 3: Display the excerpts on your blog

So, our posts now have excerpts, and we’ve made our content authors’ lives easier by adding some automation to the post creation process. But we still need a way to display them to our visitors. This is where things get complicated. Fret not. I’ll take you through it step by step.

Excerpts = {
    FirstPostID: -1,
    LastPostID: -1,

    // Instead of the contents of the Body field, returns a temporary placeholder that we can easily find and replace.
    // Also finds and stores the lowest and highest post IDs for later use.
    ReplaceBody: function(ctx) {
        var id = parseInt(ctx.CurrentItem.ID);

        if(id < Excerpt.FirstPostID || Excerpt.FirstPostID === -1) {

            Excerpt.FirstPostID = id;
        }

        if(id > Excerpt.LastPostID) {

            Excerpt.LastPostID = id;
        }

        var ret = "<p id='excerpt_placeholder_" + id + "'>Loading...</p><p><a href='" + _spPageContextInfo.webServerRelativeUrl + "/Lists/Posts/Post.aspx?ID=" + id + "'>Read More</a></p>";

        return ret;
    },

    // Fetches the excerpts and replaces the placeholder elements with them.
    ReplaceExcerptPlaceholder: function() {
        $(document).ready(function() {
            $.ajax({
                url: _spPageContextInfo.webServerRelativeUrl + "/_api/web/lists/getByTitle('Posts')/items?$select=ID,Excerpt&$filter=ID le " + Excerpts.FirstPostID + " and ID ge " + Excerpts.LastPostID,
                type: "GET",
                headers: {
                    "accept": "application/json;odata=verbose",
                },
                success: function (data) {
                    var res = {};
                    for (var i = 0; i < data.d.results.length; i++) {
                        res = data.d.results[i];
                        $('#excerpt_placeholder_' + res.ID).replaceWith(res.Excerpt);
                    }
                },
                error: function (err) {
                    console.log(JSON.stringify(err));
                }
            });
        });
    }
};

// Override the Body View
(function () {
    var override = {};
    override.Templates = {};
    override.Templates.Fields = {
        'Body': {
            'View': Excerpts.ReplaceBody
        }
    };
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(override);
})();

// Load jQuery if it doesn't already exist
(function() {
    if(typeof jQuery === 'undefined') {
        var headTag = document.getElementsByTagName("head")[0];
        var jqTag = document.createElement('script');
        jqTag.type = 'text/javascript';
        jqTag.src = '//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js';
        jqTag.onload = Excerpts.ReplaceExcerptPlaceholder;
        headTag.appendChild(jqTag);
    } else {
        Excerpts.ReplaceExcerptPlaceholder();
    }
})();

I should tell you what this code does before I explain how to use it, so let’s start at the bottom and work our way up. As before, the code relies on JQuery, and I want you to be able to drop this into SharePoint as-is, so lines 121-144 load JQuery dynamically if you don’t already have it.

In order to display the excerpts, we need somewhere to put them, so in lines 100-119 we register our own function to override the Body field’s view for each post. I’ve named the function “ReplaceBody”, and it’s defined on lines 31-53. ReplaceBody is given a Render Context object, and is expected to return an html string. The Render Context object, ctx, contains a bunch of things, but we really only care about ctx.CurrentItem, which, as the name implies, is the SharePoint item to be rendered. It contains all of the fields exposed by the current list view, but we only need the item’s ID. There are a couple of if statements that are used to store the lowest and highest post IDs for later. The function then generates an html string that contains a “<p>” element to serve as a placeholder for the excerpt and a Read More link that points to the view post page.

Finally, we have the ReplaceExcerptPlaceholder function, which is defined on lines 55-96. This function uses JQuery to asynchronously fetch the excerpts from the Postslist via SharePoint’s REST API. We use the $select query to specify that we only want the ID and Excerpts fields, and the $filter query to specify that we only care about the posts whose IDs are between the lowest and highest IDs we saved previously. This helps to ensure that the returned response is as small as possible for the sake of efficiency. If we get a successful response, we iterate over it and replace each placeholder element with the actual excerpt. If something goes wrong, we log the error to the javascript console and move on.

In order to use this code, we first have to get it into SharePoint. Here’s how:

  1. Save the above gist as “DisplayBlogExcerpts.js”.
  2. Navigate to your site collection’s Master Page Gallery, e.g. “{your sitedomain}/_catalogs/masterpage/Forms/AllItems.aspx”.
  3. In the Files tab choose Upload Document.
  4. Select DisplayBlogExcerpts.js and click OK.
  5. Set the Content Type to Javascript Display Template.
  6. Enter DisplayBlogExcerpts as the name, and optionally add a title and description.
  7. Set Target Control Type to View.
  8. Set Standalone to Standalone.
  9. Set Target Scope to “/”.
  10. Set Target List Template ID to “301″.
  11. In the SharePoint ribbon under the Edit tab click Save.

Now, we need to attach it to the appropriate web parts. Navigate to your blog subsite’s home page, one of its category pages, and one of its archive pages, and follow the steps below for each page:

  1. Edit the page.
  2. Hover over the upper-right corner of the Posts web part until you see the small triangle or arrow, click it, then choose Edit Web Part.
  3. On the web part editor, click Miscellaneous to expand it.
  4. In the JS Link field, enter “~sitecollection/_catalogs/masterpage/DisplayBlogExcerpts.js” and click Apply.
  5. For the archive and category pages, under List Views, change Selected View to “<Summary view>” and click Apply, then change Selected View to “<Current view>” and click Apply again.
  6. In the SharePoint ribbon under the Page tab click Stop Editing.

If everything worked, you should now have excerpts on all of your blog’s list pages.

Cheap and Recommended SharePoint 2013 Hosting

ASPHostPortal.com is Perfect, suitable hosting plan for a starter in SharePoint. ASPHostPortal the leading provider of Windows hosting and affordable SharePoint Hosting. ASPHostPortal proudly working to help grow the backbone of the Internet, the millions of individuals, families, micro-businesses, small business, and fledgling online businesses. ASPHostPortal has ability to support the latest Microsoft and ASP.NET technology, such as: WebMatrix, WebDeploy, Visual Studio 2015, .NET 5/ASP.NET 4.5.2, ASP.NET MVC 6.0/5.2, Silverlight 6 and Visual Studio Lightswitch, ASPHostPortal guarantees the highest quality product, top security, and unshakeable reliability, carefully chose high-quality servers, networking, and infrastructure equipment to ensure the utmost reliability.

SharePoint 2013 Hosting Tutorial – Easy to Backup and Archive Documents Using SharePoint Designer

Hence, now I can unveil my task. The objective is to create a weekly copy of the document named Document and move the copy to the folder Archive thereafter.

back1

Environment

For me there’s nothing better than a SharePoint Designer to create workflows for all minor customizations that need to be automated.

Workflow is rather a misleading term, as it normally only arises a visualization of some systematic process from user to user or level to level. However, I consider it normally as a sequence of steps that can be automated and hence for this specific task, I just had to settle at one version of the SPD for creating the workflow all the reasons that unfold in the course of the document.

What I’m talking about in this article is my experience on the SharePoint Online only. This can definitely be implied on SP 2013, but, I’m certain, definitely not on lower versions for all the same reasons.

Challenges

When I started this task, I took this up as a challenge to be self-sufficient, or rather make the best use of the limitations that I have.

While I could get started with creating a copy of the document using a workflow, to begin with, my first challenge was to trigger the process at a specified wee hour, since all that I knew was either workflows could get started when items are created or modified, and in the last case triggered manually…I could be dependent on some console app or some available scheduler apps for SP Online, but then I had to deal with the infrastructure challenges of setup and enabling the corresponding features. Or lastly, I could stay awake to initiate the workflow. Not that bad for a one-time trigger, but it would have then lacked the generalization.

Anyways, just as I thought the only hindrance was getting the workflow started, I stumbled against another – the archival process had to be periodic! This churned my grey cells to think of something beyond a manual process and set up an automated delay process in the process that I still ‘would be’ conceptualizing. But it did open an avenue to work with Date-Time and Pause, and here’s when I opted out of my most preferred SPD 2010 to explore a new terrain – SPD 2013 for the best I knew that processes could be setup in a loop in the latter.

This was however not the end of my woes. When a simple workflow is triggered, it acts upon just one specific item. Now I face my next challenge – how to identify the copy that was created and move it to the specified folder. It’s easy when we think of it – get the last index of the document library. That’s exactly what’s needed, but unfortunately, for anyone who’s had a little experience with SPD would know, there exists no such function that can directly return the last index of the list and document library in this approach.

By now I’ve enumerated my major challenges so far, and the remaining that I faced weren’t show stoppers, but yes, I would definitely discuss them in the course of this solution.

Belling the cat

I’ll tackle all my challenges listed so far in the same sequence.

How to set up the scheduler

It wasn’t that tough a job. I could start my workflow whenever I wanted, however, the slight workaround that I did was to add a Pause until the required schedule. Thereafter, the workflow would just be in motion.

By now, I’ve a fair idea of how my entire process will be framed, hence, this is the first reason why I preferred the SPD 2013 over 2010 – the former allows creating stages, and so, after I’ve set the scheduler in the starting stage, I can isolate this step from the subsequent.

back2

The Pause function lets you choose from either the Current date or the Specific date. So now I can do everything that I want in Stage 2.

To keep the curiosity active, I’ll unfold the details of the steps as we knock out each challenge.

How to set up the infinite loop

Now that I know that my workflow will transition to Stage 2 after the scheduled time, I can safely setup the loop. This suffices stronger to use the SPD 2013 now. However, setting up the loop requires evaluation of some metadata, for which, from the given set of columns, using the Title seems to be a good bet as this lies unused so far, not impacted by time also if I don’t wish to create any additional columns in my document library (however creating a dedicated column of a type as simple as a Single line of text suffices). The only other thing that I need to do is setup the value before the workflow starts and make sure the value is maintained to keep the loop running, and thereby I get my first step to setup the loop.

back3

P.S.: I’ve made use of string type variable Title1 for the only reason that no error incorporates in manual change that may impact evaluation.

I’ve exploited the column Title at various other places in the process to indicate the state of the workflow, however, before ending one loop, I’ll make sure the Title column is set back to the value that keeps the loop running infinitely (unless I need to perform only a finite set of iterations).

How to create a copy of the document

This can be easily done with the Copy document action and since the requirement is to create the copy in the same document library, select the corresponding destination.

back4

How to move the copy to the archival folder

Now that the item of interest is copied, the copy needs to be moved to the Archive folder. Thinking of a normal case, modifying Path and Name is not a task, but only when we perform this on the item that triggered the workflow and not any other item of the library. For this reason it is required that the copy can be distinguished uniquely and its Path and name can then be modified.

To do so, set the Title of the original item before the copy, so that the copied document contains a known value for the metadata and then modify the Title of the original item after copy so that the copied item can be uniquely identified in the document library.

back5

Having performed as in the screen shot above, we can now see that the Title of the original item was set to Stage2 before copy, so that the copied item has the same value in the Title field, and soon after copy, the Title of the original item is set to Copied.

Having done this, using some workarounds, we can fetch the ID of the copied item as demonstrated in the following screen shot.

back6

The captured ID will now do wonders, as this lets us uniquely pick the copied item for relocation.

back5=7

The one thing that needs to be highlighted here is the use of ID in setting up the Path and Name.

If I were to present the revelation of this workflow before the end, the backed up documents would be named something as in the following screen shot.

back8

The frequency of the repetition of the cycle is translated as time difference observed in Modified column. But the backups definitely don’t have an appealing Name.

With my experience of iterations, I figured out that the workflow returns an error to create (or move documents in a location) if there already exists an item with the same name.

This makes us wonder why not append the document name with a timestamp – good question, but my experience says if the process is repeated multiple times over the day, the timestamp remains constant throughout the day. Hence, a minimum gap of 24 hours is desirable to fetch a unique date-timestamp.

However, using the ID for uniqueness seems to be a safe generalized bet. Hence, using the ID seems to be one of the logical propositions irrespective of the frequency of repetition, considering that there’s no available function to concatenate strings.

However, we are not that short of ingenious ideas also. I’ve tweaked my item name to create a workflow variable FileName and concatenate the Name of the current item with the ID using a string builder.

back9

If the workflow has a minimum frequency of 24 hours, similar concept can be used with the date-timestamp. However, the thing to be noted is to replace the special chars ‘/’ and ‘:’ while using it.

s111

Having setup the value for FileName either ways, this variable can now be used to edit the Path and Name for the copied item as described in section

back10

How to setup the periodic loop

Now that a single copy and relocation process is setup, the entire process can be setup at the desired interval by setting up a Pause before the next loop gets executed and the areas highlighted in the following screen shot ensure well that the workflow is in place for the next loop to get executed after the pause.

back11

How does the output look

Keeping the curious minds satiated, the following screen shot gives an insight of how the backup archival process progresses.

back12

In the given example, since the workflow interval was 5 minutes, I preferred to use ID to append to the original file name. However, as mentioned afore, if the cycle had a minimum interval of 24 hours, I would get backed up documents christened as in the following screen shot.

back13

Cheap and Recommended SharePoint 2013 Hosting

ASPHostPortal.com is Perfect, suitable hosting plan for a starter in SharePoint. ASPHostPortal the leading provider of Windows hosting and affordable SharePoint Hosting. ASPHostPortal proudly working to help grow the backbone of the Internet, the millions of individuals, families, micro-businesses, small business, and fledgling online businesses. ASPHostPortal has ability to support the latest Microsoft and ASP.NET technology, such as: WebMatrix, WebDeploy, Visual Studio 2015, .NET 5/ASP.NET 4.5.2, ASP.NET MVC 6.0/5.2, Silverlight 6 and Visual Studio Lightswitch, ASPHostPortal guarantees the highest quality product, top security, and unshakeable reliability, carefully chose high-quality servers, networking, and infrastructure equipment to ensure the utmost reliability.