AngularJS: Bind UI Select selection sequentially


Hello,

I felt lucky to work with angularJS with the integration with SharePoint(as backend) in my recent project. There was a requirement to have two drop-downs on a single page application where on selection of one; other drop-down value will be automatically filtered.  I am going to share with you guys that how I have implemented.  I understand that this may not be Ideal way of doing it but I am sure that it is quickest solution that I did in code to achieve this requirement.

HTML: The below html will generate two dropdowns and populate with country and states data.

<h3>Countries</h3>
<ui-select ng-model="ctrl.country.selected" name="country" theme="bootstrap" title="Select a Country" >
<ui-select-match placeholder="Select or search a country in the list...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="country in ctrl.countries | filter: $select.search">
<span ng-bind-html="country.name | highlight: $select.search"></span>
<small ng-bind-html="country.code | highlight: $select.search"></small>
</ui-select-choices>
</ui-select>
<h3>States</h3>
<ui-select ng-model="ctrl.state.selected" name="state" theme="bootstrap" title="Select a state">
<ui-select-match placeholder="Select or search a state in the list...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="s in ctrl.states | countryFilter: { concode: ctrl.country.selected.code }">
<span ng-bind-html="s.name | highlight: $select.search"></span>
<small ng-bind-html="s.concode | highlight: $select.search"></small>
</ui-select-choices>
<ui-select-no-choice>
<span ng-if="ctrl.country.selected.name">&nbsp; No state found for '{{ctrl.country.selected.name}}' country !</span>
<span ng-if="!ctrl.country.selected.name">&nbsp; Please select country !</span>
</ui-select-no-choice>
</ui-select>

Custom Filter:

If you have notice in abouve html code, I have created a custom search filter which search the states dropdown data based on the countyr selected using first dropdown. Here is the code for the filter:

app.filter("countryFilter", function () {
return function (items, props) {
var out = [];
if (angular.isArray(items)) {
var keys = Object.keys(props);
items.forEach(function (item) {
var itemMatches = false;
for (var i = 0; i < keys.length; i++) {
var prop = keys[i];
var text = props[prop].toLowerCase();
//if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
if (item[prop].toString().toLowerCase() === text) {
itemMatches = true;
break;
}
}
if (itemMatches) {
out.push(item);
}
});
} else {
// Let the output be the input untouched
out = items;
}
return out;
};
});

Demo: Plunker Demo

Output:

untitled

Hope this post will help you creating synchronous drop down using UI-Select.

Happy Coding !!

CSS Trick: Create tag icon with dynamic text width using Pure CSS


Hi Guys,

If you are searching for a tag icon which can be used to show few keywords on any page. Then this is the place where you can find a very simple trick to generate it with in few minutes. The icon created using this CSS trick has feature that it can take dynamic width based upon the text width. Below image is the example how it will rendered:

 

Tag Icon

 

Click here for the Demo.

Basics:

Pure CSS post tags uses at least 2 CSS tricks such as CSS triangles and CSS circles. For CSS triangles you need to manipulate borders of an element that has zero height and width. CSS circle is simpler. All you need is a square element with rounded corners set to at least half the size of the element. The border radius will then merge into a circle.

scheme

HTML

I usually markup tags with unordered list. So the markup is fairly simple:

<ul class="tags">
   <li>CSS</li>
   <li>HTML</li>
   <li>Mohit</li>
   <li>Vashishtha</li>
   <li>SharePoint</li>
 </ul>

In the CSS part :before and :after pseudo elements will do the rest of the trick and style them to achieve the styling look like a tag.

CSS

I am placing the tags list at the bottom of the post element with adjusting ULs absolute position

.tags{
	margin:0;
	padding:0;
	position:absolute;
	right:24px;
	bottom:-12px;
	list-style:none;
}

Height (and line-height) of the list item LI. Also few margins and padding and some rounded corners on the right hand side.

.tags li{
	float: left;
        height: 24px;
        line-height: 24px;
        position: relative;
        font-size: 11px;
        margin: 2px 5px 2px 12px;
        padding: 0 10px 0 12px;
        background: #0078d7;
        color: #fff;
        text-decoration: none;
        -moz-border-radius-bottomright: 4px;
        -webkit-border-bottom-right-radius: 4px;
        border-bottom-right-radius: 4px;
        -moz-border-radius-topright: 4px;
        -webkit-border-top-right-radius: 4px;
        border-top-right-radius: 4px;
}

To achieve the pointed edge we are adding a :before pseudo-element. The element has the width and height set to zero, that way we are only using it’s borders. To “draw” an arrow pointing left we are showing only the right border.

.tags li:before {
 content: "";
 float: left;
 position: absolute;
 top: 0;
 left: -12px;
 width: 0;
 height: 0;
 border-color: transparent #0078d7 transparent transparent;
 border-style: solid;
 border-width: 12px 12px 12px 0;
}

The last element to add is the :after pseudo-element. This will act as that rounded hole. What we’re doing here is creating an empty square, and we’re rounding it’s edges so we create a circle (and of course we position it with position: absolute).

.tags li:after {
 content: "";
 position: absolute;
 top: 10px;
 left: 0;
 float: left;
 width: 4px;
 height: 4px;
 -moz-border-radius: 2px;
 -webkit-border-radius: 2px;
 border-radius: 2px;
 background: #fff;
 -moz-box-shadow: -1px -1px 2px #004977;
 -webkit-box-shadow: -1px -1px 2px #004977;
 box-shadow: -1px -1px 2px #004977;
}

That was a basic html and CSS code but if someone want to make this tag as clickable then It can easily be achieved by adding anchor tag inside the LI element. Also need to add some classes to handle the hover of achor tag.

I hope this blog is helpful for you.

Happy Designing 🙂 !!

SharePoint : Custom Task Email with Outlook ribbon control “Open this Task”


Hi Guys,

It was really interesting to work with my latest client. They had an very interesting and innovated idea to automate their manual file approval process.  The requirement was to create a multistage state machine workflow where users have privilege to approve and reject documents with some comments. It was very interesting to work with end client(as they them self don’t know what they actually want).

I will not go deep into the workflow but surly will come back with another post explaining it. This post is more about a requirement which I faced during the development of the workflow. Just wanted to share the design of the Workflow:

WF

Requirement:  As a user, I should have receive an email from workflow with custom subject having document name embedded to the subject where I can directly do some action like approve/reject or comment on the document. I should see a button in email “Open this task” which will redirect me to the page where I can take actions.

1

It looks bit easy but have hidden challenges in it. Most us are aware of the fact that when a task item is created, either directly in the task list or through a Workflow an alert email would be sent saying a task has been assigned to you (provided alerts are enabled). When we look at that email in Outlook we see an additional control in the ribbon “Open this Task” under the group “Open” as shown in above figure. Let me rephrase the requirements:

  1. We have to customize the body and subject as per their request
  2. Ribbon button “Open this Task” should present when the email is sent

The above mentioned two points are two sides of the coin, which means if you are able to see one then second will not be visible to you. So the final solution’s must have some trick to achieve both cases.

Solution: 

One point is clear that we can not go along with the default workflow email feature, we have to use “SmtpClient” or “SPUtility” to create email with custom body and subjects. Now question is how one can get ribbon button using SPUtility send email function.

  • I have used “SPWorkflowTaskProperties” class in the Task Created Event and sent it two properties “SPWorkflowTaskProperties.HasCustomEmailBody = true” and “SPWorkflowTaskProperties.EmailBody= <My Custom HTML Email Body> ” With this I can satisfy requirement 1 & 2 but not 3 (listed above).  Also if I were to create a task and if I want to send an email using Event Handler on item created I may not be able to use this. So for the generic purposes this would not fit in.
  • Next I thought of modifying the alert template but then it would have an impact on all task lists which is not a recommended option.
  • So, I have decided that I have to disable the alerts for that Task list and use “SmtpClient or SPUtility” class instead to send email which can be used at different requirements such as “event handlers/workflows or any other for that matter. With this class we do have control over all the aspects “From, To, Subject, Email Body, etc”. The only problem with this to achieve the requirement # 2 (Ribbon control in outlook). I always wondered how would outlook recognize that an email is for Task, how is this ribbon control activated as soon as it sees an email.

I believed that the alert email sent has some headers which mark this as Task which is understood by outlook and displays the controls accordingly. So now the question is what are those headers. After some research I figured out the Mail message headers. Below is the code for sending an email which also includes those headers and satisfies all the above mentioned requirements (1 & 2)

/// <summary>
/// Method used to send the task created email instead of default SP WF email notification
/// </summary>
/// <param name=”web”></param>
/// <param name=”htmlBody”></param>
/// <param name=”ToEmailId”></param>
/// <param name=”listItem”></param>
/// <param name=”emailSubject”></param>
/// <returns></returns>
public bool SendTaskMail(SPWeb web, string htmlBody, string toEmailId, SPList taskList, string itemId, string emailSubject)
{
try
{
string domain = web.Site.WebApplication.OutboundMailSenderAddress.Remove(0, web.Site.WebApplication.OutboundMailSenderAddress.LastIndexOf(‘@’));
var messageHeaders = new StringDictionary();
messageHeaders.Add(“to”, toEmailId);//author.User.Email);
messageHeaders.Add(“subject”, emailSubject);
messageHeaders.Add(“content-type”, “text/html”);

messageHeaders.Add(“Message-Id”, “<3BD50098E401463AA228377848493927” + Guid.NewGuid().ToString(“D”) + domain + “>”);
messageHeaders.Add(“X-Sharing-Title”, ConvertToBase64String(“Body”));
messageHeaders.Add(“X-AlertTitle”, ConvertToBase64String(“System”));
messageHeaders.Add(“Content-Class”, “MSWorkflowTask”);
messageHeaders.Add(“X-AlertWebUrl”, ConvertToBase64String(web.Url));
messageHeaders.Add(“X-AlertServerType”, “STS”);
messageHeaders.Add(“X-AlertWebSoap”, ConvertToBase64String(web.Url + “/_vti_bin/alerts.asmx”));
messageHeaders.Add(“X-Sharing-Config-Url”, “stssync://sts/?ver=1.1&type=tasks&cmd=add-folder&base-url=” + Uri.EscapeDataString(web.Url) + “&list-url=” + Uri.EscapeDataString(taskList.RootFolder.ServerRelativeUrl) + “&guid=” + Uri.EscapeDataString(taskList.ID.ToString(“D”)));
messageHeaders.Add(“X-Sharing-Remote-Uid”, taskList.ID.ToString(“D”));
messageHeaders.Add(“X-Sharing-WssBaseUrl”, ConvertToBase64String(web.Url));
messageHeaders.Add(“X-Sharing-ItemId”, ConvertToBase64String(itemId));

SPUtility.SendEmail(web, messageHeaders, htmlBody);

return true;
}
catch (Exception ex)
{
Utilities.UpdateLogErr(ex, “Error while sending email. Please find details in audit logs”);
return false;
}
}

Hope this helps!

Thank you for your time.

Happy SharePointing 🙂 !!

SharePoint get followed sites using REST Api


Recently I was tasked with a project requirement that the user should be able to see list of content he/she followed. To me this sounds much like using the following feature of SharePoint 2013 which allows you to follow documents, sites, people and tags. Also, we don’t want the user to navigate to his/her mySite and have a look on to the content followed.

We can use the SharePoint 2013 Representational State Transfer (REST) service to do the same tasks you can do when you use the .NetCSOM, JSOM.

Here I explain how to retrieve the site name and URL followed by the current user in SharePoint 2013 using a client object model (REST API and JavaScript) and displaying it in the SharePoint page.

1. Create a new page and a Content Editor Webpart (CEWP).

Create a New page

2. Edit the web part that was added to the page.

Edit the web part

3. Upload your text file script into the site assests and copy the path of the text file and paste it into the Content link in CEWP.

4. Output

Output

Code

The following example shows how to retrieve all of the following sites:

<html>
<head>
<script type=”text/javascript” src=”//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js”></script>

<script type=”text/javascript”>
var followingManagerEndpoint;
var followedCount;

var followingEndpoint;
var URL;
var website;
var clientContext;

SP.SOD.executeFunc(‘sp.js’, ‘SP.ClientContext’, loadWebsite);
function loadWebsite() {
clientContext = SP.ClientContext.get_current();
website = clientContext.get_web();
clientContext.load(website);
clientContext.executeQueryAsync(onRequestSucceeded, onRequestFailed);
}

function onRequestSucceeded() {

URL = website.get_url();
followingManagerEndpoint = decodeURIComponent(URL) + “/_api/social.following”;

getMyFollowedContent();
}

function onRequestFailed(sender, args) {
alert(‘Error: ‘ + args.get_message());
}

// Get the content that the current user is following.
// The “types=14” parameter specifies all content types
// (documents = 2 + sites = 4 + tags = 8).
function getMyFollowedContent() {

$.ajax( {
url: followingManagerEndpoint + “/my/followed(types=14)”,
headers: {
“accept”: “application/json;odata=verbose”
},
success: followedContentRetrieved,
error: requestFailed
});
}

// Parse the JSON data and iterate through the collection.

function followedContentRetrieved(data) {
var stringData = JSON.stringify(data);
var jsonObject = JSON.parse(stringData);
var types = {
1: “document”,
2: “site”,
3: “tag”
};

var followedActors = jsonObject.d.Followed.results;
var followedList = “You’re following items:”;

for (var i = 0; i < followedActors.length; i++) {
var actor = followedActors[i];
followedList += “<p>The ” + types[actor.ActorType] + “: \”” +actor.Name + “\”</p>”+”<p>Site URL ” + “: \”” +
actor.Uri+ “\”</p>”;;
}
$(“#Follow”).html(followedList);
}

function requestFailed(xhr, ajaxOptions, thrownError) {
alert(‘Error:\n’ + xhr.status + ‘\n’ + thrownError + ‘\n’ + xhr.responseText);
}

</script>
</head>
<body>
<div id=”Follow”></div>
</body>
</html>

Happy SharePointing 🙂

SharePoint 2013: The search service is not able to connect to the machine that hosts the administration component.Verify that the administration component.


Hi,

Issue:

The search service is not able to connect to the machine that hosts the administration component. Verify that the administration component ‘GUID’ in search application ‘Search Service Application’ is in a good state and try again. In Farm Search Administration page when click on “Modify Topology” get error “An unhandled exception occurred in the user interface.Exception Information: Exception has been thrown by the target of an”

Cause: Search is not able to connect is because of name reasons, in this article I am explaining various the solution of this issue.

Solutions: Please find the below solutions, That one of it can resolve the issue.

Solution 1:

In the end it turns out to be that the application pool that hosts the search service application somehow doesn’t have the correct access.
You can simply change the application pool to use SharePoint Web Services System for search service applications and check.
1. Click on Start > Run > Type Inetmgr > Click OK

0094

 

 

 

 

 

 

 

 

 

 

 

2.  In IIS > Expand server > Expand sites > Expand “SharePoint Web Services”
0096

3. Now check all the GUID 1 by 1 in content view unless you find searchadmin.svc and searchservice.svc

0095

4. Right click GUID go to advance settings

0097

5. Change the application to “SharePoint Web Services” > Click OK
0098

Solution 2: Enable the timer job and do IIS reset

1. Run below PS command to know the status of timer job
Get-SPTimerJob job-application-server-admin-service
Result ==> Is Disabled: True

  1. Run below PS command to enable the service.
    Enable-SPTimerJob job-application-server-admin-service
    Result ==> IsDisabled: False
  2. Do Net Stop sptimerv4
  3. Do Net start sptimerv4
  4. DO iisreset

Solution 3:Ensure the account has full control permissions on the Search service application and IIS account used by this service application
Follow below steps
1. Open Central Admin  > Select Security > Select “Configure service accounts”
0092

2. Select the search service application

0093

3.   For “select account for this component” Select a account which has full permission

Hope that helps. Happy SharePointing 🙂

Fix for Memory leak by Noderunner.exe


Hi,

Issue: My virtual development machine is allocated 8 GB RAM out of 16 GB of Host. Still it runs very slow. In order to develop things I have to stop the Search service and memory consumption reduced to ~5GB from 6-7GB. But this is just a work around what if I need to build some module which requires Search service.

A quick investigation in Task Manager highlight Memory usage by search components are much large then other processes. Several NodeRunner.exe processes consume lots of Memory and CPU. The culprit processes are Microsoft SharePoint Search component.

image_thumb1

Although there is no problem with just killing the noderunner.exe processes in Task Manager; SharePoint creates them again almost immediately.

Cause:

The architecture of search has undergone lot of changes in SharePoint 2013. Many of the core components are replaced by the FAST Search components. Below are a few new components which are added in the new architecture

  • Crawl Component
  • Content Processing Component
  • Query Processing Component
  • Index Component
  • Analytic Processing Component

All these components run as a process called ‘noderunner.exe’. On a default single server installation of SharePoint there will five instances of noderunner.exe (one for each of the component listed above). There is another process called ‘Host Controller’, which monitors the noderunner processes. If any of the noderunner.exe fails, the host runner will restart that process.

Resolution:

1. Open SharePoint 2013 Management Shell and type in:

             Set-SPEnterpriseSearchService -PerformanceLevel Reduced

image_thumb2

2. To ensure the setting has been changed enter the following command:

Get-SPEnterpriseSearchService

image_thumb3

3. Open NodeRunner process configuration file below in Notepad

C:\Program Files\Microsoft Office Servers\15.0\Search\Runtime\1.0\noderunner.exe.config.
Update <nodeRunnerSettings memoryLimitMegabytes=”0″ />.
This is the configuration to limit NodeRunner process memory usage, replace 0 to acceptable number like 100 or 250.

image_thumb4

image_thumb6

4. Restart SharePoint Search Host Controller service. Better if it is possible to restart the server.

Conclusion:

Search has become the most integral part in SharePoint 2013 now. So, it’s not a good idea to stop search service or any of its component. But one can limit the memory usage or reduce the performance level for Search Service. By default the performance level for a Search Service is set to Maximum.

Happy SharePointing 🙂 !!

Not able to Edit web part


Hi,

It is weird if you have full rights and still you are not able to edit the web parts. Well I should say its exacted in some sense. SharePoint is a product which gives flexibility to configure your portal as you want. So what is the trick behind this issue.

Let me clear it should not treated like an issue instead its a security setting which is restricting users having full permissions to even edit the web parts on web application. So question is where can I find this setting.

Central Admin > Application Management > Manage Web applications >  select your web application >Web Part Security.

As per this setting you can configure:

1) Web Part Connections: Allow users to create connection between webparts

2) Online Web Part Gallery: Allow user to access the online web part Gallery.

3) Scriptable Web Parts: Allow contributors to add and edit scriptable Web parts

We are more interested in the third setting which allows/restrick contributors to edit of add web parts.

There are two possible ways you can achieve editing web parts on the page:

I) Disable this setting I mention in Central Administration like this:
– Go to Central Admin > Application Management > Manage Web applications
-select your web application that you want to make this change on (yes, this can only be done at the web application level which kind of sucks)
-select ‘Web Part Security’
-scroll down to ‘Scriptable Web Parts’ and select ‘Allows contributors to add or edit scriptable Web Parts’
-click OK

Capture

II) If you do not want to disable this setting, give the Full Control user ‘Approve’, ‘Manage’ and ‘Designer’ permissions, in ADDITION to ‘Full Control’

Hope this blog will help you achieving what you want.

Happy SharePointing 🙂