<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SharePoint Archives - Michael Soriano</title>
	<atom:link href="https://michaelsoriano.com/category/sharepoint/feed/" rel="self" type="application/rss+xml" />
	<link>https://michaelsoriano.com/category/sharepoint/</link>
	<description>I turn code into captivating user experiences for the web</description>
	<lastBuildDate>Wed, 14 Feb 2024 18:36:26 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.4</generator>
	<item>
		<title>Create Custom HTML Forms for SharePoint with this jQuery Plugin</title>
		<link>https://michaelsoriano.com/sharepoint-forms-custom-html/</link>
					<comments>https://michaelsoriano.com/sharepoint-forms-custom-html/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Tue, 21 Nov 2017 17:32:54 +0000</pubDate>
				<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[jQuery]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6024</guid>

					<description><![CDATA[<p>There is a big need to build fully customizable forms in SharePoint. I have tried several form builders, but wasn&#8217;t really happy with the restrictions that it comes with. So I wrote this plugin that will create HTML forms in SharePoint. It requires very little code (it&#8217;s all HTML). But the most important thing is [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/sharepoint-forms-custom-html/">Create Custom HTML Forms for SharePoint with this jQuery Plugin</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>There is a big need to build fully customizable forms in SharePoint. I have tried several form builders, but wasn&#8217;t really happy with the restrictions that it comes with. So I wrote this plugin that will create HTML forms in SharePoint. It requires very little code (<em>it&#8217;s all</em> HTML). But the most important thing is &#8211; it&#8217;s customizable.</p>



<p>There is basically no limit on what you can do.</p>



<p>The gist of it is, all you have to do is match the column names in SharePoint &#8211; to the field in the List. That also means you can arrange the fields, labels, messaging, colors &#8211; just about anything you want.</p>



<p>Again, it&#8217;s all HTML.</p>



<p class="btn"><a href="https://github.com/michaelsoriano/sp-forms">View in GitHub</a></p>



<p>This is a jQuery plugin, so it needs jQuery. The optional Bootstrap CSS can also be added (not required) &#8211; to get you a jump ahead on responsive and styles. The output will be something like below:</p>



<p><br><img fetchpriority="high" decoding="async" width="725" height="675" class="alignnone size-full wp-image-6234" style="border: 1px solid #ebebeb;" src="https://michaelsoriano.com/wp-content/uploads/2017/11/submit.gif" alt="submit form"></p>



<p>The best way to get up and running is by downloading the files editing the HTML. That&#8217;s all. The types of fields (IN THE HTML) that are supported are:</p>



<ul class="wp-block-list">
<li>text</li>



<li>select (drop down lists)</li>



<li>checkbox &#8211; (multiple values)</li>



<li>radio buttons &#8211; (single value)</li>



<li>textarea (multi line text)</li>



<li>file (upload an attachment)</li>
</ul>



<p>There is built-in input validation, loading image, &#8220;thank you&#8221; and &#8220;error&#8221; messaging. Again, you customize these fields by simply updating HTML.</p>



<h3 class="wp-block-heading">How does the Form link with the SharePoint List?</h3>



<p>The HTML part of the form connects with the list via &#8220;attributes&#8221;. To be exact, &#8220;data-list-name&#8221; refers to the List name, and each field will have a &#8220;name&#8221; attribute which refers to the column in your said SharePoint list.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;div data-list-name="sp-forms-form2" ... ></code></pre>



<p>The above shows that we&#8217;re connecting to &#8220;<strong>sp-forms-form2</strong>&#8221; list. This DIV is not exactly a &#8220;Form&#8221; &#8211; but a wrapper for all of the fields, messaging and buttons that we need. So this DIV is very important.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;input name="Title" ... /></code></pre>



<p>The above field shows that we&#8217;re connecting to the column &#8220;<strong>Title</strong>&#8221; in the &#8220;<strong>sp-forms-form2</strong>&#8221; list.<br>Easy enough? Let&#8217;s continue.</p>



<div style="background: #fff6c8; padding: 15px 25px; margin-bottom: 25px; margin-top: 20px; border-top: 1px solid #e2dbb5; border-bottom: 1px solid #e2dbb5;"><strong>Important: </strong>You have to know that all of the fields from this form will be saved your list using the &#8220;text&#8221; datatype, except a &#8220;textarea&#8221; &#8211; which will be a &#8220;Multiple lines of text&#8221;.</div>



<figure class="wp-block-image"><img decoding="async" width="572" height="406" src="https://michaelsoriano.com/wp-content/uploads/2017/11/create-column.png" alt="column create" class="wp-image-6227" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/create-column.png 572w, https://michaelsoriano.com/wp-content/uploads/2017/11/create-column-300x213.png 300w" sizes="(max-width: 572px) 100vw, 572px" /></figure>



<h4 class="wp-block-heading">Do not use any type &#8211; it will not insert.</h4>



<p>Again, use only &#8220;Single line of text&#8221; for all fields except a &#8220;textarea&#8221; &#8211; which is &#8220;Multiple lines of text&#8221;.&nbsp; *All values from the form will be inserted as plain text. Checkbox (multiple values) will be separated by a semicolon, but still as text.</p>



<h3 class="wp-block-heading">How to add validation?</h3>



<p>For each field, you can a set of validation rules. For now, we only have &#8220;required&#8221;, &#8220;date&#8221;, &#8220;email&#8221; and &#8220;phone&#8221;. Simply add the rules to the input/textarea/select as an attribute called &#8220;<strong>data-rules</strong>&#8220;. And if you need to use more than one, simply separate it with a pipe &#8220;|&#8221;.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;input data-rules="required|email" ...</code></pre>



<p>The output will look behave like below:</p>



<p><img decoding="async" width="725" height="321" class="alignnone size-full wp-image-6235" style="border: 1px solid #ebebeb;" src="https://michaelsoriano.com/wp-content/uploads/2017/11/validation.gif" alt="validation"></p>



<p>Are you still with me? Awesome.</p>



<h3 class="wp-block-heading">How to add a Drop Down List?</h3>



<p>A drop down list is simply a &#8220;<strong>select</strong>&#8221; tag in HTML. It&#8217;s basically a select tag, with &#8220;options&#8221; inside it. The &#8220;options&#8221; are the drop down values. It looks something like below:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;select name="countries">
   &lt;option value="">--&lt;/option>
   &lt;option value="USA">USA&lt;/option>
   ...
   ...
   ...
&lt;/select></code></pre>



<p>Simply add more options to the &#8220;select&#8221; tag to build your drop down list.</p>



<p><strong>How about a textarea, checkbox and radio buttons?</strong> </p>



<p>Those are all in the <a href="https://github.com/michaelsoriano/sp-forms/blob/master/sp-forms.html">demo HTML</a>: It is fully documented and you should be able to figure it out easily. Note that you will need to open this in an HTML editor such as <a href="https://notepad-plus-plus.org/">Notepad++</a> or <a href="https://code.visualstudio.com/">VSCode</a>. Don&#8217;t do regular notepad. Just don&#8217;t.</p>



<p><strong>How about People pickers? Date Pickers?</strong></p>



<p>The plugin itself doesn&#8217;t have it. But its just HTML + JavaScript. Simply add them on document ready. That&#8217;s the beauty of this plugin. You&#8217;re free to do anything you want because you&#8217;re dealing with the code.</p>



<p><strong>How to get the label &#8220;inside&#8221; the text input?</strong></p>



<p>This one is a little tricky. I find it easier to use the &#8220;placeholder&#8221; attribute, than to use a &#8220;label&#8221;. So do something like below:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;input placeholder="Label here..." ></code></pre>



<p>Anything else that you want to do with the labels and fields should be doable. For example, making the fonts bigger, making the widths of the fields wider &#8211; adding plugins, it&#8217;s completely up to you.</p>



<h3 class="wp-block-heading">What happens when I click &#8220;Submit&#8221;</h3>



<p>Clicking submit will add the record into the list that you&#8217;ve added inside the list that you&#8217;ve specified in the &#8220;data-list-name&#8221; wrapper that we have.</p>



<p>Let&#8217;s say you have everything in place, a new record will go inside your list once you click &#8220;<strong>Submit</strong>&#8220;:</p>



<p><img decoding="async" width="750" height="421" class="alignnone size-full wp-image-6231" src="https://michaelsoriano.com/wp-content/uploads/2017/11/item-inserted.png" alt="item inserted" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/item-inserted.png 750w, https://michaelsoriano.com/wp-content/uploads/2017/11/item-inserted-300x168.png 300w" sizes="(max-width: 750px) 100vw, 750px" /></p>



<p><strong>Can I view the submitted record?</strong></p>



<p>By default, as soon as the form submits &#8211; it goes to the newly added record. This means that the url will change to a:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">http://yoursite.com/yourpage.aspx?form1=25</code></pre>



<p>This will be the &#8220;permanent&#8221; url for the record. If you want to go back to a black form &#8211; simply remove the &#8220;?form1=xxx&#8221; from the address bar.</p>



<p>In the default &#8220;Thank you&#8221; message there is a link to create another record:</p>



<p><img decoding="async" width="426" height="318" class="alignnone size-full wp-image-6251" src="https://michaelsoriano.com/wp-content/uploads/2017/11/add-another.png" alt="" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/add-another.png 426w, https://michaelsoriano.com/wp-content/uploads/2017/11/add-another-300x224.png 300w" sizes="(max-width: 426px) 100vw, 426px" /></p>



<p>Clicking this link will reload the page &#8211; with the form fields ready to go.</p>



<p><strong>Can I customize the &#8220;Thank You&#8221; message?</strong></p>



<p>Yes definitely. Again, go to the HTML and you will see the thank you messaging wrapped in it&#8217;s own DIV:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;div class="success-message" style="display:none;">
   Thank you for your submission. Click Here ...
&lt;/div></code></pre>



<p><strong>Where does the attachment go?</strong></p>



<p>The input field of type &#8220;file&#8221; and MUST be named &#8220;<strong>attachment</strong>&#8221; will add the file as an &#8220;attachment&#8221; to the list item:</p>



<p><img decoding="async" width="616" height="421" class="alignnone size-full wp-image-6232" src="https://michaelsoriano.com/wp-content/uploads/2017/11/item-inserted-w-attachment.png" alt="item inserted" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/item-inserted-w-attachment.png 616w, https://michaelsoriano.com/wp-content/uploads/2017/11/item-inserted-w-attachment-300x205.png 300w" sizes="(max-width: 616px) 100vw, 616px" /></p>



<p>The code for this field looks like below. Again, refer to the HTML and it should have this field already setup for you.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;input type="file" name="attachment"></code></pre>



<p><strong>Important: </strong>You don&#8217;t need to create a column named &#8220;attachment&#8221; in the list. SharePoint allows an attachment to be tied up to each list item. This is a pretty cool feature.</p>



<h3 class="wp-block-heading">How do I install the plugin?</h3>



<p>Let&#8217;s begin by grabbing the files from <a href="https://github.com/michaelsoriano/sp-forms/archive/master.zip">Github</a>. Unzip the package, and upload to a document library in your SharePoint site. It will look something like below:</p>



<p><img decoding="async" width="666" height="443" class="alignnone size-full wp-image-6229" src="https://michaelsoriano.com/wp-content/uploads/2017/11/files-in-doclib.png" alt="files" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/files-in-doclib.png 666w, https://michaelsoriano.com/wp-content/uploads/2017/11/files-in-doclib-300x200.png 300w" sizes="(max-width: 666px) 100vw, 666px" /></p>



<p>On the Document Libary settings, click &#8220;Open in Explorer&#8221;.</p>



<p><img decoding="async" width="750" height="416" class="alignnone size-full wp-image-6263" src="https://michaelsoriano.com/wp-content/uploads/2017/11/open-in-ie.png" alt="" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/open-in-ie.png 750w, https://michaelsoriano.com/wp-content/uploads/2017/11/open-in-ie-300x166.png 300w" sizes="(max-width: 750px) 100vw, 750px" /></p>



<p>This will now open, as if it was a directory in your local drive. Let&#8217;s open the &#8220;<strong>sp-forms.html</strong>&#8221; with a text editor such as Notepad++.</p>



<p><img decoding="async" width="626" height="416" class="alignnone size-full wp-image-6264" src="https://michaelsoriano.com/wp-content/uploads/2017/11/open-in-notepad.png" alt="" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/open-in-notepad.png 626w, https://michaelsoriano.com/wp-content/uploads/2017/11/open-in-notepad-300x199.png 300w" sizes="(max-width: 626px) 100vw, 626px" /></p>



<p>Edit the paths of the sp-forms.css and sp-forms.js to the directory that you added them to.</p>



<p>Then create a page in SharePoint, add a Content Editor Webpart:</p>



<p><img decoding="async" width="850" height="245" class="alignnone size-full wp-image-6261" src="https://michaelsoriano.com/wp-content/uploads/2017/11/add-cewp.png" alt="" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/add-cewp.png 850w, https://michaelsoriano.com/wp-content/uploads/2017/11/add-cewp-300x86.png 300w, https://michaelsoriano.com/wp-content/uploads/2017/11/add-cewp-768x221.png 768w" sizes="(max-width: 850px) 100vw, 850px" /><br></p>



<p>In the settings for that wepart, add the path to the HTML file in the document library.</p>



<p><img decoding="async" width="369" height="350" class="alignnone size-full wp-image-6233" src="https://michaelsoriano.com/wp-content/uploads/2017/11/map-to-html.png" alt="map to html" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/map-to-html.png 369w, https://michaelsoriano.com/wp-content/uploads/2017/11/map-to-html-300x285.png 300w" sizes="(max-width: 369px) 100vw, 369px" /></p>



<p>If it can&#8217;t find the list, you will see an error message like below:</p>



<p><img decoding="async" width="410" height="323" class="alignnone size-full wp-image-6228" src="https://michaelsoriano.com/wp-content/uploads/2017/11/error-message.png" alt="error message" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/error-message.png 410w, https://michaelsoriano.com/wp-content/uploads/2017/11/error-message-300x236.png 300w" sizes="(max-width: 410px) 100vw, 410px" /></p>



<p>That means that you should create the list, along with the columns that is described in the beginning of this tutorial.</p>
<p>The post <a href="https://michaelsoriano.com/sharepoint-forms-custom-html/">Create Custom HTML Forms for SharePoint with this jQuery Plugin</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/sharepoint-forms-custom-html/feed/</wfw:commentRss>
			<slash:comments>97</slash:comments>
		
		
			</item>
		<item>
		<title>Build a SharePoint Single-Page App using nothing but Front-End Code</title>
		<link>https://michaelsoriano.com/build-sharepoint-single-page-app-front-end-code/</link>
					<comments>https://michaelsoriano.com/build-sharepoint-single-page-app-front-end-code/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Wed, 15 Jun 2016 15:49:28 +0000</pubDate>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Handlebars]]></category>
		<category><![CDATA[REST]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=5501</guid>

					<description><![CDATA[<p>For this session, I would like to show you how to build a &#8220;mini&#8221; single page application in SharePoint 2013. A single page application that is ALL Front-end code (JavaScript, HTML and CSS); while using SP&#8217;s REST services. We&#8217;re also using Bootstrap for the responsiveness and tab interface, Handlebars for the templating, as well as [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/build-sharepoint-single-page-app-front-end-code/">Build a SharePoint Single-Page App using nothing but Front-End Code</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>For this session, I would like to show you how to build a &#8220;mini&#8221; single page application in SharePoint 2013. A single page application that is ALL Front-end code (JavaScript, HTML and CSS); while using SP&#8217;s <a href="https://msdn.microsoft.com/en-us/library/office/fp142380.aspx">REST services</a>. We&#8217;re also using <a href="http://getbootstrap.com/">Bootstrap</a> for the responsiveness and tab interface, <a href="http://handlebarsjs.com/">Handlebars</a> for the templating, as well as <a href="https://jquery.com/">jQuery</a> for everything else.</p>



<h5 class="wp-block-heading"><a id="user-content-note-that-this-will-require-the-following-files" class="anchor" href="https://github.com/michaelsoriano/sp-tabbed-containers#note-that-this-will-require-the-following-files" aria-hidden="true"></a>Note that this will require the following files:</h5>



<ul class="wp-block-list">
<li>jquery.min.js</li>



<li>bootstrap.min.js</li>



<li>handlebars.min.js</li>



<li>moment.min.js</li>



<li>editor.js</li>



<li>editor.css</li>



<li>bootstrap.min.css</li>



<li>font-awesome.min.css</li>
</ul>



<h5 class="wp-block-heading">The plugin already includes the above files via CDN.</h5>



<p class="btn"><a href="https://github.com/michaelsoriano/sp-tabbed-containers">View in Github</a></p>



<p>We are building &#8220;<em>Tab Containers</em>&#8220;. Basically, content that is shown in different tabs in a page. The entire CRUD interface also comes with it &#8211; so we&#8217;ll be able to add, edit and delete tab content and items, all in one page (without refreshing).</p>



<h3 class="wp-block-heading">Why is this Useful?</h3>



<p>Well there really is no way to achieve this in SharePoint. If you want to add Tabs inside an SP page, you would have to paste the whole code inside their editor. But updating this is quite cumbersome to most users.</p>



<p>This solution provides you with a nice interface to manage your tab content, while the data is stored in an SP list. The good thing about this is, you can use multiple apps and utilize just one list. So if you convert this into a webpart or an app &#8211; you simply need one list per site to make it work.</p>



<p>Ready to get started? Also, I&#8217;m only going to discuss the meat of the logic. You will need some basic JavaScript and SharePoint to follow and complete this tutorial.</p>



<h3 class="wp-block-heading">Create the List</h3>



<p>The data for our application will be stored in a custom list. The list will basically contain four columns: 1) <strong>Title</strong>: which is the default title field, 2) <strong>content</strong> which is a Rich Text type 3) <strong>tab-order</strong> a single line text value 4) <strong>webpart-id</strong> &#8211; this will be the identifier for our webpart (in case you want multiple webparts in the site).</p>



<p><img decoding="async" width="509" height="474" class="alignnone size-full wp-image-5634" src="https://michaelsoriano.com/wp-content/uploads/2016/04/sp-tabs7.jpg" alt="sp-tabs7" srcset="https://michaelsoriano.com/wp-content/uploads/2016/04/sp-tabs7.jpg 509w, https://michaelsoriano.com/wp-content/uploads/2016/04/sp-tabs7-300x279.jpg 300w" sizes="(max-width: 509px) 100vw, 509px" /></p>



<p>The title column will hold tab title, content is the contents of the tab, tab order is for ordering the tabs from left to right. You can go ahead and fill it out with dummy data for now, so we can go ahead and fetch the data for our front end. Note that that I have the list template also included in the Github page.</p>



<h3 class="wp-block-heading">Fetch the Items</h3>



<p>We are going to use a slight variation of the &#8220;<a href="https://toddmotto.com/mastering-the-module-pattern/">Revealing Module</a>&#8221; pattern to construct our code. This is especially useful when you are expecting your code to be reused multiple times in a page. In our case, users might want multiple of these web parts in a page, so a &#8220;modularized&#8221; approach is needed.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var SpTabs = function(){
   //ENTER REST OF CODE HERE
return {
    init : init,
    getContent : getContent
  }
}</code></pre>



<p>As you can see, we are returning two public functions from our &#8220;SpTabs&#8221; object. The &#8220;init()&#8221; method will make the object unique per instance, while the &#8220;getContent()&#8221; will fetch the items for our view. Let&#8217;s build our init() function right below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var init = function(obj){
    setListName(obj.listName);
    setWebPartId(obj.webPartId);
    setListItemEntityTypeFullName();
    checkPermissions();
}</code></pre>



<p>Inside our &#8220;init()&#8221;, we have some setters. It simply sets our module up for execution. The setter functions are pretty self explanatory &#8211; and you can simply investigate what each of them does in the source code. Let&#8217;s continue getting our items:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var getContent = function(obj){
    var endpoint = "/_api/web/lists/getbytitle('"+listName+"')/Items?";
    endpoint = _spPageContextInfo.webAbsoluteUrl + endpoint + '$orderby=tab_x002d_order asc';
    endpoint += "&amp;$filter=(webpart_x002d_id eq '"+webPartId+"')";
    var ajax = $.ajax({
      url: endpoint,
      method: "GET",
      headers: { "Accept": "application/json; odata=verbose" },
      success : function(data){
        items = data.d.results;
        buildTabsHtml();
        buildTabsContentHtml();
      },
      error : function(data){
        console.log(data);
      }
    });
    return ajax;
  }
</code></pre>



<p>This is the AJAX call that goes into our API to fetch our items. As you can see, we are returning the variable &#8220;ajax&#8221; from the getContent() function, in cases where we want to add additional stuff once the response is received. But the default behavior is inside the &#8220;success&#8221; method of jQuery&#8217;s $.ajax(). </p>



<p>Note the two methods <strong>buildTabsHtml()</strong> and <strong>buildTabsContentHtml()</strong>, and our results are in our global var &#8220;items&#8221;. So we&#8217;re ready to build some output.</p>



<h3 class="wp-block-heading">Output with Handlebars</h3>



<p>Let&#8217;s create our <a href="http://handlebarsjs.com/">Handlebars</a> templates so we can use it to produce our content. In case you haven&#8217;t used it, Handlebars is a minimal template language for JavaScript. It just makes life easier. Note that we have to include our handlebars source to make it work. Also, we are using <a href="http://getbootstrap.com/">Bootstrap </a>for our tab styles. So you have to include that in your source as well.</p>



<p>The code that will make this work is inside our two methods <strong>buildTabsHtml()</strong> and <strong>buildTabsContentHtml()</strong>. Let&#8217;s go ahead and build that now:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function buildTabsHtml(){
    var source = $("#tabs-navigation-template").html();
    var template = Handlebars.compile(source);
    $(getId() + '.tabs-navigation').html(template(items));
    //atach handlers
    $(getId()+'.tabs-navigation li a').on('click',function(){
      $(getId()+'.tabs-navigation li').removeClass('active');
      $(this).closest('li').addClass('active');
      var id = $(this).attr('data-id');
      $(getId()+'.tab-item').addClass('hidden');
      $(getId()+'div.tab-item[data-id="'+id+'"]').removeClass('hidden');
      if(id === 'addNew'){
        addNewForm();
      }
    })
  }
</code></pre>



<p>The above will output the content of our tabs. It also attaches the handlers to the tab navigation elements. Next up is the <strong>buildTabsContentHtml()</strong> method:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function buildTabsContentHtml(){
    var source = $("#tabs-content-template").html();
    var template = Handlebars.compile(source);
    Handlebars.registerPartial("tabForm", $("#tabs-content-form-template").html());
    $(getId() + '.tabs-content').html(template(items));
    $.each(items,function(i,item){
      $(getId()+'[data-id="'+item.Id+'"] .editable-content').Editor(EditorOptions);
      $(getId()+'[data-id="'+item.Id+'"] .Editor-editor').html(item.content);
    })
    $(getId()+'.save-changes').on('click',function(){
      var id =$(this).closest('.tab-item').attr('data-id');
      if(validateFields(id)){
        $(this).addClass('fetching').html('<i class="fa fa-refresh fa-spin"></i> Saving...');
        $(getId()+'.editmode').css({'opacity':'.4'});
        setTimeout(function(){
          var ajax = submitChanges(id);
          ajax.done(function(data, xhr){
              var ajax2 = getContent();
              ajax2.done(function(){
                $(getId()+'.tabs-navigation li a[data-id="'+id+'"]').trigger('click');
                addButton();
              });
          });
        },1000);
      }else{
        showErrorMessage(id);
      }
      return false;
    })
</code></pre>



<p>Now things got a bit hairy. First you&#8217;ll notice our handlebars compile &#8211; which is normal, but note the &#8220;registerPartial()&#8221; method. This means that we&#8217;re adding another handlebars template into our existing template. This is the form that handles our inline editing. I&#8217;m not going to post the code on here, instead you can see the #tabs-content-form-template from our <a href="https://github.com/michaelsoriano/sp-tabbed-containers/blob/master/sp-tabbed-containers.txt">text</a> file &#8211; which simply contains a few input forms for our app.</p>



<h3 class="wp-block-heading">Why use partials within templates?</h3>



<p>This is another powerful feature of handlebars. This allows for more re-usability and &#8220;modularity&#8221; for your applications. In other words, we write once and re-use multiple times. In our case, the form can be reused multiple times across our application &#8211; in &#8220;edit&#8221; and &#8220;new&#8221; mode. This will become evident as you write along.</p>



<p>We&#8217;re also using a lightweight WYSWG editor called &#8220;<a href="http://suyati.github.io/line-control">Line Control</a>&#8220;. Since we&#8217;re already using Bootstrap and FontAwesome, it just makes sense that we use a plugin that requires the same libraries. So this is what&#8217;s happening on lines 8-9 above: &#8220;.Editor(EditorOptions)&#8221;, where &#8220;<em>EditorOptions</em>&#8221; is declared on top of of our file as an array.</p>



<h3 class="wp-block-heading">Insert, Update and Delete</h3>



<p>Finally, we attach our &#8220;Save&#8221; and &#8220;Delete&#8221; buttons to do a couple of REST calls to our server when clicked. First our &#8220;Save&#8221; button is connected to our &#8220;<em>submitChanges</em>(id)&#8221; method (which takes care of both &#8220;edits&#8221; and &#8220;inserts&#8221;), while the next call is to &#8220;<em>getContent</em>()&#8221; &#8211; which is our main function to grab the tab items.</p>



<p>The &#8220;Delete&#8221; will also consist of two main REST calls, which is to delete and fetch the records. Our &#8220;<em>deleteRecord</em>()&#8221; function is shown below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function deleteRecord(tab){
    var ajax = $.ajax({
       url: tab.__metadata.uri,
       type: "POST",
       headers: {
           "Accept": "application/json;odata=verbose",
           "X-RequestDigest": $("#__REQUESTDIGEST").val(),
           "X-HTTP-Method": "DELETE",
           "If-Match": tab.__metadata.etag
       },
       success: function (data) {
          console.log('record has been deleted');
       },
       error: function (data) {
          console.log('there was a problem with deleting the record');
       }
   });
   return ajax;
  }</code></pre>



<p>While our &#8220;submitChanges()&#8221; method looks like so:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function submitChanges(id){
      var item = {
        "__metadata": { "type": ListItemEntityTypeFullName },
        "Title" :   $(getId()+'[data-id="'+id+'"] input[name="title"]').val(),
        "content" : $(getId()+'[data-id="'+id+'"] .Editor-editor').html(),
        "tab_x002d_order" : $(getId()+'[data-id="'+id+'"] input[name="tab-order"]').val()
      };
      if(id === 'addNew'){
        item.webpart_x002d_id = webPartId;
        var endpoint = "/_api/web/lists/getbytitle('" + listName + "')/items";
        ajax = $.ajax({
           url: _spPageContextInfo.webAbsoluteUrl + endpoint,
           type: "POST",
           contentType: "application/json;odata=verbose",
           data: JSON.stringify(item),
           headers: {
               "Accept": "application/json;odata=verbose",
               "X-RequestDigest": $("#__REQUESTDIGEST").val()
           },
           error: function (data) {
              console.log(data);
           }
       });
       return ajax;
      } //end addNew;
      var tabItem = findItem(id);
      ajax = $.ajax({
         url: tabItem.__metadata.uri,
         type: "POST",
         contentType: "application/json;odata=verbose",
         data: JSON.stringify(item),
         headers: {
             "Accept": "application/json;odata=verbose",
             "X-RequestDigest": $("#__REQUESTDIGEST").val(),
             "X-HTTP-Method": "MERGE",
             "If-Match": tabItem.__metadata.etag
         },
         error: function (data) {
            console.log(data);
         }
     });
     return ajax;
  }
</code></pre>



<p>Note that all of the REST calls all look similar, with a select few nodes that changes. First you&#8217;ll notice the &#8220;X-HTTP-Method&#8221; for edits is &#8220;MERGE&#8221; and &#8220;DELETE&#8221; for deleting. The rest are pretty much SharePoint REST API requirements &#8211; which you can find more on <a href="https://msdn.microsoft.com/en-us/library/office/jj860569.aspx">this page</a>. Our &#8220;item&#8221; object is also mapped to the names of the list columns that we have. Depending on your list &#8211; you may need to modify this area as well.</p>



<p>In our UI, note the placement of our buttons and our form:<br><img decoding="async" width="509" height="557" class="alignnone size-full wp-image-5632" src="https://michaelsoriano.com/wp-content/uploads/2016/04/sp-tabs5.jpg" alt="sp-tabs5" srcset="https://michaelsoriano.com/wp-content/uploads/2016/04/sp-tabs5.jpg 509w, https://michaelsoriano.com/wp-content/uploads/2016/04/sp-tabs5-274x300.jpg 274w" sizes="(max-width: 509px) 100vw, 509px" /><br>Lastly, you notice a couple of helper functions &#8220;getId()&#8221; and &#8220;findItem()&#8221;. The <strong>getId()</strong> simply returns our current div &#8211; with the &#8220;#&#8221; and a space as a string (or the CSS selector for the current div), while our <strong>findItem()</strong> loops through our global <strong>items</strong> object and returns the current item.</p>



<p>Moving forward, let&#8217;s look at a couple of important internal methods which includes our validation and error messaging mechanism.</p>



<h3 class="wp-block-heading">Form Validation</h3>



<p>Since we&#8217;re entering our data into our SharePoint lists through client side, we can implement a validation method using JavaScript as well. The cool thing about SP&#8217;s REST API has it&#8217;s own validation in the server side so all we have to worry about is the user experience.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function validateFields(id){
    errors = [];
    $('.error').remove();
    var title = $(getId()+'[data-id="'+id+'"] input[name="title"]');
    var content = $(getId()+'[data-id="'+id+'"] .Editor-editor');
    var tabOrder = $(getId()+'[data-id="'+id+'"] input[name="tab-order"]');
    if(title.val() == ''){
      var obj = {};
      obj.field = 'title';
      obj.message = 'Title cannot be empty'
      errors.push(obj);
    }
    if(content.html() == ''){
      var obj = {};
      obj.field = 'content';
      obj.message = 'Content cannot be empty'
      errors.push(obj);
    }
    if(tabOrder.val() == ''){
      var obj = {};
      obj.field = 'tab-order';
      obj.message = 'Tab order cannot be empty'
      errors.push(obj);
    }
    if(errors.length &gt; 0){
      return false;
    }
    return true;
  }
</code></pre>



<p>Our very simple validation code is above. Note that this happens every time that &#8220;submit&#8221; button is clicked. So it simply goes through the fields &#8211; check for empty and puts the errors in an array. I&#8217;m not checking for anything else like valid data etc &#8211; and feel free to add your own rules. Simply keep pushing the error messages into our array when invalid. Our messaging is handled in the code below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function showErrorMessage(id){
    $.each(errors,function(i,er){
      var field = '';
      if(er.field === 'content'){
        field = $(getId()+'[data-id="'+id+'"] .Editor-container');
      }else{
        field = $(getId()+'[data-id="'+id+'"] input[name="'+er.field+'"]');
      }</code></pre>



<p><em>[the code above has been truncated due to an error w syntax highlighter&#8230; sorry]</em></p>



<p>The following screenshot shows our validation code in action. Error messaging is placed underneath each label and at the same time. This way, users can see where they had made an error and fix. Remember to add your own rules as necessary.</p>



<p><br><img decoding="async" width="516" height="502" class="alignnone size-full wp-image-5764" src="https://michaelsoriano.com/wp-content/uploads/2016/05/tabs-validation.png" alt="tabs-validation" srcset="https://michaelsoriano.com/wp-content/uploads/2016/05/tabs-validation.png 516w, https://michaelsoriano.com/wp-content/uploads/2016/05/tabs-validation-300x292.png 300w" sizes="(max-width: 516px) 100vw, 516px" /></p>



<h3 class="wp-block-heading">Checking Permissions</h3>



<p>Finally, since we&#8217;re not using the regular SharePoint process in updating a page with tabs, we need to come up with our own. See, the entity we&#8217;re updating is not the current page &#8211; but a list. So we need to check if the current user has permission to edit the list &#8211; and give them access to our newly created UI.<br>I found this <a href="http://www.lifeonplanetgroove.com/checking-user-permissions-from-the-sharepoint-2013-rest-api/">great article</a> on how to effectively do this &#8211; since Microsoft&#8217;s documentation is a bit vague. </p>



<p>We&#8217;re using the &#8220;effectiveBasePermissions&#8221; REST endpoint along with SP.BasePermissions() class &#8211; which we need from SP.ClientContext object. Yes, it&#8217;s a bit of a mess so simply check the code below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function checkPermissions() {
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {
      var call = jQuery.ajax({
          url: _spPageContextInfo.webAbsoluteUrl +
              "/_api/Web/lists/getbytitle('"+listName+"')/effectiveBasePermissions",
          type: "GET",
          dataType: "json",
          headers: {
              Accept: "application/json;odata=verbose"
          }
      });
      call.done(function (data, textStatus, jqXHR) {
          var permissions = new SP.BasePermissions();
          permissions.initPropertiesFromJson(data.d.EffectiveBasePermissions);
          var permLevels = [];
          for(var permLevelName in SP.PermissionKind.prototype) {
              if (SP.PermissionKind.hasOwnProperty(permLevelName)) {
                  var permLevel = SP.PermissionKind.parse(permLevelName);
                  if(permissions.has(permLevel)){
                        permLevels.push(permLevelName);
                  }
              }
          }
          // console.log(permLevels);
          if($.inArray('editListItems',permLevels) != -1){
            userCanEdit = true;
            addButton();
          }else{
            console.log('You dont have "editListItems" permissions on '+ listName);
          }
      });  //end done
    });
  }
</code></pre>



<p>We&#8217;re still using jQuery&#8217;s ajax to get information, though it&#8217;s wrapped inside a &#8220;SP.SOD.executeFunc()&#8221; method &#8211; which is Microsoft&#8217;s way of loading and executing internal scripts. What we get back is an array we&#8217;re calling &#8220;permLevels&#8221; This array contains all the permissions a user has against our list. </p>



<p>We&#8217;re simply looking for the &#8220;editListItems&#8221; &#8211; and if found, we&#8217;re show the button and let the user edit.<br><img decoding="async" width="638" height="495" class="alignnone size-full wp-image-5767" src="https://michaelsoriano.com/wp-content/uploads/2016/05/tabs-45.jpg" alt="tabs-45" srcset="https://michaelsoriano.com/wp-content/uploads/2016/05/tabs-45.jpg 638w, https://michaelsoriano.com/wp-content/uploads/2016/05/tabs-45-300x233.jpg 300w" sizes="(max-width: 638px) 100vw, 638px" /></p>



<h3 class="wp-block-heading">Final Steps</h3>



<p>Our code is now complete. Note that there is not a single line of .NET code above &#8211; it&#8217;s all JavaScript, HTML and CSS. All server interactions are done through the REST API. This code can be applied whichever way you want to implement &#8211; may it be a custom web part, an app part or simply add the code to a Content Editor.</p>



<p>Remember to update the initialize settings like below: The important part is the &#8220;webPartId&#8221; and &#8220;listName&#8221; parameters &#8211; which connects the plugin to the data you need.</p>



<p><img decoding="async" width="432" height="330" class="alignnone size-full wp-image-5631" src="https://michaelsoriano.com/wp-content/uploads/2016/04/sp-tabs4.jpg" alt="sp-tabs4" srcset="https://michaelsoriano.com/wp-content/uploads/2016/04/sp-tabs4.jpg 432w, https://michaelsoriano.com/wp-content/uploads/2016/04/sp-tabs4-300x229.jpg 300w" sizes="(max-width: 432px) 100vw, 432px" /></p>



<p>Once that&#8217;s done, simply reload the page and you should see your SPA in action. Note that the code editor I used is very basic &#8211; so you might need to go to the list itself when updating content.</p>



<p><img decoding="async" width="581" height="597" class="alignnone size-full wp-image-5858" style="border: 1px solid #ebebeb;" src="https://michaelsoriano.com/wp-content/uploads/2016/06/sp-tabs2.gif" alt="sp-tabs2"></p>



<p>This editor was mostly designed for quick updates to your content.</p>



<p>Remember, the purpose of this article was really to expose you to the inner workings of REST and how to build a single page application right inside SharePoint with existing open technologies such as jQuery, Handlebars and Bootstrap. </p>



<p>Hope you enjoy this piece. Let me know your comments below.</p>
<p>The post <a href="https://michaelsoriano.com/build-sharepoint-single-page-app-front-end-code/">Build a SharePoint Single-Page App using nothing but Front-End Code</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/build-sharepoint-single-page-app-front-end-code/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>Build a Better Photo Gallery for SharePoint using REST and Handlebars</title>
		<link>https://michaelsoriano.com/better-photo-gallery-sharepoint-rest-and-handlebars/</link>
					<comments>https://michaelsoriano.com/better-photo-gallery-sharepoint-rest-and-handlebars/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Mon, 21 Mar 2016 01:01:35 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Handlebars]]></category>
		<category><![CDATA[REST]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=5473</guid>

					<description><![CDATA[<p>Working with SharePoint&#8217;s REST API is pretty cool. Lately, I&#8217;ve been writing plenty of applications where the entire CRUD is involved; all using SharePoint lists behind the scenes. Meaning, the entire front end is entirely up to me to build. This way, I can use different JavaScript libraries and frameworks when building these interfaces. Note [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/better-photo-gallery-sharepoint-rest-and-handlebars/">Build a Better Photo Gallery for SharePoint using REST and Handlebars</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Working with SharePoint&#8217;s REST API is pretty cool. Lately, I&#8217;ve been writing plenty of applications where the entire <a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> is involved; all using SharePoint lists behind the scenes. Meaning, the entire front end is entirely up to me to build. This way, I can use different JavaScript libraries and frameworks when building these interfaces.</p>



<h4 class="wp-block-heading">Note that this will require the following files:</h4>



<ul class="wp-block-list"><li>bootstrap.css</li><li>magnific-popup.css</li><li>jquery-1.12.0.min.js</li><li>jquery.magnific-popup.min.js</li></ul>



<p><strong>The plugin already includes the above files via CDN. The Plugin JavaScript and CSS is also included via RawGit &#8211; so changes may affect your working files.</strong></p>



<p class="btn"><a href="https://github.com/michaelsoriano/sp-photo-gallery">View in Github</a></p>



<p><br>Today, let&#8217;s look at something pretty simple. Let&#8217;s build a photo gallery using <a href="https://products.office.com/en-us/sharepoint/collaboration">SharePoint</a> Picture library as the backend, together with <a href="http://handlebarsjs.com/">Handlebars.js</a> &#8211; a good Javascript templating system. With this knowledge, you will gain good understanding on how to select items with SharePoint&#8217;s REST API, which I happen to have a <a href="https://michaelsoriano.com/understanding-sharepoint-rest-api-part-1-selecting-items/">post</a> on.</p>



<p><br><img decoding="async" width="750" height="500" class="alignnone size-full wp-image-5868" src="https://michaelsoriano.com/wp-content/uploads/2015/02/bspg2.jpg" alt="bspg2" srcset="https://michaelsoriano.com/wp-content/uploads/2015/02/bspg2.jpg 750w, https://michaelsoriano.com/wp-content/uploads/2015/02/bspg2-300x200.jpg 300w" sizes="(max-width: 750px) 100vw, 750px" /></p>



<p>Ready to get started? Roll up your sleeves and let&#8217;s write some code. Note that I will not go over the entire code base in this tutorial &#8211; just the meat of the logic.</p>



<h3 class="wp-block-heading">Setup the Gallery</h3>



<p>First we need to make sure we have a gallery to connect to. In SharePoint, you do this by going to &#8220;View All Site Content&#8221; and adding a new Picture Library. Note that for this demo I&#8217;m using SharePoint 2010 &#8211; I believe in newer versions you have to &#8220;<em>Add an App</em>&#8221; &gt; &#8220;<em>Photo Library</em>&#8220;.</p>



<p>Be sure to note the name of your library:<br><img decoding="async" width="660" height="469" class="alignnone size-full wp-image-5483" src="https://michaelsoriano.com/wp-content/uploads/2016/02/sp-photo-gallery-3.jpg" alt="sp-photo-gallery-3" srcset="https://michaelsoriano.com/wp-content/uploads/2016/02/sp-photo-gallery-3.jpg 660w, https://michaelsoriano.com/wp-content/uploads/2016/02/sp-photo-gallery-3-300x213.jpg 300w" sizes="(max-width: 660px) 100vw, 660px" /><br>Upload some images to your newly created library. Now we can continue and pull our images in the front end.</p>



<h3 class="wp-block-heading">The Javascript</h3>



<p>Create a Javasript file and name it sp-gallery.js. You can place it inside any SharePoint document library &#8211; and simply map to it using Windows Explorer so you can write to it just like you would as if it was a local file.</p>



<p>Let&#8217;s setup the wrapper for our gallery. We&#8217;re using the &#8220;<a href="https://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript">Revealing Module</a>&#8221; pattern so we can have methods that are public and private, as well as we keep our logic real tidy. We&#8217;re adding private variables inside our class so we can use it all over our code.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var gallery = function(list){
  var webUrl = _spPageContextInfo.webAbsoluteUrl;
  var listName = list;
  var limit = 20;
  var skip = 0;
  var total = 0;
}</code></pre>



<h6 class="wp-block-heading">Get the List Count</h6>



<p>Our first method is to grab the number of photos in our library. This is important so we can decide whether to show our &#8220;show more&#8221; button or not. Note the use our our &#8220;webUrl&#8221; and &#8220;listName&#8221; variables in our method. Add this code inside our gallery wrapper. This method is internal, so we create a function declaration:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function getListCount(webUrl,listName) {
    var url = webUrl + "/_vti_bin/listdata.svc/" + listName + '/$count';
    var ajax = $.ajax({
        url: url,
        method: "GET",
        headers: { "Accept": "application/json;odata=verbose,text/plain" },
        error: function (data) {
          console.log('error in fetching list count');
          console.log(data.responseJSON.error);
        }
    });
    return ajax;
}</code></pre>



<p>The above will return a &#8220;promise&#8221; object that we can use to manipulate later on. In the case above, it&#8217;s simply a number.</p>



<h3 class="wp-block-heading">Get the Gallery Items</h3>



<p>This method is the call to grab our list items. Again, we&#8217;re using jQuery&#8217;s &#8220;Ajax&#8221; method, returning a promise object.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function getListItems(webUrl,listName, itemId) {
    var url = webUrl + "/_vti_bin/listdata.svc/" + listName;
    if(itemId !== null){
      url += "(" + itemId + ")";
    }
    url += '?$top='+limit+'&amp;$skip='+skip;
    var ajax = $.ajax({
        url: url,
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        error: function (data) {
          console.log(data.responseJSON.error);
        }
    });
    return ajax;
  }</code></pre>



<h3 class="wp-block-heading">Compile with HandleBars</h3>



<p>This method is taking the data that is returned from our ajax promise above, and compiling it with handlbars. We haven&#8217;t built our HTML yet &#8211; which contains the actual handebars template. Note that this is a public function, so we&#8217;re creating the function as a &#8220;function expression&#8221;:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var buildGallery = function(data){
      var source   = $("#photogallery").html();
      var template = Handlebars.compile(source);
      $('.photo-gallery-wrap').append(template(data));
      $('.popup').magnificPopup({
          type: 'image',
          gallery:{
            preload: [0,5],
            enabled:true
          },
          removalDelay: 300,
          mainClass: 'mfp-fade'
      });
  }</code></pre>



<p>Also note that I&#8217;ve added a &#8220;popup&#8221; functionality which we&#8217;ve instantiated in the code above. We&#8217;re using <a href="http://dimsemenov.com/plugins/magnific-popup/">magnificpopup.js</a> for this awesome feature.</p>



<h3 class="wp-block-heading">The &#8220;Show More&#8221; button</h3>



<p>We&#8217;re only loading a certain subset of photos in our gallery. We will have a button in the bottom of our images that when clicked, will do another fetch to our list and add them below. Again, this is public, so it&#8217;s a &#8220;function expression&#8221;.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var showmore = function (){
      $('#showmore').addClass('fetching').html('Loading images...');
      skip = skip+limit;
      var ajax2 = getListItems(webUrl,listName, null);
      ajax2.done(function(data){
        buildGallery(data);
        $('#showmore').removeClass('fetching').html('Show More');
        if($('.thumbnail-wrap').length &gt;= total){
            $('#showmore').hide();
        }
      });
      return false;
  }</code></pre>



<p>This sort of acts like an &#8220;infinite scroll&#8221; functionality &#8211; but with a button. I&#8217;m not particularly fond of that automatic loading.</p>



<h3 class="wp-block-heading">Initializing the Gallery</h3>



<p>Now that our methods are in place, it is time to tie them all together and returning them so we can call them outside of our class. We do this by creating an &#8220;init&#8221; function.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var gallery = function(list){
//our private vars here...
var init = function(){
      var ajax1 = getListCount(webUrl,listName);
      var ajax2 = getListItems(webUrl,listName, null);
      ajax1.done(function(data){
        total = data;
        if(total &lt;= limit){
          $('#showmore').hide();
        }
      });
      ajax2.done(function(data){
        buildGallery(data);
      });
  }
//the rest of the methods here...
//below returns our public methods for use:
 return {
    init : init,
    showmore : showmore,
    buildGallery : buildGallery
  }</code></pre>



<p>Notice that we are only returning the public functions above. So we are keeping our variables and private functions inaccessible from the outside world. Let&#8217;s move on to our helpers:</p>



<h3 class="wp-block-heading">HandleBar Helpers</h3>



<p>These methods doesn&#8217;t have to be our gallery code. This can live outside, so it can be accessed by Handlebars. The code is namespaced using the Handlebars object. I&#8217;ll explain what the do below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">Handlebars.registerHelper('findGroup', function(data) {
    var remove = _spPageContextInfo.webServerRelativeUrl;
    var str = data.Path;
    return str.replace(remove+'/','');
});
Handlebars.registerHelper('imgSrc', function(data) {
    var url = _spPageContextInfo.siteAbsoluteUrl;
    url += data.Path;
    url += '/' + data.Name
    return url;
});
Handlebars.registerHelper('imgSrcThumb', function(data) {
    var thumb = data.Name;
    thumb = thumb.replace('.jpg', '_jpg.jpg');
    var url = _spPageContextInfo.siteAbsoluteUrl;
    url += data.Path;
    url += '/_t/' + thumb;
    return url;
});</code></pre>



<p>We will use a &#8220;<em>findGroup</em>&#8221; helper inside our templates so we can &#8220;group&#8221; our photos together. This is what our &#8220;<em>Magnificpopup</em>&#8221; plugin requires &#8211; so when you click &#8220;next&#8221; or &#8220;previous&#8221; &#8211; it knows which photo to show.</p>



<p>The &#8220;imgSrc&#8221; helper simply returns the source of the images, while the &#8220;imgSrcThumb&#8221; returns the thumbnail path. Note that this helper only supports jpegs at the moment.</p>



<h3 class="wp-block-heading">The CSS</h3>



<p>We are simply displaying the thumbnails in a grid fashion, so our styles are quite basic. I&#8217;m using this inside a Bootstrap wrapper, so you can see the &#8220;.col&#8221; classes in our HTML later. Create a file and name it sp-gallery.css and add the code below:</p>



<pre class="wp-block-code"><code lang="css" class="language-css">.photo-gallery-wrap {
  overflow: hidden;
  margin-right: -30px;
}
.thumbnail {
  display: inline-block;
  width: 100%;
  height: 100px;
  background-position: center center !important;
  text-indent: -9999px;
}
.thumbnailHidden {
  display:none;
}
.showMoreWrap {
  clear:both;
  display:block;
}
#showmore {
  color:#fff;
}
#showmore.fetching {
  background:#AAD3AA;
  border:#9AC39A;
}
.thumbnail-wrap {
  margin-bottom: 25px;
}
.thumbnail-wrap.col-lg-3 {
  padding-left:0;
  padding-right: 30px;
}
@media(max-width:387px){
  .thumbnail-wrap.col-lg-3 {
    padding-right: 15px;
  }
  .col-xxs-6 {
    width:50%;
  }
  #showmore {
    display:block;
  }
}
@media(max-width:240px){
  .col-xxxs-12 {
    width:100%;
  }
}
/* overlay at start */
.mfp-fade.mfp-bg {
  opacity: 0;
  -webkit-transition: all 0.15s ease-out;
  -moz-transition: all 0.15s ease-out;
  transition: all 0.15s ease-out;
}
/* overlay animate in */
.mfp-fade.mfp-bg.mfp-ready {
  opacity: 0.8;
}
/* overlay animate out */
.mfp-fade.mfp-bg.mfp-removing {
  opacity: 0;
}
/* content at start */
.mfp-fade.mfp-wrap .mfp-content {
  opacity: 0;
  -webkit-transition: all 0.15s ease-out;
  -moz-transition: all 0.15s ease-out;
  transition: all 0.15s ease-out;
}
/* content animate it */
.mfp-fade.mfp-wrap.mfp-ready .mfp-content {
  opacity: 1;
}
/* content animate out */
.mfp-fade.mfp-wrap.mfp-removing .mfp-content {
  opacity: 0;
}</code></pre>



<p>I&#8217;ve also added extra &#8220;col&#8221; classes for my own grid styles when the viewport is decreased. Also notice the .mfp classes are necessary for our magnific popup to work &#8220;magnificently&#8221;.</p>



<h3 class="wp-block-heading">The HTML</h3>



<p>Finally, this is the file that we add to any page of our SharePoint site. Create a text file &#8211; name it &#8220;sp-gallery.txt&#8221; and add the code below:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;script src="https://code.jquery.com/jquery-1.12.0.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.0.1/jquery.magnific-popup.min.js"&gt;&lt;/script&gt;
&lt;script src="ADD-YOUR-PATH-HERE/sp-gallery.js"&gt;&lt;/script&gt;
&lt;script&gt;
$(document).ready(function(){
  var photos = gallery('TestPhotoLib'); //change to your document library name
  photos.init();
  $('#showmore').on('click', photos.showmore);
})
&lt;/script&gt;
&lt;div class="photo-gallery-wrap"&gt;&lt;/div&gt;
&lt;div class="showMoreWrap"&gt;
&lt;a id="showmore" class="btn btn-sm btn-success" href="#"&gt;Show More&lt;/a&gt;&lt;/div&gt;</code></pre>



<p>&nbsp;<br>The above contains the references to the files we need.</p>



<p>We went ahead and create our gallery and pass in the name of our Photo Gallery above. We then initialize and add the &#8220;showmore&#8221; handler when our button is clicked.</p>



<p>Add our Handlebars template to the text file:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;script id="photogallery" type="text/x-handlebars-template"&gt;
{{#each d}}
&lt;div class="col-lg-3 col-md-3 col-sm-3 col-xs-4 col-xxs-6 col-xxxs-12 thumbnail-wrap"&gt;
  &lt;a href="{{imgSrc this}}" group="{{findGroup this}}" class="thumbnail popup" style="background:url('{{imgSrcThumb this}}');" &gt;
    {{Name}}
  &lt;/a&gt;
&lt;/div&gt;
{{/each}}
&lt;/script&gt;</code></pre>



<p>&nbsp;<br>The above template is what we need for our gallery to work. This code represents each tile that we will produce in our gallery.</p>



<p>Save this text file (along with the .js and .css) and add it to any SharePoint page. Add a Content Editor WebPart, and add a link to an external file &#8211; to our .txt file.</p>



<p><br><img decoding="async" width="418" height="290" class="alignnone size-full wp-image-5482" src="https://michaelsoriano.com/wp-content/uploads/2016/02/sp-photo-gallery-2.jpg" alt="sp-photo-gallery-2" srcset="https://michaelsoriano.com/wp-content/uploads/2016/02/sp-photo-gallery-2.jpg 418w, https://michaelsoriano.com/wp-content/uploads/2016/02/sp-photo-gallery-2-300x208.jpg 300w" sizes="(max-width: 418px) 100vw, 418px" /><br>I usually edit the webpart to &#8220;NOT&#8221; show the chrome.</p>



<h3 class="wp-block-heading">Final Result</h3>



<p>Save the page and if everything works well, you should see something like below:</p>



<p><img decoding="async" width="602" height="480" class="alignnone size-full wp-image-5869" src="https://michaelsoriano.com/wp-content/uploads/2015/02/bspg.gif" alt="bspg"><br></p>



<p>A simple photo gallery with popup and paging functionality. It surely looks better than the &#8220;out of the box&#8221; photo gallery that SP provides. Furthermore, you have complete ability to change the look as much as you want.</p>



<p>But the real value is the introductory lesson to working with SharePoint&#8217;s REST api. Be sure to stay tuned for more stuff like this. </p>



<p>Leave your comments below.</p>
<p>The post <a href="https://michaelsoriano.com/better-photo-gallery-sharepoint-rest-and-handlebars/">Build a Better Photo Gallery for SharePoint using REST and Handlebars</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/better-photo-gallery-sharepoint-rest-and-handlebars/feed/</wfw:commentRss>
			<slash:comments>47</slash:comments>
		
		
			</item>
		<item>
		<title>Understanding SharePoint&#8217;s REST and Search API Part 1 &#8211; Selecting Items</title>
		<link>https://michaelsoriano.com/understanding-sharepoint-rest-api-part-1-selecting-items/</link>
					<comments>https://michaelsoriano.com/understanding-sharepoint-rest-api-part-1-selecting-items/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Sat, 16 Jan 2016 19:44:12 +0000</pubDate>
				<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Search API]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=5349</guid>

					<description><![CDATA[<p>SharePoint 2013 has a REST API that exposes plenty of information about users, lists and document libraries. For front end developers, this is a gold mine. A gold mine because of two things: 1) SharePoint&#8217;s out of the box UI is pretty bad, and 2) SharePoint&#8217;s out of the box UI is pretty bad. Update [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/understanding-sharepoint-rest-api-part-1-selecting-items/">Understanding SharePoint&#8217;s REST and Search API Part 1 &#8211; Selecting Items</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>SharePoint 2013 has a REST API that exposes plenty of information about users, lists and document libraries. For front end developers, this is a gold mine. A gold mine because of two things: 1) SharePoint&#8217;s out of the box UI is pretty bad, and 2) SharePoint&#8217;s out of the box UI is pretty bad.</p>
<div style="padding: 15px 20px; background: #fcffe6; border-radius: 4px; border: 1px solid #e5e9cd; margin-top: 20px; margin-bottom: 25px;"><strong>Update 3/2017:</strong> I&#8217;ve added Search API to this post as well. Continue reading below.</div>
<p>So plenty of room for improvement here. Now we can basically recreate SharePoint&#8217;s front end: entire new CRUD interfaces and such. And the base of it all &#8211; is its REST API.<br />
It is important to recognize that SharePoint REST API is using <a href="http://www.odata.org/">OData</a>, which is a widely used convention when in comes to RESTful web services. You can learn more about the syntax from their website.<br />
For this post I would like to cover <strong>Selecting Items</strong>.<br />
Note that I prefer using jQuery&#8217;s <strong>$.ajax</strong> method. So all my calls will look like below:</p>
<pre>$.ajax({
   url: url, //THE ENDPOINT
   method: "GET",
   headers: { "Accept": "application/json; odata=verbose" },
   success: function (data) {
        console.log(data.d.results) //RESULTS HERE!!
   }
});
</pre>
<p>All we&#8217;re doing is replacing the <strong>url</strong><br />
<strong>A special note on SP 2010 users:</strong> the querystring section of the examples below may be the same. The only difference I&#8217;ve seen is the endpoint part of the url. SP 2010 has below:</p>
<pre class="">"/_vti_bin/listdata.svc/" + querystring</pre>
<h3>1) Selecting all items, all columns</h3>
<p>The simplest way to grab list items is to get everything. This is done by using the endpoint below. Simply change the &#8220;list&#8221; value to your own:</p>
<pre class="">/_api/web/lists/getbytitle('listname')/Items?$select=*</pre>
<p>Again, this will select &#8220;almost&#8221; all columns that are available to the list.  Note that I said &#8220;almost&#8221;, because SharePoint&#8217;s REST API doesn&#8217;t really bring back everything. Things such as author information and values of lookups have to be queried differently (more on this below).</p>
<h3>2) Selecting all items, custom columns</h3>
<p>)I find it good practice to only grab the columns that I need. This makes the payload as lean as possible.</p>
<pre class="">/_api/web/lists/getbytitle('listname')/Items?$select=ID,Title</pre>
<p>This also makes it easier to find things because each Javascript object only contain the columns &#8220;ID&#8221; and &#8220;Title&#8221;. What I don&#8217;t understand is why &#8220;ID&#8221; and &#8220;Id&#8221; is present &#8211; maybe a configuration error with the list. But nevertheless, the result is more manageable:<br />
<img decoding="async" class="alignnone size-full wp-image-5453" src="https://michaelsoriano.com/wp-content/uploads/2016/01/rest-select-1.jpg" alt="rest-select-1" width="449" height="181" srcset="https://michaelsoriano.com/wp-content/uploads/2016/01/rest-select-1.jpg 449w, https://michaelsoriano.com/wp-content/uploads/2016/01/rest-select-1-300x121.jpg 300w" sizes="(max-width: 449px) 100vw, 449px" /></p>
<h3>3) Getting the total items in a list</h3>
<p>To get the number of items in a list, append the &#8220;ItemCount&#8221; in the end of your query sting.</p>
<pre class="">/_api/web/lists/getbytitle('listName')/ItemCount
</pre>
<p>I know that you can simply do a &#8220;.length&#8221; from the a regular call which brings you all of your results, but the above is useful for filtered results, or when paging. The output looks like below:<br />
<img decoding="async" class="alignnone size-full wp-image-5470" src="https://michaelsoriano.com/wp-content/uploads/2016/01/item-count1.jpg" alt="item-count1" width="340" height="125" srcset="https://michaelsoriano.com/wp-content/uploads/2016/01/item-count1.jpg 340w, https://michaelsoriano.com/wp-content/uploads/2016/01/item-count1-300x110.jpg 300w" sizes="(max-width: 340px) 100vw, 340px" /></p>
<h3>4) Retrieving specific list items</h3>
<p>Now this endpoint will only get the list item with the ID of &#8220;4&#8221; (I&#8217;ve removed the &#8220;_spPageContextInfo.webAbsoluteUrl&#8221; component for easier read&#8230;</p>
<pre class="">/_api/web/lists/getbytitle('listname')/items(4)</pre>
<p>A more powerful solution is using the <strong>$filter</strong> key. Not that this option allows you to get items with more flexibility. Check out this example which grabs items with the title equals to &#8220;example 1&#8221;. Note the use of single quotes! Almost all values in SharePoint REST use single quotes!</p>
<pre class="">/_api/web/lists/getbytitle('listname')/Items?$select=Title&amp;$filter=Title eq 'example 1'</pre>
<h3>5) Multiple $filter keys + values</h3>
<p>To get items that have Title that is equal to multiple values, use the endpoint below:</p>
<pre class="">/_api/web/lists/getbytitle('listname')/Items?$select=Title&amp;$filter=((Title eq 'example 1') or (Title eq 'example 2'))</pre>
<p>Notice that I used parenthesis to enclose the multiple parameters. This is completely optional &#8211; but improves readability.<br />
In the case of multiple &#8220;ANDs&#8221; and &#8220;ORs&#8221;, for a stricter and finer result set, you need to use the parenthesis to enclose filter sets. This example below:</p>
<pre class="">/_api/web/lists/getbytitle('ListName')/Items?$&amp;$select=Title&amp;$filter=((ContentType eq 'Operating Policy') or (ContentType eq 'Procedure')) and (Subject eq 'Safety')</pre>
<p>You see how we&#8217;re grabbing items with &#8220;ContentType&#8221; equaling to &#8220;Operating Policy&#8221; OR &#8220;Procedure&#8221; AND &#8220;Subject&#8221; equaling to &#8220;Safety&#8221;.</p>
<h3>6) Using &#8220;startswith()&#8221; and &#8220;substringof()&#8221; functions with $filter</h3>
<p>At times you need a more powerful filter in SharePoint REST API. See &#8220;eq&#8221; will only retrieve exact matches. If you want to get everything that starts with &#8220;test&#8221;, you use the &#8220;<strong>startswith()</strong>&#8221; function:</p>
<pre class="lang:default decode:true">/_api/web/lists/getbytitle('ListName')/Items?$filter=((startswith(column,'test')))</pre>
<p>Note that the &#8220;column&#8221; is the first parameter, then the value! This is a mistake that I&#8217;ve done several times because the <a href="https://social.technet.microsoft.com/wiki/contents/articles/35796.sharepoint-2013-using-rest-api-for-selecting-filtering-sorting-and-pagination-in-sharepoint-list.aspx#Filtering_items">documentation</a> is pretty weak.<br />
Now, if you want to get items that &#8220;contains&#8221; specific characters, you use the &#8220;<strong>substringof()</strong>&#8221; function.</p>
<pre class="lang:default decode:true">/_api/web/lists/getbytitle('ListName')/Items?$filter=((substringof('test',column)))</pre>
<p>Unlike startswith(), the substring() takes the &#8220;value&#8221; first, then the &#8220;column&#8221;. Again, note the difference between the two.</p>
<h3>7) Limiting your results</h3>
<p>The <strong>$top</strong> parameter basically limits your items to a specified number. The syntax is below:</p>
<pre class="">/_api/web/lists/getbytitle('listname')/Items?$select=Title&amp;$top=10</pre>
<p>This is also useful for creating paging systems &#8211; in combination with an offset option (below).</p>
<h3>8) Offsetting results (for paging)</h3>
<p>So you know how to limit your results, and you know how to get the total items. All you need is to offset your results. You do this with the &#8220;$skip&#8221; parameter.</p>
<pre class="">/_api/web/lists/getbytitle('listname')/Items?$top='10'&amp;$skip='20'
</pre>
<p>Again, note the use of single quotes. The above will get a set of 10 items, starting from the 20th in the list. Combined with the total, you can create your own paging mechanism.<br />
<strong>Update 8/10/2016:</strong> I just found out that the <a href="http://sharepoint.stackexchange.com/questions/126565/issue-with-skip-in-rest-api">$skip parameter doesn&#8217;t work</a> with list items. There is a property in the REST response that you can use &#8211; for paging. This is known as the &#8220;___next&#8221;. I will do another tutorial strictly on this subject &#8211; so stay tuned.</p>
<h3>9) Getting the Author Information</h3>
<p>You have to specify that using the &#8220;$expand&#8221; key. Also an additional parameter to the &#8220;$select&#8221; key is needed. For example, to grab the Id and the name of the author, simply append to your query:</p>
<pre class="">/_api/web/lists/getbytitle('listname')/Items?$select=Author/Title,Comment&amp;$expand=Author/Title</pre>
<p>The above will return the author information in it&#8217;s own node called &#8220;Author&#8221;.<br />
<img decoding="async" class="alignnone size-full wp-image-5455" src="https://michaelsoriano.com/wp-content/uploads/2016/01/rest-select-2.jpg" alt="rest-select-2" width="396" height="155" srcset="https://michaelsoriano.com/wp-content/uploads/2016/01/rest-select-2.jpg 396w, https://michaelsoriano.com/wp-content/uploads/2016/01/rest-select-2-300x117.jpg 300w" sizes="(max-width: 396px) 100vw, 396px" /></p>
<h3>10) Document Libraries</h3>
<p>SharePoint REST API supports querying document libraries. Remember, doc libs are also lists and for the most part, are handled through the same endpoint.</p>
<pre class="">/_api/web/lists/getbytitle('Document Library Name')/Items?$select=Title,FileLeafRef,EncodedAbsThumbnailUrl,EncodedAbsUrl</pre>
<p>The example above returns information about your file such as the name, full url and the internal &#8220;Title&#8221;:<br />
<img decoding="async" class="alignnone size-full wp-image-5417" src="https://michaelsoriano.com/wp-content/uploads/2015/12/rest-select2.gif" alt="rest-select2" width="531" height="160" /><br />
For instances where you want to know the &#8220;type&#8221; of document library it is (example Picture Library vs Document Library), use:</p>
<pre class="">/_api/web/lists/getbytitle('Document Library Name')/BaseTemplate</pre>
<p>Although some information regarding document libraries require an entirely new endpoint. This includes file paths, subfolders, thumbnails and such.</p>
<pre class="">/_api/web/GetFolderByServerRelativeUrl('"Folder Name"')/Files</pre>
<p>The above contains an entire new set of information regarding your library.</p>
<h3>11) Getting Current User information:</h3>
<p>At times you want to grab the current user&#8217;s information. Use the endpoint below:</p>
<pre class="">/_api/SP.UserProfiles.PeopleManager/GetMyProperties</pre>
<p>I&#8217;ve also used the more current endpoint below:</p>
<pre class="lang:js decode:true">/_api/web/currentUser</pre>
<p>Again, there may be additional information that is not returned by the above, such as user groups (below) which requires a different endpoint.</p>
<h3>12) Getting Current User Groups</h3>
<p>For some reason, this information is separate from getting the current user information described above. But in order to get the current user groups, you need to pass the ID:</p>
<pre class="lang:js decode:true">/_api/web/GetUserById('"+ userId +"')/Groups</pre>
<p>So you need to get the &#8220;userId&#8221; first, then do the above ajax call. Something like below:</p>
<pre class="lang:default decode:true">function getCurrentUser(){
   var ajax = $.ajax({
       url:   _spPageContextInfo.siteAbsoluteUrl + "/_api/web/currentUser",
       method: "GET",
       headers: { "Accept": "application/json; odata=verbose" },
       error: function (data) {
           console.log(data);
          }
        });
       return ajax;
}
function getUserGroups (userId) {
   var ajax = $.ajax  ({
        url:  _spPageContextInfo.siteAbsoluteUrl + "/_api/web/GetUserById('"   + userId + "')/Groups",
        method: "GET",
           headers: { "Accept": "application/json; odata=verbose" }
     });
    return ajax;
    }
getCurrentUser().done(function(userId){
   getUserGroups(userId.d.Id).done(function(groups){
       console.log(groups.d.results);
   });
});</pre>
<p>Above is an example of a &#8220;promise&#8221;. For more on that, read my <a href="https://michaelsoriano.com/working-with-jquerys-ajax-promises-and-deferred-objects/">Working with jQuery’s AJAX, Promises and Deferred objects.<br />
</a></p>
<h3>13) Retrieving&#8221;Choice Column&#8221; values</h3>
<p>There are times when you want to build an application that requires you to drill down to a choice column, and grab it&#8217;s values. A &#8220;choice column&#8221; in SharePoint is a type of column where you add values for users to choose from.<br />
<img decoding="async" class="alignnone size-full wp-image-6088" src="https://michaelsoriano.com/wp-content/uploads/2016/01/Capture.png" alt="Choice column" width="487" height="190" srcset="https://michaelsoriano.com/wp-content/uploads/2016/01/Capture.png 487w, https://michaelsoriano.com/wp-content/uploads/2016/01/Capture-300x117.png 300w" sizes="(max-width: 487px) 100vw, 487px" /><br />
You retrieve the values by doing an ajax call to the SharePoint REST API endpoint, specifying the column name you want. Below is an example:</p>
<pre class="lang:js decode:true">/_api/web/lists/GetByTitle('LISTNAME')/fields?$filter=EntityPropertyName eq 'Subjects'</pre>
<p>The above will query the choice column &#8220;Subjects&#8221; from the list &#8220;LISTNAME&#8221;.</p>
<h6>**The __metadata object</h6>
<p>You will notice that each result will have this <strong>__metadata</strong> object tied to it.<br />
<img decoding="async" class="alignnone size-full wp-image-5458" src="https://michaelsoriano.com/wp-content/uploads/2016/01/3rd-screenshot-rest.gif" alt="3rd-screenshot-rest" width="492" height="265" /><br />
This contains important material that will help you later in update and delete operations. I&#8217;ll cover that in the next chapter.</p>
<h2><span style="text-decoration: underline;">Bonus: SharePoint Search API</span></h2>
<p>If you have Search features turned on, you will be able to do powerful queries against any of your content inside your SharePoint farm. SharePoint search crawls through your material such as Word documents, Excel, PDF, Lists, Webpages &#8211; anything that you&#8217;ve configured to be searchable &#8211; you can query against in the <strong>SharePoint Search API</strong>.<br />
Your application will go up an extra level &#8211; simply by integrating this capability. Here are a few common Search API calls &#8211; for selecting / querying items:</p>
<h3>1) A Standard Search</h3>
<p>Doing a regular is as simple as passing your search term to the endpoint below:</p>
<pre class="lang:js decode:true">/_api/search/query?querytext='"+ TERM +"'</pre>
<p>The tricky part is parsing the results.<br />
<img decoding="async" class="alignnone wp-image-6090 size-full" style="padding: 20px; border: 1px solid #ebebeb;" src="https://michaelsoriano.com/wp-content/uploads/2016/01/Capture-1.png" alt="Search API result" width="537" height="640" srcset="https://michaelsoriano.com/wp-content/uploads/2016/01/Capture-1.png 537w, https://michaelsoriano.com/wp-content/uploads/2016/01/Capture-1-252x300.png 252w" sizes="(max-width: 537px) 100vw, 537px" /><br />
Are you ready for this? The results are buried under: <strong>data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results</strong></p>
<div>The &#8220;results&#8221; property of &#8220;Rows&#8221; is an array of objects. This contains the data you want to display.</div>
<h3>2) Selecting specific Properties</h3>
<p>At times, you want the payload to remain small. The SharePoint Search API supports selecting only the properties you need. Below is a good way to achieve this:</p>
<pre class="lang:js decode:true">/_api/search/query?querytext='"+ TERM +"'&amp;selectproperties='Title,Path,FileExtension,IsContainer'</pre>
<p>Adding a &#8220;selectproperties&#8221; querystring along with a comma separated properties that we need will do the trick. Again, note the use of single-quotes.</p>
<h3>3) Offsetting Results (for paging)</h3>
<p>For instances where you want to return the set of rows that starts from a specific number:</p>
<pre class="lang:js decode:true">/_api/search/query?querytext='"+ TERM +"'&amp;startrow=10</pre>
<p>Adding the &#8220;startrow&#8221; querystring will do it. Note that SharePoint Search API has a complex algorithm of sorting and returning results. Therefore, the total and the actual values are approximates.</p>
<h3>4) Limiting Results</h3>
<p>You don&#8217;t want to return everything! You simply want to limit your search:</p>
<pre class="lang:js decode:true">/_api/search/query?querytext='"+ TERM +"'&amp;rowlimit=25</pre>
<p>The &#8220;rowlimit&#8221; querystring is your friend.</p>
<h3>5) Only Results from a Specific List or Document Library</h3>
<p>This one you will need the list Id. You can grab the list Id by going to your list / library, and clicking on &#8220;List Settings&#8221; or &#8220;Library Settings&#8221;. Once there, go to the URL and grab the value after &#8220;List=&#8221;. Note that this value is url encoded &#8211; with single quotes. So remove the leading &#8220;%7B&#8221;, and the trailing &#8220;%7D&#8221;. What you&#8217;re left with is the List Id.</p>
<pre class="lang:js decode:true">/_api/search/query?querytext='"+ TERM +"'&amp;sourceid='YOUR-LIST-ID'</pre>
<p>Remember to wrap your list id in single quotes. This query will only return items from the specific list that you&#8217;ve specified.</p>
<h3>6) Get People Results</h3>
<p>For this one, it&#8217;s exacly the same as above.</p>
<pre class="lang:js decode:true">/_api/search/query?querytext='"+ TERM +"'&amp;sourceid='b09a7990-05ea-4af9-81ef-edfab16c4e31'</pre>
<p>Simply replace the list id with this: &#8220;<strong>b09a7990-05ea-4af9-81ef-edfab16c4e31</strong>&#8220;. Yes it seems like it&#8217;s the same for everybody.</p>
<h3>7) Getting Best Bets</h3>
<p>&#8220;Best Bets&#8221; is SharePoint&#8217;s &#8220;elevated results&#8221;. These get pushed to the top of the result set, for specific queries. Note that these items are not included in the regular results &#8211; which means that it is not to be included in paging and filters and such.</p>
<pre class="lang:js decode:true">/_api/search/query?querytext='"+ TERM +"'&amp;processbestbets=true&amp;enablequeryrules=true</pre>
<p>The resultset you need to parse is in this property: <strong>data.d.query.SecondaryQueryResults.results[0].SpecialTermResults.Results.results</strong><br />
Haha! Ugly eh? Inside &#8220;results&#8221; is an array of objects you need. Note that the properties of each object may not be as complete as the primary results.</p>
<h3>8) Filtering Results</h3>
<p>Sometimes you don&#8217;t want the whole resultset to comeback. This is where filtering comes in. <strong>SharePoint Search API</strong> has &#8220;refinement filters&#8221; which does the job.</p>
<pre class="lang:default decode:true">/_api/search/query?querytext='TERM'&amp;refinementfilters='(FIELD:string("FILTERTERM", mode="phrase")'</pre>
<p>The above will search for &#8220;TERM&#8221;, filtered with the &#8220;FILTERTERM&#8221;  in the field called &#8220;FIELD&#8221;.</p>
<h3>9) Filtering Results in Multiple Fields</h3>
<p>So now we need to filter by many fields. Yes it&#8217;s possible, and we still use &#8220;refinement filters&#8221; in the Search API.</p>
<pre class="lang:default decode:true ">/_api/search/query?querytext='TERM'&amp;refinementfilters='and(COL1:string("COL1TERM", mode="phrase"),COL2:string("COL2TERM", mode="phrase"))'</pre>
<p>Just like the single filter, but instead we add &#8220;and&#8221; in the beginning (you can also use &#8220;or&#8221;), plus separating the columns and terms with a comma.</p>
<h3>10) Sorting Results</h3>
<p>At times, the sorting of SharePoint&#8217;s Search API is not what you&#8217;re looking for. Well we can sort it.</p>
<pre class="lang:default decode:true ">/_api/search/query?querytext='TERM'&amp;sortlist='LastName:ascending,FirstName:ascending'</pre>
<p>The example above shows the results being sorted by &#8220;LastName&#8221;, ascending first, then &#8220;FirstName&#8221; etc.</p>
<h3>Conclusion</h3>
<p>As I&#8217;ve mentioned, SharePoint&#8217;s REST AND SEARCH API has some very powerful features. And with OData&#8217;s standard&#8217;s, you can create quite advanced queries. I will try to keep this article updated with more <strong>Select</strong> related queries, but for now I have to go. Stay tuned for the next part.</p>
<p>The post <a href="https://michaelsoriano.com/understanding-sharepoint-rest-api-part-1-selecting-items/">Understanding SharePoint&#8217;s REST and Search API Part 1 &#8211; Selecting Items</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/understanding-sharepoint-rest-api-part-1-selecting-items/feed/</wfw:commentRss>
			<slash:comments>35</slash:comments>
		
		
			</item>
		<item>
		<title>How to make a SharePoint List work with Bootstrap &#8211; using SPServices and jQuery</title>
		<link>https://michaelsoriano.com/sharepoint-bootstrap-using-spservices-and-jquery/</link>
					<comments>https://michaelsoriano.com/sharepoint-bootstrap-using-spservices-and-jquery/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Fri, 17 Jul 2015 16:23:46 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[SOAP]]></category>
		<category><![CDATA[SPServices]]></category>
		<guid isPermaLink="false">http://fearlessflyer.com/?p=4446</guid>

					<description><![CDATA[<p>For those of you who have worked with SharePoint in the past, particularly with lists, CEWPs (Content Editor Web Part) and front end code, then you probably know that these lists do not work well in mobile. The markup is just too messy &#8211; invalid tags, divs inside spans, inline Javascripts, inline styles and even [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/sharepoint-bootstrap-using-spservices-and-jquery/">How to make a SharePoint List work with Bootstrap &#8211; using SPServices and jQuery</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>For those of you who have worked with SharePoint in the past, particularly with lists, CEWPs (<a href="https://support.office.com/en-ca/article/Content-Editor-Web-Part-c1350ff6-934c-4c2e-8e53-1ec3b548a0dc">Content Editor Web Part</a>) and front end code, then you probably know that these lists do not work well in mobile. The markup is just too messy &#8211; invalid tags, divs inside spans, inline Javascripts, inline styles and even tables! So it&#8217;s no surprise that making SharePoint work with Bootstrap is not an easy task.</p>
<h5>Note that this plugin will require the following files:</h5>
<ul>
<li>jquery.min.js</li>
<li>jquery.SPServices-2014.02.min.js</li>
<li>bootstrap.min.css</li>
</ul>
<p>In this post, I will show you how to use a Javascript plugin that I&#8217;ve written to basically recreate the markup of these SP lists so it works with Bootstrap / Mobile. It also has extra functionality like paging, filters, expand/collapse and other options. By the time we&#8217;re done, your list will look real good in desktop, tablet and mobile view:<br />
<a href="https://github.com/michaelsoriano/sp-bootstrap-list-viewer">View in Github</a></p>
<h3>How to use the Plugin:</h3>
<p>Note that I&#8217;ve only tested this with SharePoint 2013. You may need administrator rights to your website, as well as you should know how to work with custom lists and document libraries and such.<br />
After you have downloaded the files, open the &#8220;sp-bootstrap-list-viewer.html&#8221; in you text editor. This is where you will add the plugin information.<br />
You have to change the CHANGE-TO-YOUR-PATH in the JavaScript and CSS inclusion &#8211; to your downloaded path.<br />
Then, you add 2 things: the list name, the &#8220;Answer&#8221; column. The rest of the options are optional such as the &#8220;filterBy&#8221; and &#8220;rowLimit&#8221;. The table below will show you want the rest of the options do.<br />
<img decoding="async" class="alignnone size-full" src="https://michaelsoriano.com/wp-content/uploads/2015/07/sp-list3.jpg" alt="sp-list1" width="412" height="358" /><br />
Once you have edited the html file, upload it to a location in your SharePoint site, typically a document library. You will need to copy the location of the file.<br />
<img decoding="async" class="alignnone size-full" src="https://michaelsoriano.com/wp-content/uploads/2015/07/sp-list2.jpg" alt="sp-list1" width="412" height="358" /><br />
Let&#8217;s go ahead and add a CEWP into your SharePoint page. in the &#8220;Content Link&#8221; input, add the location of the html file you&#8217;ve just uploaded.<br />
<img decoding="async" class="alignnone size-full" src="https://michaelsoriano.com/wp-content/uploads/2015/07/sp-list1.jpg" alt="sp-list1" width="412" height="358" /><br />
Click &#8220;OK&#8221; and if everything is configured correctly, you should see the plugin do its thing:<br />
<img decoding="async" class="alignnone size-full wp-image-4447 noborder" src="https://michaelsoriano.com/wp-content/uploads/2015/07/sp-bootstrap-list-viewer.gif" alt="sp-bootstrap-list-viewer" width="787" height="520" /><br />
The table below contains the options for the plugin and an explanation of what they&#8217;re for:</p>
<table class="table table-bordered">
<thead>
<tr>
<th>Option name</th>
<th>Default Value</th>
<th>Required?</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">instance</th>
<td>Random Value</td>
<td>Yes</td>
<td>Used as the &#8220;Id&#8221; of your plugin</td>
</tr>
<tr>
<th scope="row">listName</th>
<td>none</td>
<td>Yes</td>
<td>Name of the SP list</td>
</tr>
<tr>
<th scope="row">question</th>
<td>Title</td>
<td>Yes</td>
<td>Title of the row</td>
</tr>
<tr>
<th scope="row">answer</th>
<td>none</td>
<td>Yes</td>
<td>Body of the row</td>
</tr>
<tr>
<th scope="row">filterBy</th>
<td>none</td>
<td>No</td>
<td>Category column to filter rows</td>
</tr>
<tr>
<th scope="row">rowLimit</th>
<td>5</td>
<td>No</td>
<td>Number of rows to show</td>
</tr>
</tbody>
</table>
<p>One thing to remember. If you plan to use the plugin multiple times in a page, you need to change the &#8220;instance&#8221; value to a random number prefixed with alphanumeric characters. You also need to make this the &#8220;Object&#8221; name of your html (where it says var <strong>spBL233565656</strong> = new spBootstrapList &#8230;). This will make the instances of your plugin unique in every page and will not clash with each other.</p>
<h3>Under the hood:</h3>
<p>For those of you who want to know more about how the plugin works, I will show you some of it&#8217;s main functionality. Note that this was originally built for a FAQ list for SharePoint, hence the FAQ names such as &#8220;Question&#8221; and &#8220;Answer&#8221;. Though the plugin will work with any kind of SP list.</p>
<h6>Requirements</h6>
<p>We will need some help with Mark Anderson&#8217;s <a href="https://github.com/sympmarc/SPServices">SPServices</a> &#8211; a jQuery plugin that basically does the web service calls for us. This allows us to work with the lists&#8217; data and convert it to our desired markup. Of course we will need <a href="http://getbootstrap.com/">Bootstrap </a>&#8211; which will take care of the responsive and overall styles, as well as <a href="https://jquery.com/">jQuery</a> for DOM manipulation.<br />
Notice the required scripts and styles. You can link to them externally or download them to a document library in SharePoint. Our constructor spBootstrapList() calls our Javascript class, passing along our required arguments. Again, the variable name &#8220;spBL233565656&#8221; and the value for &#8220;instance&#8221; has to be identical. This is for using it multiple of these in a single page.<br />
So going into the Javascript plugin: <strong>sp-bootstrap-list-viewer.js</strong>, you will see that on first load there&#8217;s a public method that gets called to set things up &#8220;init()&#8221;. This makes the initial call to the plugin &#8220;SPServices&#8221;. As I&#8217;ve mentioned, the plugin does the AJAX call to the SharePoint web service. It uses SOAP as its protocol so the request / response will be in XML format. Our init() method also checks for valid fields:</p>
<pre class="">var init = function(){
var ajax = methods.callSPServices(_settings.rowLimit, true);
$(ajax.responseXML).SPFilterNode("z:row").each(function(e) {
    var errors = Array();
    if(typeof $(this).attr('ows_' + _settings.question) == 'undefined'){
        errors.push("Invalid field name for Question: " + _settings.question);
    }
    if(typeof $(this).attr('ows_' + _settings.answer) == 'undefined'){
        errors.push("Invalid field name for Answer: " + _settings.answer);
    }
    if(_settings.filterBy !== '') {
        if(typeof $(this).attr('ows_' + _settings.filterBy) == 'undefined'){
            errors.push("Invalid field name for FilterBy: " + _settings.filterBy);
        }
    }
    _errors = errors;
    methods.parseResponse($(this));
});
</pre>
<p>Then we parse our response and we fill our internal object &#8220;_faqs&#8221;: Notice the SharePoint internal list names that start with &#8220;ows_&#8221; &#8211; these are how it comes out of the <a href="https://developers.google.com/doubleclick-publishers/docs/soap_xml">SOAP response</a>. We parse it to our own object with more meaningful keys and it&#8217;s values:</p>
<pre>parseResponse : function(resp){
    var record = {};
    record.question = resp.attr('ows_' + _settings.question);
    record.answer = resp.attr('ows_' + _settings.answer);
    record.created = resp.attr('ows_' + 'Created');
    if(_settings.filterBy !== ''){
        record.filterBy = resp.attr('ows_' + _settings.filterBy);
    }
    _faqs.push(record);
},
</pre>
<p>By the way, in order for us to make public methods from within our plugin is that we assign it to the &#8220;this&#8221; keyword. This way it becomes accessible from the outside. Here is an example of all the public methods of our plugin:</p>
<pre>this.paginate = paginate;
this.filter = filter;
this.showHideFilters = showHideFilters;
this.clearFilter = clearFilter;
this.showHideAnswer = showHideAnswer;
</pre>
<p>Continuing with our process, note that we need the &#8220;_faq&#8221; array to be filled for our next method to fire. This method is called <strong>methods.buildFaqs()</strong>, So we built another object called &#8220;methods&#8221; and inside this is a series of functions. This will be our &#8220;internal&#8221; methods.<br />
If you look at the buildFaqs() method, the code looks like below:</p>
<pre class="">buildFaqs : function(){
  var output = '';
  for(var i=0; i&lt;_faqs.length; i++){
    var hr = (i != (_faqs.length-1)) ? '</pre>
<p><em>[code above has been truncated &#8211; due to syntax highlighting error]</em><br />
So you see, we have our SharePoint list data in our array, and we build the HTML from it.</p>
<h6>Pagination</h6>
<p>Our pagination logic is quite interesting. We use the Bootstrap pagination HTML, and for each page, we need to do a <a href="http://www.w3schools.com/ajax/">AJAX</a> call in order to get the next page ID. This is how SharePoint determines where to offset the record when a query is made by using &#8220;<a href="https://social.msdn.microsoft.com/Forums/en-US/02663336-3185-498a-904f-86845106b624/getlistitems-with-jquery-using-listitemcollectionpositionnext-as-a-query-option?forum=sharepointdevelopmentprevious">ListItemCollectionPositionNext</a>&#8221; as a parameter.</p>
<pre>var buildPagination = function(){
  if(_errors.length &gt; 0) {
      $('#'+ _settings.instance+' .spBLPagerContainer').html('');
      console.log('Exiting buildPagination()');
      return false;
  }
  methods.getTotal(); //inside here we build filters
  if(parseInt(_totalRecords) &gt; parseInt(_settings.rowLimit)) { //yes paginate
      var pages = Math.ceil(_totalRecords / _settings.rowLimit);
      var positions = Array('');
      for (var i=0; i &lt; (pages - 1); i++) { //builds the values required 'ListItemCollectionPositionNext'
          var pos = '';
          if(i == 0){ //skips first to not pass pos
              positions.push(methods.getNextPos(pos));
          }else{
              var offset = i;
              positions.push(methods.getNextPos(positions[offset]));
          }
      }
  // console.log(positions);
  methods.buildPagination(positions);
  }else{ // no need to paginate
      $('#'+ _settings.instance+' .spBLPagerContainer').html('');
  }
}
</pre>
<p>We then proceed to build the actual markup with our internal method: methods.buildPagination():</p>
<pre class="">buildPagination : function(items){
  if(_firstLoad == false){
      $('#'+ _settings.instance+' .spBLPagerContainer').html(pager);
  }
  _positions = items;
  var pager = '</pre>
<p>&nbsp;<br />
<em>[code above has been truncated &#8211; due to syntax highlighting error]</em><br />
Each button has an inline &#8220;onclick&#8221; that calls our public &#8220;paginate()&#8221; method. Each of them also has the attribute &#8220;data-position&#8221; which holds the offset &#8220;ID&#8221; that we talked about:</p>
<pre>var paginate = function(clicked){
  if($(clicked).parents('li').hasClass('active') || $(clicked).parents('li').hasClass('disabled')){
      return false;
  }
  $('#'+ _settings.instance+' .pagination li').removeClass('active');
  var pos = $(clicked).attr('data-position') != '' ? $(clicked).attr('data-position') : '';
  if($(clicked).hasClass('NextButton')){
      $('#'+ _settings.instance+' a[data-position="'+pos+'"]').not('.NextButton').parents('li').addClass('active');
  }else if($(clicked).hasClass('PrevBtn')){
      $('#'+ _settings.instance+' a[data-position="'+pos+'"]').not('.PrevBtn').parents('li').addClass('active');
  }else{
      $(clicked).parents('li').addClass('active');
  }
  methods.updateNextPrevBtns(pos);
  methods.clearFaqs();
  var options = {
      CAMLViewFields: methods.fieldsToRead(true),
      CAMLQuery: methods.query(),
      CAMLRowLimit : _settings.rowLimit,
      CAMLQueryOptions: ""
  }
  var ajax = $().SPServices(methods.mergeSPCommon(options));
  $(ajax.responseXML).SPFilterNode("z:row").each(function(e) {
      methods.parseResponse($(this));
  });
  methods.buildFaqs();
}
</pre>
<p>You noticed too from the code above that we use SPServices on each click. That&#8217;s because we are only grabbing a predefined set of records &#8211; which is the limit that we pass into our plugin.</p>
<h6>Filters</h6>
<p>So the plugin supports filtering. This means that you can choose a field from your list and make that a &#8220;filter&#8221; column.<br />
First, assuming you&#8217;ve selected a valid field, we have to build it. Take a look at the code below:</p>
<pre>getFilterByValues : function(resp){
  var filterList = Array();
  var filterListUnique = Array();
  $(resp.responseXML).SPFilterNode("z:row").each(function(e) {
      var filterValue = $(this).attr('ows_' + _settings.filterBy);
          if(typeof filterValue !== 'undefined'){ //only add to array if theres a value
              filterList.push(filterValue);
          }
  });
  $.each(filterList,function(i,el){ //get rid of duplicates
      if($.inArray(el, filterListUnique) === -1){
          filterListUnique.push(el);
      }
  });
  _filterByListUnique = filterListUnique;
  _filterByList = filterList;
}
</pre>
<p>The above simply grabs the data. And since there are duplicate entries &#8211; we will have to make them unique and fill up our &#8220;_filterByListUnique&#8221; array. This is next:</p>
<pre class="">buildFilters : function(){
  var count = 0;
  var out = '';
  out +=</pre>
<p><em>[code above has been truncated &#8211; due to syntax highlighting error]</em><br />
The above builds out the checkboxes we need for our filtering capabilities. Now when each item is clicked, it triggers our filter() method:</p>
<pre>var filter = function(clicked){
  _firstLoad = false;
  _filterByValues = [];
  $('#'+ _settings.instance+'-filtersArray :checkbox:checked').each(function(e){
      _filterByValues.push($(this).val());
  })
  methods.filter();
}
</pre>
<p>Which actually calls our internal methods.filter() method:</p>
<pre>filter : function(){
  $('#'+ _settings.instance+'-filtersArray input').attr('disabled', 'disabled');
  $('#'+ _settings.instance+' .clearFilter').attr('disabled', 'disabled');
  methods.clearFaqs();
  var ajax = methods.callSPServices(_settings.rowLimit, true);
  $(ajax.responseXML).SPFilterNode("z:row").each(function(e) {
      methods.parseResponse($(this));
  });
  setTimeout(function(){
      methods.buildFaqs();
      buildPagination();
      $('#'+ _settings.instance+'-filtersArray input').removeAttr('disabled');
      $('#'+ _settings.instance+' .clearFilter').removeAttr('disabled');
  },10);
  if(_filterByValues.length &gt; 0){
      $('#'+ _settings.instance + ' .clearFilter').show();
  }else{
      $('#'+ _settings.instance + ' .clearFilter').hide();
  }
}
</pre>
<p>A lot going on here. You see that we make a new AJAX call through SPServices, passing our filter value. We parse the response, rebuild our items through &#8220;methods.buildFaqs()&#8221; and rebuild our pagination through buildPagination().<br />
There&#8217;s much more logic in the plugin such as the creating the <a href="https://msdn.microsoft.com/en-us/library/dd588092%28v=office.11%29.aspx">CAML</a> queries &#8211; but I decided not to go through them. If you&#8217;re well versed with .NET and SharePoint &#8211; you will be able to decipher these easy.</p>
<h3>Console Debugging</h3>
<p>Once you have the code in place &#8211; save and refresh your page. If by any reason some of the options are passed incorrectly, error handling is added and will be displayed in the HTML. You also need to turn on the console for more messages of what&#8217;s going on. I&#8217;ve added a couple of helpers that will get you information about your list such as getAllColumns(). This will display all of the fields that belong to the list you&#8217;re working with. Simply use the instance name + getAllColumns().</p>
<h3>Conclusion</h3>
<p>As you can see, we can make SharePoint internal lists work responsively. We may have to redo the markup entirely &#8211; but there are web services in place to grab the data. Thanks to open source code such as SPServices, jQuery and Bootstrap &#8211; our task becomes somewhat easier.<br />
Feel free to comment below.</p>
<p>The post <a href="https://michaelsoriano.com/sharepoint-bootstrap-using-spservices-and-jquery/">How to make a SharePoint List work with Bootstrap &#8211; using SPServices and jQuery</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/sharepoint-bootstrap-using-spservices-and-jquery/feed/</wfw:commentRss>
			<slash:comments>56</slash:comments>
		
		
			</item>
	</channel>
</rss>
