Tag: Development

  • Developing ReactJS Single Page Apps for SharePoint

    reactonsharepointLast year, I decided that I wanted to learn different ways to create web applications.  The two major candidates were Angular 1.x and ReactJS.  I went through some courses on Pluralsight and other training sites for both.  After “playing” around with both, I can honestly say that I prefer ReactJS over Angular.  Angular 2.0 looks promising, but I think some of the same reasons I choose React over Angular still exist:

    1. Angular supplements HTML with its own attributes and puts javascript in HTML.  React is straight Javascript.
    2. You have to learn a whole framework with Angular.  With React, I can choose my own ecosystem.
    3. One thing I read, is that because React is just javascript, it teaches you to be a better JavaScript programmer.
    4. React is focused on doing one thing and being the best at it.  It makes UI’s fast!  The virtual DOM just makes sense to me.
    5. Data flow in React is one way.  It flows down from the top and state is passed back up.  That makes sense to me.

    I’ve been developing React apps on NodeJS but I’m a SharePoint Developer.  I kept wondering if I could write Single Page Apps (SPA) for SharePoint.

    Basically, my requirements were:

    1. Write a ReactJS app that would compile down to a static JavaScript file that I could embed in a Content Editor Web Part.
    2. Use SharePoint’s REST interfaces to access the SharePoint objects.
    3. Since this would be hosted on SharePoint, I didn’t need to worry about cross-domain authentication.
    4. Use React Router to control app routing.
    5. Create a workflow that would allow me to easily develop and deploy these apps to SharePoint.

    With the recent guidance from Microsoft about the SharePoint Framework, I thought this was the perfect time to attempt to write a React app on SharePoint.

    After a lot of research, I found a couple of things.

    There is a project called ReactJS.NET that makes using React with .NET easier.  It focuses on the .NET MVC pattern.  I looked at that, created some demos but it didn’t fit my requirements.  I didn’t want to have to deploy compiled C# code to a SharePoint server.

    I decided to start rolling my own solution.  I chose

    • ReactJS
    • NodeJS
    • Babel (to transpile JSX)
    • npm (to load the node packages and run scripts
    • Webpack to bundle them into static files

    I was trying to put this all together when someone recommended that I check out the team at Facebook Incubator’s create-react-app bootstrapper.  After looking through the demos. Installing it myself and creating some quick (albeit small) apps and getting them to run on SharePoint, I think I have found my solution.

    A couple of challenges.

    1.  How do I develop on NodeJS without connecting to the SharePoint REST interfaces?
    2. How do I deploy the created app to SharePoint.

    The answer to the first question was to create a “dummy” REST interface for development.  I created the lists that I needed in SharePoint and then used Postman to call the REST interfaces and grab the data that was returned.  I copied that data object into my React App as the data source and then created an API module that would use the local data instead of calling SharePoint.  Since we can request a JSON object from SharePoint using the Accept header, it was easy to recreate the API necessary using array methods.  Once the app was developed using my dummy API, I substituted my real API that actually called the SharePoint REST endpoints.

    The second question posed more of a problem.  I planned to put my app on a web part page by referencing it in a content editor web part.  For years I have been storing custom code in the Site Assets library.  You could also create a CDN to host your app code.  Either way, your development workflow needs to be able to copy the static files from your production build, to SharePoint.  My original solution was to upload them via the web interface.  This worked but it was too cumbersome.  My next solution was to map a drive to Site Assets folder in SharePoint.  This works some of the time, but this also is cumbersome.  I recently read about an npm module called spsave.  I’m going to try to work it into my workflow.  This should allow me to automatically deploy my files to SharePoint when I run the build command.

    I put together a presentation about my work to get React to work in SharePoint.  It’s still a work in progress.  I delivered the presentation at SharePoint Saturday – Kansas City on October 1 and then again in Minneapolis for SharePoint Saturday – Twin Cities.  My slides are linked below but the best thing to do would be to look at the code of the Contacts app I created for the presentation.  It’s a simple app but demostrates the use of a dummy API to develop with.  The github link to the code is below also.

    I plan on continuing to improve my demo and adding to it.  I think I’m going to add some tests and I still need to add a delete function.  If you are interested, go ahead and star my repository.  If you find an error in the code, or a better way of doing something – I’d love to hear about it!  Remember, I’m still learning so be kind!

    ReactJs SPA’s on SharePoint

    https://github.com/dipetersen/ReactOnSharePoint

    spstc2016-reactjs-on-sharepoint

     

  • A(nother) Business Case for Twitter

    I can’t see why some companies continue to block Twitter access to their employees.  Especially developers.  For me, Twitter has been an invaluable resource.  A wealth of 140 character wisdom.  An constant supply of what is new in the SharePoint (or insert your favorite topic here) world.

    This example just happened to me yesterday.  I am working for a client that wants me to write a SharePoint 2010 workflow using K2’s Blackpearl.  Believe me, I am excited about using Blackpearl but it is a learning curve and I want to be productive.   Normally, I would just fire up Visual Studio and start writing a workflow.  K2 promises that Blackpearl can write complex workflows without code.  I wanted to see if I could figure it out on my own.  I read through the “My first workflow” instructions and thought I understood what I needed to do.  I started working through my own requirements when I got stumpted.  I knew what I wanted to do, I just couldn’t figure out how to tell Blackpearl to do it!

    Finally, I sent out a Tweet asking this simple question:

    I received a reply asking for my contact information and later last night – I received a detailed email from Holly at K2 telling me how I could accomplish this.  I searched Google, Bing without any hint on how to do this.  It didn’t help that I wouldn’t have understood what I was reading anyway.  Holly’s instructions were clear and easy to understand.  We’ve exchanged a couple of emails and she has suggested ways I could fulfill my whole requirement.  I am going to try this but I was so pleased that I wanted to get this post out here so that other companies would think twice about allowing their developers to use tools like Twitter.

  • Removing OPTIONS with jQuery

    Here’s a usability solution that was necessitated by my desire to present a logical, workable solution to my end-user.  I’m still learning jQuery so my solution may not be the most elegant – but it works. I welcome any improvements!

    The Setup

    I have a SharePoint site that is displaying the results of an SQL stored procedure.  I’m using Quest Web Parts for SharePoint – qSIListView part which is part of their fine System Integration web parts package.  The great thing about these web parts is that I can create a stored procedure on a database and then use the Filter capabilities of the qSIListView to supply the stored procedure with the parameter values.  It’s a pretty slick solution and very easy to configure.  My problem  is that when you use the filter fields as the Parameter input fields, only the “Equals” operator has any meaning.  I can select “Begins with” or “Contains” but it will only just pass the parameter value and not the operator.  That means that my End User will be presented with a lot of false options.  To avoid the confusion, I would like to present the user with one operator – “Equals”, or in the case where I’m trying to do some wild card matching in SQL, I would remove all but “Contains”.  You get my point.  The problem is that the Web Parts do not have the ability to filter out the operator selections.  I’ve submitted this change idea to Quest for future versions but in the mean time, I needed to find a solution.  My solution was to use jQuery.

    Click to enlarge.

    Solution

    There are many posts out on the web about using jQuery to manipulate the SharePoint interface.  One of the best sites for jQuery on SharePoint can be found on EndUserSharePoint.com.  The solution I am talking about today can be used in any web environment, including SharePoint.  Essentially, my short script removes all <option> elements from all select boxes that match a certain text value.  This effectively narrows the choices presented to the User to only the valid choices, Exclude from search and Equals.

    To do this, I placed a Content Editor Web Part (CEWP) onto my page and pasted my script in it.  In the script, I use jQuery to select all <OPTION> elements of the page and remove them if they contain any of the invalid choices.   The script is pretty straight forward.  I have jQuery stored in a script library on my SharePoint site.  This library provides read-access to all users on the site.  It is also a common place to store all of my scripts.  A good post on creating a script library can be found on here.

    Once I load the document, I have search for all matching <OPTION> elements and remove them.


    <script src="http://mysharepointdomain.com/scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
    <script type="text/javascript">
    $(document).ready(function(){
    $("option").remove(":contains('Does not equal')");
    $("option").remove(":contains('Contains')");
    $("option").remove(":contains('Starts with')");
    $("option").remove(":contains('Ends with')");
    $("option").remove(":contains('Is empty')");
    $("option").remove(":contains('Is not empty')");
    });
    </script>

    That’s it!  The end result looks like this.

    Click to enlarge.

    As I said earlier, this is a pretty simple solution to a problem that I was having.  Now, every time I use filter fields to supply parameter values, I can be assured that I have presented my User with valid options.

    I welcome any feedback!

  • Default Quick Launch Heading Paths

    Every so often, I come across sites that have the default Heading entries on the Quick Launch deleted.  I decided to write them down here in case I ever needed to put them back.  It’s also handy to be able to navigate to the All Items link in a site with no Quick Launch.  This is really for my reference but I hope this helps someone else out!

    Default Quick Launch Heading Paths

    View All Site Content
    /[web url]/_layouts/viewlsts.aspx

    Documents
    /[web url]/_layouts/viewlsts.aspx?BaseType=1

    Lists
    /[web url]/_layouts/viewlsts.aspx?BaseType=0

    Discussions
    /[web url]/_layouts/viewlsts.aspx?BaseType=0&ListTemplate=108

    Sites
    /[web url]/_layouts/viewlsts.aspx?ShowSites=1

    People and Groups
    /[web url]/_layouts/people.aspx

    Recycle Bin

    /[web url]/_layouts/recyclebin.aspx

    ******  UPDATED for 2010 ************

    Pictures

    /[web url]/_layouts/viewlsts.aspx?BaseType=1&ListTemplate=109

  • XSL:split-string function

    One of the reasons I like developing for SharePoint is that I get to work with many different technologies and platforms.  When I am designing a custom list for (display, edit or new), There are times where I may have a delimited string in a field that I want to display differently on the screen.  Since the forms are all XSL style sheets, it is helpful to have a few XSL templates to process the data.

    I wrote this XSL template so I could wrap some HTML around any element in a delimited list.  This is specifically geared towards XSL 1.0.  In XSL 2.0, I would most likely use tokenize.  I’m not an expert at XSL so if anyone has any suggestions that would improve this template, please leave comments.

    <xsl:template name="split-string">
    <xsl:param name="list" />
    <xsl:param name="delimiter" />
    <xsl:param name="id" />
    <xsl:if test="normalize-space($list)">
    <xsl:variable name="newlist">
    <xsl:choose>
    <xsl:when test="contains($list, $delimiter)">
    <xsl:value-of select="normalize-space($list)" />
    </xsl:when>
    <xsl:otherwise>
    <xsl:value-of select="concat(normalize-space($list), $delimiter)"/>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:variable>
    
    <xsl:variable name="first" select="substring-before($newlist, $delimiter)" />
    <xsl:variable name="remaining" select="substring-after($newlist, $delimiter)" />
    <!-- This is where you need to put the display code -->
    <a>
    <xsl:attribute name="href">./Attachments/<xsl:value-of select="$id" />/<xsl:value-of select="$first" /></xsl:attribute>
    <xsl:attribute name="target">_blank</xsl:attribute>
    <img src="~/_layouts/images/doclink.gif" width="16" height="16" alt="" border="0" />
    <xsl:value-of select="$first" />
    </a>
    <!--  end display code -->
    <xsl:if test="$remaining">
    <!-- I put a little display code here also -->
    <br />
    <!-- end display code -->
    <xsl:call-template name="split-string">
    <xsl:with-param name="list" select="$remaining" />
    <xsl:with-param name="delimiter">
    <xsl:value-of select="$delimiter"/>
    </xsl:with-param>
    <xsl:with-param name="id"><xsl:value-of select="$id" /></xsl:with-param>
    </xsl:call-template>
    </xsl:if>
    </xsl:if>
    </xsl:template>
    

    You can add or remove variables depending on what you need. In the above example code, I had a semi-colon list of email attachment file names that were attached to the list. I wanted to create a ‘clickable’ link to each file, which is why I needed the ID field. Normally, you wouldn’t need the ID field.

    This is how I called the template in my XSL:

    <xsl:call-template name="split-string">
    <xsl:with-param name="list"><xsl:value-of select="@EmailAttachmentNames" /></xsl:with-param>
    <xsl:with-param name="delimiter">;</xsl:with-param>
    <xsl:with-param name="id"><xsl:value-of select="@ID" /></xsl:with-param>
    </xsl:call-template>
  • Easy Check If An SPWeb/SPList Exist

    I write a lot of code using the SharePoint object model.  Often times, I want to check to see if a particular Web exists in a Site Collection or a List exists in a Web.  I used to write methods that enumerated through the collection to see if they existed or I wrapped a Try-Catch block around the code in case the object didn’t exist.

    Recently I came across a code snippet that made checking for the existence of a web or list easy.  I can’t remember where I found it so I’ll thank the nameless person who originally wrote the code.  I’m only capturing it here for my own reference and possibly help someone else.

    
            static bool ListExists(SPWeb web, string listName)
            {
                return web.Lists.Cast().Any(list => string.Equals(list.Title, listName));
            }
    
    
            static bool WebExists(SPSite site, string webName)
            {
                return site.AllWebs.Cast().Any(web => string.Equals(web.Name, webName));
            }
    
    
  • Determining SQL Requirements for SharePoint

    Joel Oleson has a good post about determining your SQL server requirements in your SharePoint implementation.  A good resource for planning.

    10 Key Questions Determining SharePoint SQL Server Count

  • Another example of how JQuery can help your site!

    I like this post because it illustrates how JQuery can make your UI code more efficient. Look at the code examples in this post. What once took 6 lines of code only takes one using JQuery. Of course, you have the overhead of loading the JQuery framework – but if you are doing a lot of client-side manipulation of the user interface then look to how JQuery can help you be more efficient.

    Low impact text changing in SharePoint with jQuery