Saturday, 21 March 2015

SharePoint 2013 Document Library Drag and Drop option not showing in IE

One of new feature in SharePoint 2013 is the ability to drag and drop files into document libraries. This is useful for adding multiple documents to a library and removes the need to open the library in explorer view.


The reason for drag and drop not working and your document library looking like the above screen shot is due to two reasons:
1. You are using Internet Explorer 9 or lower.
2. You don’t have any Office 2013 components installed.

Resolution:

1. This is due to the fact that the drag and drop functionality uses HTML5. Installing Office 2013 will add an ActiveX control to allow you to use this drag and drop functionality in older browsers.
2. If you were to upgrade to IE10 or IE11 the HTML5 would be handled and the drag and drop would be available regardless of whether or not Office 2013 is installed.



Reference link

Monday, 2 March 2015

ISSUE: Save site as template option missing for publishing sites in SharePoint 2013.


Problem: When you browse to  SharePoint Server Site settings page, you discover that the Save site as template option isn't available.

This issue most frequently occurs because the Community Sites or the SharePoint Server Publishing feature is currently enabled or was previously enabled for the affected site. 

SharePoint doesn’t support creating a template from a site where publishing or community features were enabled. This is because the publishing feature creates site elements that are not supported as part of a template, and these elements remain even when the feature is disabled. This also includes templates that were created through SharePoint Designer.





Even when i tried to navigate to “_layouts/savetmpl.aspx”("Save site as template" page), it is throwing following error.

The "Save site as template" action is not supported on this site.



Here the solution:
After searching on net and i came to know that for publishing site "SaveSiteAsTemplate" is disabled.

Now how to enable this option.


Below are the steps to resolve this issue.


1. Open you Team Site in SharePoint Designer 2013.


2. In SharePoint Designer, under Sites tab select "Site Options".





3. Find "SaveSiteAsTemplateEnabled" in Site Properties.





4. Next change this setting to "true".




5. Now in your Publishing site navigate to "http://<site name>/_layouts/15/savetmpl.aspx" and you would see the old Save Site as Template Page as expected.






Wednesday, 18 February 2015

How to change ownership or email of SharePoint access request

The access request feature allows people to request access to content that they do not currently have permission to see. As a site owner, you can configure the feature to send you mail when someone requests access to a site. You can then choose whether to approve or decline their request. If you approve the request, you can also specify the specific level of permission you’d like to assign to a user.

The access request feature also works together with the Share command for sites. If someone who is not a site owner for a site (that is, someone who does not have full control for a site) uses the Share command to invite other people to view a site, then that action will generate an access request for the site owner. The site owner can then approve or decline the request, or specify the permission level to be assigned to the new user.

ISSUE:

we can set up access request on your site, by default who creates the site that person is responsible for approving access requests and all request will be send to the same person.
Now, that person moved away from the current department or you may want to change the person.

Resolution:

Site owners can set up the access request feature so that it sends them an email when someone requests access to a site.

    1. Go to Settings Settings button > Site Settings.

    2. Under Users and Permissions, click Site Permissions.

    3. On the Permissions tab, click Access Request Settings.

    In the Access Request Settings dialog box, select the check box next to Allow access requests, and then type the email address of the person you want to make responsible for approving access requests.

    4. Click OK.


If you want to disable access request you can uncheck "Allow access requests".

How to redirect to root site when user click on subsite logo

Requirement:

I have one sub site (this is search center) under the root site collection. Whenever search any keyword it will redirect to search site. Here there is no way to go to home site. Now users want to go back when they click on site logo.

Solution:

Here the solution.

1. Open the sub site/ Search site in SharePoint designer 2013.
2. Open the site's master page and add the below JQuery script.

<script type="text/javascript">
$(function(){
  $('.ms-siteicon-a').click(function(e){
   e.preventDefault();
    window.location.href="/";
  });
});
</script>

Now save and check it.


SharePoint Timer stuck stopping


Error: When we got search issue and we need to update cache.ini file. For this we need to disable SharePoint timer job and also need to stop SharePoint timer service. when we try to stop SharePoint timer service but its strucked in stopping state only and it's not stopping and also production applications are stopped working.

Resolution for the error:

Go to the Windows Task Manager, click on Processes tab. Select "Show processes from all users". Right click on OWSTIMER.EXE and then click on End Process. Now the SharePoint timer service will be stopped.


Monday, 26 January 2015

How To: CRUD operation in SharePoint apps on list (host web apps) using JavaScript Object Model (JSOM)

In my previous post, have shown how to deploy simple SharePoint app in hosted web apps.

Now i want to show how to Create, Read, Update and Delete operation on host web apps list.

I have created one list named it as "Associate" with 4 columns named as associate id(internal name Title), associate_name, associate_num, associate_address.


As we know, server side code is not allowed in SharePoint-hosted apps. So, we have to use client side object mode(JSOM/REST API)

1. Open visual studio 2013 --> Create new project --> Apps for SharePoint
2. Give a name for solution and click on OK.


3. Now go to pages folder and right click on it then add client web part call it as "CRUDOpps.aspx"

Now design the page as below,

<body>
    <div>
        <input id="btnGetList" onclick="associateList()" type="button" value="Get List" />

        <div id="divList">&#160;</div>

        <div id="newitem" style="display: none">
            <table>
                <tbody>
                    <tr>
                        <td>Associate Id </td>

                        <td>:</td>

                        <td>
                            <input name="associateId" id="txtTitle" type="text" /></td>
                    </tr>
                    <tr>
                        <td>Associate Name </td>

                        <td>:</td>

                        <td>
                            <input name="associateName" id="txtName" type="text" /></td>
                    </tr>
                    <tr>
                        <td>Associate Number </td>

                        <td>:</td>

                        <td>
                            <input name="associateNumber" id="txtNumber" type="text" /></td>
                    </tr>
                    <tr>
                        <td>Associate Address </td>

                        <td>:</td>

                        <td>
                            <input name="associateAddress" id="txtAddress" type="text" /></td>
                    </tr>
                    <tr>
                        <td></td>

                        <td></td>
                    </tr>
                    <tr>
                        <td>
                            <div id="AddAssociate" style="display: none">
                                <input onclick="runSubmit()" type="button" id="btnAddSubmit" value="Add" />
                            </div>
                        </td>
                        <td>
                            <div id="UpdateAssociate" style="display: none">
                                <input onclick="runUpdate()" type="button" id="btnUpdate" value="Update" />
                            </div>
                        </td>

                        <td>
                            <input id="btnCancel" onclick="runCancel()" type="button"
                                value="cancel" /></td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</body>

4. Now open App.js from the Scripts folder and add the JavaScript code for performing CRUD operations on the CategoryList. There are some specific steps we need to implement for every operation:


We need to work with the App Web and Host Web URL. To do that the following helper method with querystring parameter will help us out:

function manageQueryStringParameter(paramToRetrieve) {
    var params =
    document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == paramToRetrieve) {
            return singleParam[1];
        }
    }
}

5. Read list items

In the App.js declare variables to store the Host web and App web:

var hostWebUrl;
var appWebUrl;

Get the Host Web and App Web Url in document.ready:

hostWebUrl = decodeURIComponent(manageQueryStringParameter('SPHostUrl'));
appWebUrl = decodeURIComponent(manageQueryStringParameter('SPAppWebUrl'));


In the above code: SPHostUrl represents the full URL of the host site and SPAppWebUrl represents the full URL of the app web.

context = new SP.ClientContext(appWebUrl);
clientContext = new SP.AppContextSite(context, hostWebUrl);

These two statements are used to get context of App web and host web.

In CRUDOpps.aspx page we have added on button to get list of associate details when user click on the button it will display available associate details along with update and delete button for each row.

Add the following method in App.js to list of associate in host web.

function associateList() {
    context = new SP.ClientContext(appWebUrl);
    clientContext = new SP.AppContextSite(context, hostWebUrl);
    list = clientContext.get_web().get_lists().getByTitle(listName);
    var query = new SP.CamlQuery();
    query.set_viewXml("");
    listItems = list.getItems(query);
    context.load(listItems);
    context.executeQueryAsync(onSuccess,onFail);
}

Once the query is success, the below function will execute

function onSuccess() {
    listItemEnumerator = listItems.getEnumerator();
    output = "<table style=><tr><th>Associate Id</th><th>Associate Name</th><th>Associate Number</th><th>Associate Address</th></tr>";
    while (listItemEnumerator.moveNext()) {
        itemId = listItemEnumerator.get_current().get_id();
        output = output + "<tr><td>" + listItemEnumerator.get_current().get_item('Title') + "</td><td> " + listItemEnumerator.get_current().get_item('associate_name') + "</td><td>" + listItemEnumerator.get_current().get_item('associate_num') + "</td><td>" + listItemEnumerator.get_current().get_item('associate_address') + " </td><td><input id='btnDelete' onclick='deleteItem(" + listItemEnumerator.get_current().get_id() + ")' type='button' value='delete'/></td><td><input id='btnUpdate'onclick='updateItem(" + listItemEnumerator.get_current().get_id() + ")' type='button' value='Update'/></td></tr>";
     
    }
    output = output + "</table><br/><input id='btnAdd' type='button' value='Add Associate' onclick='addnewItem()'/>";
    $("#divList").html(output);
}


Fail method will be common for all failure calls

function onFail() {
    alert('request failed');
}


After displaying all associates details, now you can update/ delete any associate details or you can add new associate details clicking on add associate button.

7. Create item in list

Add the following method in App.js to create a new associate details:

when you click on add associate button, will show add new associate form.

function addnewItem() {
    $("#txtTitle").attr("value", "");
    $("#txtName").attr("value", "");
    $("#txtNumber").attr("value", "");
    $("#txtAddress").attr("value", "");
    $("#newitem").show();
    $("#AddAssociate").show();
    $("#UpdateAssociate").hide();
}

8. Update item in list

Here am using one method for add and update associate details

function operation(string) {

    context = new SP.ClientContext(appWebUrl);
    clientContext = new SP.AppContextSite(context, hostWebUrl);
    list = clientContext.get_web().get_lists().getByTitle('associate');
    if (string == 'update') {
        listItem = list.getItemById(itemId);
        parameter = 'updated';
    }
    else {
        var listCreateInfo = new SP.ListItemCreationInformation();
        listItem = list.addItem(listCreateInfo);
        parameter = 'added';

    }
    if (($("#txtTitle").val() != "") && ($("#txtName").val() != "") && ($("#txtNumber").val() != "") && ($("#txtAddress").val() != "")) {
        listItem.set_item('Title', $("#txtTitle").val());
        listItem.set_item('associate_name', $("#txtName").val());
        listItem.set_item('associate_num', $("#txtNumber").val());
        listItem.set_item('associate_address', $("#txtAddress").val());
        listItem.update();
        context.load(listItem);
        context.executeQueryAsync(onSuccessOfOperation,onFail);
    }
    else {
        alert('Enter all the fields');
    }
}

On success it will updated associate details on page.

function onSuccessOfOperation() {

    if (parameter == 'added') {
        alert('Item added to list');
        parameter = "";
    }
    if (parameter == 'updated') {
        alert('update complete');
    }
    if (parameter == 'deleted') {
        alert('Item deleted');
    }
    addnewItem();
    $("#newitem").hide();
    associateList();
}

9. Delete item in list

Add the following method in App.js to update associate details based on ID.

function updateItem(a) {
    itemId = a;
    parameter = 'update';
    context = new SP.ClientContext(appWebUrl);
    clientContext = new SP.AppContextSite(context, hostWebUrl);
    list = clientContext.get_web().get_lists().getByTitle(listName);
    listItem = list.getItemById(itemId);
    context.load(listItem);
    context.executeQueryAsync(onUpdate,onFail);
}
function onUpdate() {
    $("#newitem").show();
    $("#AddAssociate").hide();
    $("#UpdateAssociate").show();
    $("#txtTitle").attr("value", listItem.get_item('Title'));
    $("#txtName").attr("value", listItem.get_item('associate_name'));
    $("#txtNumber").attr("value", listItem.get_item('associate_num'));
    $("#txtAddress").attr("value", listItem.get_item('associate_address'));
}

In App.js add the below code to Delete associate details.

function deleteItem(itemId) {
    parameter = 'deleted';
    $("newitem").hide();
    context = new SP.ClientContext(appWebUrl);
    clientContext = new SP.AppContextSite(context, hostWebUrl);
    list = clientContext.get_web().get_lists().getByTitle('associate');
    var listItem = list.getItemById(itemId);
    listItem.deleteObject();
    context.executeQueryAsync(onSuccessOfOperation,onFail);
}


10. Since the App makes call to the SharePoint List, we need to set permission for the App to access list. To set these permissions, in the project double-click on AppManifest.xml and from the permission tab set the permissions as below:


11. Now i want to change client app title, description, width and height.


12. Now build the application deploy on developer site. Once you deploy on developer site now we will move the app to on working site.

13. Now open catalog site for the working site and upload CRUD Operations on List.app file in Apps for SharePoint.

14. Now follow my previous post to display app on a page.

15. After adding the app on page it looks like as below, by default it will show only one button.



16. Once user click on get list button, it will show list of available associate details


17. When user click on update button then it will show edit form for the respective associate.


18. Once user edit the details click on 'update'.

19. To add new associate details, then click on add associate button then enter details and click on add.

20. To delete any associate from list, click on delete of that associate.

After doing any operation the list automatically updates.

That is all about how to perform CRUD operations on list in SharePoint apps.

Please find the complete source code here.

Monday, 12 January 2015

Error Type: DataForm Web Part displays "Unable to display this Web Part"

There is one scenario,

1. Create a list or library in SharePoint 2010. 
2. Open the list / library in SharePoint Designer. 
3. Close and hide the XSLTListView Web part on the page.
4. Insert a DataForm web part on the page. 

The page is working fine in SharePoint 2010 but once you migrate the site from SharePoint 2010 to SharePoint 2013 and If the list contains a large number of columns or custom XSL has been applied to the DataForm web part the following error message may be displayed:

"Unable to display this Web Part. To troubleshoot the problem, open this Web page in a Microsoft SharePoint Foundation-compatible HTML editor such as Microsoft SharePoint Designer. If the problem persists, contact your Web server administrator."

You can also see System.StackOverflowException errors in the SharePoint log.


In SharePoint 2013, Microsoft has reduced the timeout for XSLT transformation from 5 seconds to 1 second without giving the administrator the option of increasing it manually via Powershell.  The reduction is a securtity measure to reduce the risk of successfull DoS attacks. .

The timeout essentially causes any modified XSLTListViewWebPart and XSLTDataViewWebParts to error intermittently when viewed in the browser.

We can fix the above error using Powershell script.
Below script is used to make the change to the Timeout value.  Changing it to 5 seconds worked for us and the webparts are now showing fine.

PowerShell to set XsltTransformTimeOut

$farm = Get-SPFarm

$farm.XsltTransformTimeOut = 5

$farm.Update()