Tag Archives: jQuery

Enable Search feature for SharePoint Lookup Table – Single Value Only

Today I want to talk about how to enable search feature in your SharePoint New/Edit Form for SharePoint Lookup field… I’m gonna use jQuery and jQuery UI’s Autocomplete widget to fulfill this feature.

Let’s assume you have a list called “Lookup” with all your items (to be lookup) and a list “Lookup Test” that lookup to list “Lookup”‘ title. By default, a lookup field does not allow you to do “contains” search (which is kinda very common to have nowadays).

I’m attaching the comparison of the before and after applying the tricks that I’m gonna cover in this post.

search lookup comparison

This is assuming that you already have a SharePoint Designer 2013 and you’ve created two lists as mentioned above.

First of all, Open your SharePoint Designer, navigate to your SharePoint Site and Open the New Form of the “Lookup Test” list.

search lookup designer 2

Once it is opened, make sure you have already click “Advanced Mode” in order to edit the NewForm.aspx

search lookup field 1

Scroll to place holder “PlaceHolderAdditionalPageHead” content placeholder and include the necessary JS/CSS


<script src="https://code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css"/>

<style>
.custom-combobox {
position: relative;
display: inline-block;
}
.custom-combobox-toggle {
position: absolute;
top: 0;
bottom: 0;
margin-left: -1px;
padding: 0;
}
.custom-combobox-input {
margin: 0;
padding: 5px 10px;
}
</style>

search lookup field 2

Scroll to right before the closing tag of placeholder “PlaceHolderMain” and insert the following JS Code


<script type="text/javascript">
(function( $ ) {
$.widget( "custom.combobox", {
_create: function() {
this.wrapper = $( "<span>" )
.addClass( "custom-combobox" )
.insertAfter( this.element );

this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},

_createAutocomplete: function() {
var selected = this.element.children( ":selected" ),
value = selected.val() ? selected.text() : "";

this.input = $( "<input>" )
.appendTo( this.wrapper )
.val( value )
.attr( "title", "" )
.addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy( this, "_source" )
})
.tooltip({
tooltipClass: "ui-state-highlight"
});

this._on( this.input, {
autocompleteselect: function( event, ui ) {
ui.item.option.selected = true;
this._trigger( "select", event, {
item: ui.item.option
});
},

autocompletechange: "_removeIfInvalid"
});
},

_createShowAllButton: function() {
var input = this.input,
wasOpen = false;

$( "<a>" )
.attr( "tabIndex", -1 )
.attr( "title", "Show All Items" )
.tooltip()
.appendTo( this.wrapper )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass( "ui-corner-all" )
.addClass( "custom-combobox-toggle ui-corner-right" )
.mousedown(function() {
wasOpen = input.autocomplete( "widget" ).is( ":visible" );
})
.click(function() {
input.focus();

// Close if already visible
if ( wasOpen ) {
return;
}

// Pass empty string as value to search for, displaying all results
input.autocomplete( "search", "" );
});
},

_source: function( request, response ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
response( this.element.children( "option" ).map(function() {
var text = $( this ).text();
if ( this.value && ( !request.term || matcher.test(text) ) )
return {
label: text,
value: text,
option: this
};
}) );
},

_removeIfInvalid: function( event, ui ) {

// Selected an item, nothing to do
if ( ui.item ) {
return;
}

// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children( "option" ).each(function() {
if ( $( this ).text().toLowerCase() === valueLowerCase ) {
this.selected = valid = true;
return false;
}
});

// Found a match, nothing to do
if ( valid ) {
return;
}

// Remove invalid value
this.input
.val( "" )
.attr( "title", value + " didn't match any item" )
.tooltip( "open" );
this.element.val( "" );
this._delay(function() {
this.input.tooltip( "close" ).attr( "title", "" );
}, 2500 );
this.input.autocomplete( "instance" ).term = "";
},

_destroy: function() {
this.wrapper.remove();
this.element.show();
}
});
})( jQuery );

</script>

The similar javascript can be found in jQuery UI Autocomplete Combobox example

Within the same location, insert the following script to convert the lookup field into combo box with search feature.


//Change the lookupField base on the internal field name that you want to enable search feature.

var lookupField = "Lookup";

ExecuteOrDelayUntilBodyLoaded(function(){

$('select[id^="' + lookupField + '"][id$="LookupField"]').combobox();

});

search lookup field 3

Save your NewForm.aspx  and you will be prompted warning message saying that the page will no longer base on the site definition, which is okay. Click Yes to see the miracle!

Once you are happy, make sure you do the same steps for your EditForm.aspx.

 

 

 

My Top 5 Favourite jQuery Plugins for Web Design

Hi, It has been a while for me to stop posting new blogs. Today, I would like to share a bit of my web designing experience after googling and searching around to implement a sleek, elegant and yet simple jQuery plugin that may help you to improve the aesthetic of your website.

It’s worth taking a little of effort to learn and the rewards could be really great. Doing just a simple text, inserting images and setting colours is no longer enough for a good web design nowadays. It needs to be responsive, animated (in a simple and light way of course) and well, organised. I’m gonna list out the top 5 favourite plugin and do a simple demo here. I hope they will help!

WOW

A simple effect that make your website lively.

Try to see Paragraph below

WOW – Fade In Left

WOW – Fade In Down

The trick is simple, include the Animate.css and wow.min.js to your website and add “wow” and “fadeInLeft” or “fadeInUp” to any HTML DOM element that you want to have the WOW effect.

for example


<p class="wow fadeInLeft">WOW - Fade In Left</p>
<p class="wow fadeInDown">WOW - Fade In Down</p>

There are more effect available other than the two mentioned above. Just click on the Header to go to the official site.

matchHeight

At times, your content or paragraph may have different height and you want to align them vertically and ensure they both end at the point.
You’ve got matchHeight to help you on this!
Before

This is a Sample 1

And with some random text with shorter Height

This is another Sample

And again with some random text but this time round, we have more content and it is quite length!!

After

This is a Sample 1

And with some random text with shorter Height

This is another Sample

And again with some random text but this time round, we have more content and it is quite length!!

This is another Sample3

And with some random text with shorter Height

This is another Sample4

And again with some random text but this time round, we have more content and it is quite length!!

New Line 1

New Line 2

 

To achieve this, you need to include jquery.matchHeight.js and ensure your DIV is having ‘data-mh’ attribute.
Those DIV with the same value will be grouped and adjusted together.
Like above sample

<div>
 <div data-mh='items-a'></div>
 <div data-mh='items-a'></div>
</div>
<div>
 <div data-mh='items-b'></div>
 <div data-mh='items-b'></div>
</div>

smoothscroll

Easing scrolling movement has become one of the simple and yet nice effect to incorporate into your web page. Native browser scroll and move is too dull and it doesn’t really make mobile viewer who are scrolling the page using finger, to navigate the page well. To avoid this, let’s include a tweak to your web pages.

Download jquery-mousewheel and simov/simplr-smoothscroll. Include them into the Head of your web page

Run the following Javascript

$(document).ready(function(){
 $.srSmoothscroll({
        step:150,
        speed:800
      });
});

See DEMO

Stellar

Another powerful jQuery plugin that you will not regret using it. Stellar, the name may not means anything to you but let’s see what this guy does.

You can find the Stellar JS here and include again into your Head section of your web page. In this post, I will briefly cover how to use inline DOM attribute to archive the effect. For more information, please refer to Stellar Official Site.

A Div with a random image as background and a long written text above it. Scroll down and see the effect.

My New Home

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin gravida tellus id consectetur elementum. Phasellus eu nisl sit amet urna laoreet auctor. Sed commodo urna ante, eu bibendum elit ultrices eget. Sed leo dui, ornare ut lectus aliquet, maximus pulvinar lacus. Mauris id commodo metus, ac faucibus est. Suspendisse ultricies ullamcorper ante id pharetra. Etiam lobortis magna id elit consectetur cursus.

Mauris maximus nulla id sapien ornare, sit amet ornare sem ornare. Maecenas ante turpis, vehicula sed bibendum et, porta in massa. Vestibulum imperdiet nec augue et auctor. Aenean interdum urna erat, ut vulputate urna pharetra quis. Nullam sit amet scelerisque lacus. Nunc pulvinar quam dolor, at fermentum tortor ultrices eget. Donec dignissim sapien sed sapien suscipit sodales. Praesent magna odio, ultricies quis ipsum at, volutpat aliquet ligula.
=
Nulla nec lectus egestas, ultricies dolor et, gravida libero. Vivamus egestas mi sed eros scelerisque iaculis. In hac habitasse platea dictumst. Aliquam gravida vehicula ante eget commodo. Quisque ornare auctor aliquet. Sed tempus est et erat laoreet ultricies. Praesent blandit pharetra accumsan. Vivamus vitae turpis consectetur, lacinia diam eu, consequat tellus. Maecenas at dapibus turpis. Aliquam erat volutpat. Donec dictum sagittis purus, condimentum euismod dolor vehicula ac. Aliquam iaculis eget enim mollis consectetur. Maecenas vitae purus nisi. Vivamus risus libero, tempus in facilisis eu, facilisis a nibh.

Nullam sed gravida neque. Suspendisse in magna vulputate, tempus lacus in, iaculis quam. Phasellus cursus interdum ipsum, vitae dapibus metus facilisis non. Maecenas vitae luctus mi. Nulla ut ultrices purus, in pretium ipsum. Vivamus vel ligula malesuada, malesuada ante vel, consectetur risus. Ut ultrices laoreet laoreet. Ut iaculis tristique nibh, ac vulputate nulla aliquam vel. Ut condimentum ex est, quis vestibulum orci ornare vel. Sed facilisis blandit nisi in bibendum.

Nam dignissim turpis vel egestas tincidunt. Quisque auctor sagittis erat id ultrices. Interdum et malesuada fames ac ante ipsum primis in faucibus. In vel sem vel ipsum congue vehicula. Vestibulum diam ex, auctor maximus blandit sed, varius eu magna. Vivamus sollicitudin purus ac rutrum tempor. Nulla sollicitudin pellentesque elit, ut pretium dui pharetra non. Vestibulum varius magna nulla, id tincidunt velit pharetra nec. Ut rhoncus nec leo eu semper. Curabitur ac varius libero. Suspendisse scelerisque porttitor eros et lobortis. Donec vitae convallis eros.

Sed nibh neque, ultricies eget tortor a, fringilla tempus ligula. Donec fermentum diam ac enim consectetur, in viverra odio sagittis. Pellentesque rutrum convallis nulla, sed luctus ipsum semper ac. In sit amet dignissim orci, condimentum luctus eros. Vivamus tempus auctor mi vel pellentesque. Etiam laoreet, magna nec ultricies molestie, orci lorem feugiat justo, non efficitur enim quam eu enim. In faucibus tellus id libero bibendum mollis. Duis ut sapien eget sapien dapibus molestie non quis nibh. Nunc sollicitudin, dui vel blandit posuere, diam justo dictum nibh, quis euismod nisi dolor quis elit.

Nulla id ligula vitae ante fringilla auctor et et sapien. Quisque sit amet viverra est. Aliquam imperdiet, risus vel interdum sagittis, justo arcu bibendum leo, vitae porttitor quam erat a ex. Maecenas viverra est id vehicula tempus. Pellentesque mattis ac nibh eu posuere. Donec tincidunt orci quis fermentum convallis. Morbi faucibus tellus ac massa tincidunt laoreet. In odio erat, maximus eu rhoncus a, blandit vitae felis. Phasellus nec erat nisl. Fusce ac facilisis arcu. In hac habitasse platea dictumst. Duis faucibus semper scelerisque.

To archive this, Insert the stellar attribute to your Div like below. Note that I also include some background css to make it nicer.

<div style="background-image: url('YOUR_IMAGE_URL');
   background-size: 100%;
   background-repeat:no-repeat;
   color:#ededed;
   padding:10px;
   border:2px solid #888888;"
   data-stellar-background-ratio="-0.2"
   data-stellar-vertical-offset="0">

   Your Content goes here...

</div>

Once you have the DOM Added, run JavaScript like below to trigger the Stellar effect

jQuery(function () {
 jQuery(window).stellar({horizontalScrolling: false});
});

 

mobile menu

The last and also very important component in modern web design is Responsive Mobile Menu. With Touch experience, Hover in Menu is no longer desirable in mobile view, we have to think from the point when users are browsing in a small screen and your menu bar must be Big enough to be able to Touch.
To achieve that, Responsive Mobile Menu is here to help you.

First of all, include all the necessary JavaScript into your web pages

<link rel="stylesheet" href="http://responsivemobilemenu.com/demo/rmm-css/responsivemobilemenu.css" type="text/css"/>
<!-- Include JQUERY if you haven't -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="http://responsivemobilemenu.com/demo/rmm-js/responsivemobilemenu.js"></script>

Note that i’m mapping from a demo script. You may want to download from the original source and upload to your web server before making the reference

Assuming your menu are something like below

    <div style="width:500px">
        <div class="rmm" data-menu-style="graphite">
            <ul>
                <li><a href='#home'>Home</a></li>
                <li><a href='#about-me'>About me</a></li>
                <li><a href='#gallery'>Gallery</a></li>
                <li><a href='#blog'>Blog</a></li>
                <li><a href='#links'>Links</a></li>
                <li><a href='#sitemap'>Sitemap</a></li>
            </ul>
        </div>
    </div>

A live sample is shown below: (with fixed 500 px)

Same sample with longer 100% width

 

Putting them all together

Header 1

And with some random text with shorter Height

Header 2

And again with some random text but this time round, we have more content and it is quite length!!

Header 3

And with some random text with shorter Height

Header 4

And again with some random text but this time round, we have more content and it is quite length!!

 

Nulla id ligula vitae ante fringilla auctor et et sapien. Quisque sit amet viverra est. Aliquam imperdiet, risus vel interdum sagittis, justo arcu bibendum leo, vitae porttitor quam erat a ex. Maecenas viverra est id vehicula tempus. Pellentesque mattis ac nibh eu posuere. Donec tincidunt orci quis fermentum convallis. Morbi faucibus tellus ac massa tincidunt laoreet. In odio erat, maximus eu rhoncus a, blandit vitae felis. Phasellus nec erat nisl. Fusce ac facilisis arcu. In hac habitasse platea dictumst. Duis faucibus semper scelerisque.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Nulla id ligula vitae ante fringilla auctor et et sapien. Quisque sit amet viverra est. Aliquam imperdiet, risus vel interdum sagittis, justo arcu bibendum leo, vitae porttitor quam erat a ex. Maecenas viverra est id vehicula tempus. Pellentesque mattis ac nibh eu posuere. Donec tincidunt orci quis fermentum convallis. Morbi faucibus tellus ac massa tincidunt laoreet. In odio erat, maximus eu rhoncus a, blandit vitae felis. Phasellus nec erat nisl. Fusce ac facilisis arcu. In hac habitasse platea dictumst. Duis faucibus semper scelerisque.

 

Nulla id ligula vitae ante fringilla auctor et et sapien. Quisque sit amet viverra est. Aliquam imperdiet, risus vel interdum sagittis, justo arcu bibendum leo, vitae porttitor quam erat a ex. Maecenas viverra est id vehicula tempus. Pellentesque mattis ac nibh eu posuere. Donec tincidunt orci quis fermentum convallis. Morbi faucibus tellus ac massa tincidunt laoreet. In odio erat, maximus eu rhoncus a, blandit vitae felis. Phasellus nec erat nisl. Fusce ac facilisis arcu. In hac habitasse platea dictumst. Duis faucibus semper scelerisque.

Facebook Access Token Request does not work in IE 8

Integrating Facebook Feeds to your Web Application could be a very common thing nowadays. Supporting this integration across different browser could be a headache for most developers out there. Including me myself.

At the end of this session, you will know how to perform an AJAX request to query Facebook feeds access token at client side which support IE 8 Browsers and all other Modern browsers. Using jQuery 1.9

Note: You can only do client side query if your web servers are not having internet connectivity to Facebook. Especially “graph.facebook.com” where you perform access token retrieval and Graph API.

First of all, you need a jQuery and Facebook JS like this

<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head></pre>
<body>
 <div id="fb-root">
 <script type="text/javascript" src="https://connect.facebook.net/en_US/all.js"></script>
 </div>
...
</body>

And then you need this to initialise FB SDK

<script type="text/javascript">
var access_tokenParam = ""; //to store the access token
var appId = "" // YOUR APP ID HERE
var appSecret = "" //APP SECRET;

window.fbAsyncInit = function () {
 FB.init({
 appId: appId, //App Id
 status: true,
 xfbml: true
 });

};
</script>

Lastly, you need create a Facebook App (if you have not) for an App ID and App Secret key. You can get it here App DashBoard

Note that you need to set your App to use the testing domain URL. In my cases, i use “facebooktest.com”

facebook app dashboard setting

Not to forget to map this URL to your 127.0.0.1 in hosts file (C:\Windows\System32\drivers\etc\hosts)

127.0.0.1 facebooktest.com

To share what happened before i come to a workaround, below are the JavaScript to obtain Facebook access token to perform Graph API. THIS WORKS in all other browser EXCEPT Internet Explore 8.


$.support.cors = true; //

$.ajax({
 type: "POST",
 url: "https://graph.facebook.com/oauth/access_token",
 cache: false,
 data: {
 "client_id": appId,
 "client_secret": appSecret,
 "grant_type": "client_credentials"
 },
 error: function (xhr, status, error) {

//ERROR THROWN TypeError: Access is Denied for IE8
 },
 success: function (response) {

 },
 complete: function (request, textStatus) {
 if (request.responseText != null) {
 access_tokenParam = request.responseText.split('=')[0] + "=" + escape(request.responseText.split('=')[1]);
//access_tokenParam will be the token that you will then be used for subsequently Graph call
 }

}
 });

If this script runs on IE 8, you will hit TypeError: Access is Denied This is due to IE 8 does not use the XMLHttpRequest, but an alternative object named XDomainRequest. Some googling suggested using JSONP. Alright, lets try.

$.ajax({
 type: "POST",
 url: "https://graph.facebook.com/oauth/access_token",
 cache: false,
 dataType: "jsonp",
 data: {
 "client_id": appId,
 "client_secret": appSecret,
 "grant_type": "client_credentials"
 },

error: function (xhr, status, error) {

//ERROR Thrown "Parseerror" in IE8 AGAIN...
 });

The above both attempts to get the access token failed in IE8. After digging deeper to Facebook Documentation, i found this

There is another method to make calls to the Graph API that doesn't require using a generated app token. You can just pass your app id and app secret as the access_token parameter when you make a call:
http://graph.facebook.com/endpoint?key=value&access_token=app_id|app_secret
The choice to use a generated access token vs. this method depends on where you hide your app secret.

Holy cow…

What you need to do is just setting your access token as per below

access_tokenParam = “access_token=XXX|YYY”

where XXX is your App ID and YYY is your App Secret. e.g. “access_token=778487422177917|gu_TZwkQe5jtBj7VvZpMJX8odlx”

don’t try to use it, it is not valid =)

Knowning that the Access Token needs not to be provided by Graph, you may then perform API call like this (taking my posts as example)


access_tokenParam = 'access_token=' + appId + '|' + appSecret;
renderFBNewsFeed('yihaa5', access_tokenParam);

function renderFBNewsFeed(id, access_tokenParam) {
 var url = '/' + id + '/posts?' + access_tokenParam;
 FB.api(url, { return_ssl_resources: 1 }, function (response) {
 if (response.data) {
 var html = "";
 for (var i = 0; i < response.data.length; i++) {
 var obj = response.data[i];
 var fakeTitle = obj.name ? obj.name : (obj.story ? obj.story : obj.message );
 var fakeDes = obj.description? obj.description : obj.caption;
 html += "<h2>" + fakeTitle + "</h2>";
 html += "<h3>" + fakeDes + "</h3>";
 }
 $("#fbNewsWrapper").html(html);
 }
 });

}

You can find the entire html file here Hope it helps!

Toggling SharePoint 2010 Calendar View using JavaScript

Calendar is a very common used  module in SharePoint, it comes with 3 OOTB views namely Daily, Weekly and Monthly. Toggling between these views can be easily done using Ribbon button provided. However, there would be cases where you need to run your own JavaScript, perhaps to have a custom button to toggle the views of your calendar.

SharePoint has a in-built javascript function MoveDate which takes in a single parameter that is the view mode to be toggled.

For example


MoveDate('day')

This method simply toggle the current calendar control to ‘Daily’ view. Likewise, passing ‘week’ and ‘month’ will toggle the calendar to weekly and monthly view respectively.

This method however, doesn’t provide the flexibility to specify which calendar you want to toggle view. Imagine if you have more than 1 calendar control added into one single page. This method will just toggle the first loaded instance of calendar control. That’s not good.

Having digging deeper to the SharePoint javascript, there is a hidden function called ‘_MoveToDate(a,b,c)‘ which does the trick. Well I personally do not know what is parameter a for, however, parameter b is the view mode and c is the calendar instance id.

Making use of parameter b and c is good enough to get you toggling view of a specific calendar

That is, making a js call _MoveToDate(null,’day’,’the calendar id‘) will toggle the respective calendar control with ‘the calendar id’ to Daily view.

Now the second question is how to actually retrieve the so-called calendar id? To get that, it requires a little bit of jQuery Selector knowledge (You can read up here). In my case, I added the toggle buttons (within a DIV tag) on top of each calendar control. With this, i would call my custom js ToggleCalendar function with this  as the parameter. Firstly, lookup to the parent DOM object of this and get the sibling <table> tag (SharePoint Calendars are encapsulated within HTML tables, check View Source if you like). After getting the Table DOM, lookup for TD tag with ID starts wth “WebPartTitle”, reason being is that the ID of the calendar is in this format “WebPartTitleXXXX” where XXXX is the calendar instance ID and it is  usually WPQ1 or WPQ2 and so on depending on the number of calendar control you added to your page.

The code below simply showing how to retrieve a SharePoint calendar instance ID, and also to toggle its view to Daily view.


function GetInstanceID(obj)
{
$tdTag = $(obj).parent().siblings('table').find('td[id^="WebPartTitle"]');
var rawID = $($tdTag).attr('id');
return rawID.substring('WebPartTitle'.length);
}

function ToggleCalendar(obj)
{
_MoveToDate(null,'day',GetInstanceID(obj));
}

P.S. The code is with assumption that sp.js has been loaded successfully and you have also included jQuery file.