My Take Away from SharePoint Saturday New York 

Tags

,

This past weekend (Saturday July 25, to be specific) I attended the SharePoint Saturday New York conference. I’m not a SharePoint developer and my role has nothing to do with Sharepoint, so I must be out of my mind for wanting to get up at 4AM on a Saturday and drive into the middle of Times Square at the peak of summer. The effort however was well worth it as I left there feeling energized and inspired to continue to create (side) projects that run against this platform.

SharePoint Saturday events, if you are not familiar, are free events organized by enthusiastic volunteers and made possible by generous sponsors.  We get to hear and interact with individuals that are at the top of their fields of expertise and understand first hand why they deserve the credentials they have been awarded (MVP, etc). In my prior role as a Project Manager, I developed several client-side solution that leveraged SharePoint within the company. As I moved on from that role, I never rally gave up the platform, as to this day I still have side projects that are developed against it and, from time to time, provide freelance development consulting services.

I have always developed SharePoint client side solutions.   To me, SharePoint is simply my data store (API) and host for the solution. For a long time there were not many out there that were building solutions this way.  I can remember a few years back when I would look at the agenda for these types of conferences and all I would see were sessions on how to create server based solutions using managed code.  But this is not the case now a days. A large percentage of the sessions focused on how to create solutions using client side technologies like HTML5, CSS AND JavaScript, and most surprising, they explored alternatives to Microsoft’s Add-In model, which has never won me over.

The sessions I attended were:

  • “Love in the Time of Javascript: Useful Patterns for Client-Side Code in SharePoint” – Jason Specland (@jayspectech, slides )
  • “JavaScript Libraries for Office 365 Developer” – Tim Ferro (@timferro, slides)
  • “Developing Applidation for SharePoint with Modern Web Development” – Scot Hillier (@ScotHillier, slides)
  • “Building Applications with the Office 365 Unified API” – Rich Ross (@rich_ross)
  • “Building SharePoint Single Page Applications using AngularJS” – Steve Pietrek (@spietrek, slides)

Of these, the sessions by Tim Ferro and Steve Pietrek were the ones that most resonated with me and the approaches I use to develop for SharePoint. Don’t get me wrong; the other sessions were good (ex. I heard probably the best explanation of how oAuth2 works by Scot Hillier), but both of these guys do most of the work client side and outside of the Add-In model.  Spietrek’s session was the closest in style to the way I develop – right down to the toolset and deployment approaches.  They also showed a few techniques that I was not familiar with and will be looking more into (ex. run SPA in localhost and access normal SharePoint APIs – nice! or Registering JavaScript on all pages in Office 365 from the browser).

I also was inspired by Rich Ross’s session on the O365 unified API. Although he had Visual Studio open most of the time and working with C# code (you know: backend stuff… that I have never touched), the capabilities of the new unified Office 365 APIs will enable an entire new set of apps that can integrate with the office products.  There is great potential here and ideas were racing through my mind on the drive home.

As SharePoint development continues to shift to client side, I was surprised to not see more speakers advocate the use of Asynchronous Module Definition (AMD) or commonJS patterns. After all, most of the attendees where C# and .NET developers whom will be making the transition, and introducing them to a mechanism that allows them to modularize their solutions probably make more sense to them given their backgrounds.  Personally, I think that if they are going to be transitioning starting now, they should develop their solution using JavaScript version 6 (ES6) and utilize a transpiler to run that code in today’s browsers.  ES6 is the start of the real evolution of the JavaScript language and learning it has a greater value (IMO) than try to learn Angular or just about any other framework out there…

Overall, the event was great and I can’t believe I have missed a few of these in the last two years. It inspired me, motivated me and in a way, validated that the way I have been building stuff, ever since SharePoint 2007, is actually not so “anti-pattern”. If you want to listen to extremely smart and energized individuals talk about great subjects, I suggest attending these whenever they are available in your area.

My First Yeoman Generator: sharepoint-spa – Easily Setup New SharePoint Web Single Page Applications

Tags

, , , ,

I have used Yeoman from time to time and it really is a nice tool if you can find the right generator. Yeoman, if you are not familiar with it, is a scaffolding utility that can help setup just about any type of project.  For example: want to create a jQuery plugin? Just use the official jQuery generator and it will setup the entire structured for you, ready with testing framework and Grunt build configuration. There are generators for just about any type of project. If you kick off different projects on a regular basis, its worth looking into Yeoman and how it can support you in starting a new project.

I normally did this by maintaining my own set of folders that contained the setup I liked for different project types.  This works, but it still requires some tedious manual changes every time I copy a folder to start a new project – things like:

  1. Change App/Library name across several files
  2. Add/Remove dependencies as needed
  3. Adjust build steps
  4. etc.

Yeoman, however, can do all this after prompting you for a few values, and it comes setup to take advantage of npm and bower, which makes it ideal for setting up browser based projects.  Wanting this type of flexibility, I took my setup for creating SharePoint Single Page Applications (SPA) and converted that to a generator – now found here: github.com/purtuga/generator-sharepoint-spa.

Usage

First, you need to obviously have yeoman installed:


npm install -g yo bower grunt-cli gulp

Now, let’s install the generator so that yeoman can use it:


npm install -g generator-sharepoint-spa

Ok. Now we’re all setup to create our first SharePoint SPA project based on this generator. Lets create a new folder and then execute yeoman inside that folder.


mkdir mySpApp

cd mySpApp

yo sharepoint-spa

The generator will ask a few questions, including weather a few libraries should be included as part of the setup:

generator-sharepoint-spa

When the interview process completes, Yeoman will proceed to setup the directory and file structure for the app, and then run both npm install and bower install, leaving your directory ready to go.

The App Structure

The structure that is created looks like the following:

generator-sharepoint-spa-app-dir

app Folder:

This is where your your application runtime code live. The folder is setup with a scripts and styles folder where your JavaScript code and CSS style sheets should live. The vendor folder is created by bower.js to install the dependencies that have been defined for your app. The content of this folder should not be manipulated outside of the bowser.json configuration file (note that this folder is included in the GIT ignore file and thus will not be included/saved with your commits).

The scripts folder contains a SharePoint app initializer (init.js) as well as an application main module (main.js), which serves as the entry point into the application. All files (with the exception of init.js) are AMD modules and any new module created should also be defined as such.

The styles folder contains a common style sheet by default (common.less) and is setup to use the LESS CSS pre-processor from within the AMD modules (just take a look at the main.js module).

setup Folder:

The setup folder has several files used by the build process to create both the “compiled” single-file web app as well as a development version that utilizes requireJS as the AMD script loader.

_build Folder:

The build folder is created by the (Grunt) build process and is where you will find the built app along with a single-file compiled version of the app called app.run.aspx and app.debug.aspx (includes non-minimized code).

About The Build

The build for the project is handled by Grunt. The primary tasks available are:

  1. build : Will build the problem, but not the single-file application.
  2. deploy : Builds the project and then copies the files from the _build folder to a designated folder (ex. a SharePoint folder that is currently being synced to your OneDrive for Business local folder).
  3. spa : Will build the project and create the single-file compiled versions (app.run.aspx and app.debug.aspx)
  4. jshint : validate our code with jshint
  5. watch : Validate your code with jshint as files are saved

Example

To play with a test app I created, that shows how easy MyBoard (a Task Manager app I also created) is to install, take a look at this: github.com/purtuga/SPLightBoard. The App’s compiled single-file is located under the dist folder.

What’s Missing or Whats Next

The current setup will get you up and running with creating small apps that can be quickly deployed to SharePoint.  The setup of third party libraries needs some more attention in future versions, since currently only SPWidgets (full disclosure: my own creation) is integrated into the Require.JS setup and build process – mainly because its currently the only one I list that is AMD compliant… SPServices is making the move, but has not yet release a version that supports it and SharePointPlus does not offer such support (as of this writing).

I’ll also be making changes at some point to provide a way to efficiently add jQuery/jQuery UI and require.JS support, that takes into consideration any existing versions of these libraries that may already be loaded (a common problem with SharePoint environments is that every tries to load their own version of these libraries without first checking if they are already available).

Lastly, the generator does not currently provide a setup for running unit tests, although a test folder is created during setup. My goal here is to provide a menu allowing you to choose a testing framework and then re-use existing generators to add the setup.

Conclusion

Yeoman generators make setting up new projects a breeze and I’m glad I went through the effort of converting this SharePoint SPA template I had. Setting up new SharePoint web apps is now an effort that takes only a few-seconds.

Creating a Private Event Bus with jQuery

Tags

, , ,

jQuery has a great API for working with DOM events – both native and custom. The great thing about its system is that you can also use it on regular objects, thus allowing you to quickly create private event systems for your application that don’t rely on DOM elements. In this post, I will show how I recently accomplished that by creating a private event bus for use on the Sharepoint MyBoard web app.

When building scalable apps or components the use of events helps keep functional code small and isolated while assisting in defining how that component interfaces or interacts with other components. The event system breaks the dependency from other components because it simply emits a signal “to all” listening indicating that a certain state or action was encountered. What those listening do based on that information we don’t care – that logic is built into the listening component.  Likewise, a component can listen for certain types of events in the Bus that it will use to mange and control its own functionally.

Let’s start with the end result and by writing down the desired API we would like out of the event bus.

Listen to events:


// Listen to events
events.on("eventName", callback)

// Remove an event listener
events.off("eventName", callback)

// Trigger  an event
events.trigger("eventName", [argsToPassAlong])

Pretty strait forward API.  So let’s create this with jQuery:


var bus = $({});

That’s it. I know this is going to look strange to you – you don’t normally see a JavaScript Object being passed into the jQuery constructor, but it’s a valid signature – http://devdocs.io/jquery/jquery#jQuery-object

So what we have above is a jQuery selection instance that has full access to all of jQuery prototype methods ($.fn).  It’s a bit overkill, but it works and it leverages the already available jQuery event system, which personally, I really like. Here is an example of it in action:

Example on jsbin.com

Hope you found this helpful.

SharePoint SPWidgets v2.5.2 Released (bug fixes)

Tags

, , , ,

Over the weekend, I released SPWidgets (purtuga.github.io/SPWidgets) version 2.5.2. SPWidgets, if you are not familiar with it, is a set of developer JavaScript widgets meant to create customizations for a SharePoint environment.  It currently includes a People Picker, Filter Panel, Kanban Board Widget, Date Field and an Upload Widget.

Whats New

This latest version provides mostly bug fixes based on user reports as well as refinements I identified while continuing to improve the MyBoard Single page Application (a SharePoint Kanban Task Manager). The full change log can be found in Github (here).

Automated Testing Framework

In addition, and in an effort to improve code and release quality (as well as time), I have started the process of adding Unit Test cases to this library. I have worked with a few different types of testing frameworks (Mocha, QUnit, Chai, Sinon) but wanted to try a new one, so I went with Jasmine.  Its still early for me to judge it among the others, but the one thing I can say looks promising is that ti includes everything I need in one package (Assertions, HTTP mocks, ajax support, etc).  The setup into a web page was simple, however, getting it incorporated into the Grunt build process was a little tricky and at times frustrating – I think mainly because I needed to setup requireJS (a client side library) into the build system (a “server” side setup).  The good thing with these types of tools are that once its setup – its (for the most part) hands off.

I have added some test cases already and my goal is to continue to increase code coverage with it. I have even started to collect SharePoint API responses that will be used for mocking up the calls that several of the widgets make to the SharePoint APIs.

So that’s what’s going on… SPWidgts v2.5.2 provides bug fixes and lays the foundation for starting to add unit test cases.

SharePoint SPWidgets Converted to AMD Modules

Tags

, , ,

SPWidgets – purtuga.github.io/SPWidgets – is a project I started back in 2012 when I started to take advantage of the SharePoint platform to build custom web solutions for the teams I worked with. It initially served as a place to gather reusable User Interface (UI) components that could be quickly applied to multiple projects – similar to jQuery UI (it’s design was inspired by jQuery UI). It has since grown to also include reusable utilities as well as SharePoint API methods – each self contained and again reusable across solutions.

I have now taken the self-contained reusable concept a step further and converted all files in the project to Asynchronous Module Definitions (AMD). If you have not yet learned how to use AMD and break up your projects code into modules, I suggest you take the time as it will forever change the way you design software – in a positive way. I think that anyone would agree that working with small pieces of code is much better than to try and navigate through a 5000+ line script file.

Why

I’m a big proponent of modules and now use requireJS for just about all web development. SPWidgets was already broken up into individual files – each providing self contained functionality, so the move to AMD was not a difficult one for me. The move benefits the development of this library as well as anyone else wanting to use these modules without having to include the entire library into their projects. This was another big motivation for the move. When building SharePoint web apps, I want to keep them as small as possible, and AMD modules allow me to do that so that only the modules I referenced as dependencies will be compiled into the final file.

Build Process Updated as Well

I also took this opportunity to convert the build process to use Grunt, which was something that was way past due – this project was still using the cumbersome Ant system. Because SPWidgets is a jQuery library used by others (yes, there are a few out there – I think), the build process “compiles” the final single file just as it did before (look in the “dist” folder). The move to AMD should be transparent to existing users of this library – all widgets and utilities should continue to be exposed as they were before and with the same input signatures.

Support for Bower Package Manager

In the process of converting all code to AMD and re-factoring the Demo showcase page, which I also use for development, I also introduced support for Bower to help manage the project’s dependencies and also allow others to list SPWidgets as one of their dependencies.

Conclusion

Having SPWidgets broken up into AMD modules provides the most flexibility for advanced development while at the same time, through the use of the build process, continue to allow for the single jQuery library to be generated. In one of my next posts I will demonstrate how to build a quick SharePoint web app that utilizes a few of the modules available in SPWidgets.

How to render a SharePoint page in IE using EDGE mode without changing the master page

Tags

, ,

So you are running the latest version of Internet Explorer and you’re thinking: I should get good performance and better User Experience when accessing a SharePoint site. After all, Microsoft® has done allot of work to bring that browser closer to being standards compliant. Wrong!

SharePoint’s User Interface (UI) is a creature of habit. It’s coded to target specific versions of Internet Explorer (IE), which makes me think some group at the company is stuck in the early 2000’s. If you take a look at SharePoint 2010 page source, you will see this meta tag in the section:


<meta http-equiv="X-UA-Compatible" content="IE=8" />

This essentially tells Internet Explorer to render the page using the IE 8 rendering engine even if the current version of IE is a more recent one (ex. IE10 or IE11).

SharePoint 2013 is no better. Despite still not using the HTML5 standard header, it instructs IE to render the page using IE10:


<meta http-equiv="X-UA-Compatible" content="IE=10" />

This is why I always strongly suggest using a non-IE browser when using SharePoint.

In working an issue found by a user of MyBoarda SharePoint task management app that I have a available – I found that the problem was due to the page being rendered in IE8 mode. If I brought up the debugger in IE11 and switched the rending engine to EDGE (latest version), then the issue would not occur. Rather than spending time trying to find a code workaround for this version of IE, something I have decided to stop doing long ago, I instead researched if there is a way to force the MyBoard app page to be rendered using IE EDGE, but at the same time not impact the entire site.

Changing the Master page to include the meta tag to render the page in IE using the latest engine is not an option, since MyBoard is an app whose main feature is that it can be quickly used from any site in a SharePoint (it simply requires it to be placed in a Document Library). It’s also only a single page, thus impacting an entire site for the benefit of only one page is not good. There are also several posts on the web documenting the negative impacts to a SharePoint site if this is done – perhaps the main reason that SharePoint, by default, sets its rendering engine to a specific version of IE.

So what do we do? What options do we have?

Solution

The solution is to use a simple HTML file (I call it my “IE Loader”), which loads with a meta tag that instructs IE to render in EDGE mode, and show the MyBoard app page in that iframe. The reason this works is because IE can only set the rendering engine once per page load. Once set (by the “top” page) it cannot be changed and thus all pages loaded through an iframe are forced to EDGE mode.

Here is the HTML:

This file, named ie.aspx (yes, file extension is, and needs to be, ‘aspx’ instead of ‘html’), can simply be uploaded to a Document Library and it will load the file defined at line 26 (var url) by default.

The JavaScript code simply ensures that the iframe takes up the entire width and height of the browser window, and maintains those dimensions even when window is resized, thus providing the allusion to the user that its actually not in a frame. In addition, it supports providing the URL to the page that should be loaded via the ‘search’ parameter field. Example: the following URL

ie.aspx?/sites/sitename/documents/myCustomPage.aspx

will load the page at /sites/sitename/documents/myCustomPage.aspx in the iframe rendered using the latest version of IE.

A default page to be loaded should be set so that if a user clicks on this file they will not get an alert.

Some caveats and tips:

  • Displaying the page in an iframe means that all links that the user clicks on, will also be displayed on the iframe and potentially breaking form functionally. To get around this, one can further enhance the code above to “break” the iframe if the URL is changed to one that is not the page that was meant to be displayed in an iframe.
  • For non-IE browsers that may access the ie.aspx page, it may be desirable to also break the iframe and just show the intended page directly.
  • If using this workaround on a controlled page, code can be added to that page to detect if IE is being used and if so, whether the ie.aspx page is the one displaying it.

Conclusion
So the solution here will trigger IE to render a single page using the latest version of the browser while leaving the rest of the site intact. This approach also does not require any structural change to a site or the involvement of an IT department to implement. In my current use of it, I have additional code that further integrates the “IE viewer” with the app I have loaded in the iframe.

Grunt – How to Copy Only New Files

Tags

, , , ,

In using Grunt on a large project, I wanted to speed up the build time by only copying files to the staging area that have changed. Unless I missed something, the Grunt Copy plugin always copies all files, regardless if they were changed or not. It does provide hooks that we can use in determining what should be copied, thus I created this small function that does just that using the filter parameter. The function simply compares the time stamp of the FROM file to the TO file, and tells the Copy plugin if it should copy it or not.

The function below can also be found in this GIST:

Usage

In your Gruntfile.js, include the above function before defining your grunt configuration. Then use it in the Copy task as:


grunt.initConfig({

    copy: {
        build: {
            src:    "src/**,
            dest:   "build/",
            expand: true,
            filter: onlyNew(['copy', 'build'])
        }
    }

})

 

The example above will copy files from a the src folder to the build folder, but only if they are newer than those currently in the build folder. Note the use of expand: true, which is necessary in order for this work.

Using a Local Time Stamp File for Destination

I often use the Copy task to copy files over the network to a server – usually a linux mounted directory or a SharePoint document library folder. I call it my deployment task. Both of these types of destinations can be very slow when copying large amounts of files because the Copy task needs to access file information on the destination in order to determine if the file should be copied or not. To get around that performance issue, a second parameter can be given to the onlyNew function – a path to a local file – that will be used as the Destination file to compare time stamps to. That file will be “touched” at the end of the build so that it insures the next time the grunt task is ran, it will be comparing file time stamps against the last run.

Here is an example of a Copy task that uses a local file for comparing time stamps:


grunt.initConfig({
    copy: {
        deploy: {
            src:    "build/**,
            dest:   "//network.mapped.drive/folder",
            expand: true,
            filter: onlyNew(['copy', 'build'], "build/copy.deploy.last.deployed.txt")
        }
    }

})

 
I use this function in several projects to assist with a more efficient build. Perhaps I should create a Grunt plugin out of it, so that it can be better incorporated into a build by defining it as a dependency in the package.js.

Grunt: How to embed the content of files in JavaScript Files

Tags

, , , ,

When working with any project, large or small, I almost always break up the source into different files in order provide clarity and maintain small working components. So you usually find a few different files under the src folder of my projects: JavaScript files, HTML files and CSS files – all of which are then embedded into a single file by the build process.

When I started to work with Grunt, one of the first functions I needed was one that allowed me to embed the content of one file into another. The function works in conjunction with the grunt copy plugin as the ‘process’ option callback function. I needed this when:

– embedding JavaScript files into HTML files
– embedding CSS files into HTML files
– embedding HTML files into other HTML files
– embedding HTML, CSS files into a JavaScript files

The widgets and plugins I create are often used by simply including a script into the page. That JavaScript file includes everything needed to provide the functionally. In the source file, I often have variables defined that will hold the content of other files. For Example: in this code sample, the content of a file called ui-template.html will replace the token show below (inside the quotes):

var uiTemplate = "//BUILD_INCLUDE('./ui-template.html')[asJsString]";

The function recognizes the following tokens:

//BUILD_INCLUDE()
/* BUILD_INCLUDE() */
<!-- BUILD_INCLUDE() -->

Just include these in the various files that need content embedded and then define a grunt copy task that uses this function as the callback to the ‘process’ option. In addition to these tokens, options can be passed along by wrapping them in square-brackets. One the options in the example above is asJsString, which essentially takes the content of the given file and formats it as a JavaScript string – ideal for embedding into JavaScript files. Right now, this is the only option supported. Note that when using it to embed content as a JavaScript string, it is assumed that the content will be embedded within double-quotes, as shown in the example above.

The name of the file to be included can also use normal Grunt template tokens, so you could do something like this:

// BUILD_INCLUDE('<%= buildDir %>/src/file1.js')

Here is the full function code, hosted as a gist at Github:

Usage Example

Here is a full example of how to use this function. Suppose you have the following files:

demo/myPlugin.html
src/myPlugin.js
src/template.html
src/styles.css
Gruntfile.js

The demo/myPlugin.html contains the following:

<script>
    //BUILD_INCLUDE('dist/myPlugin.js')
</script>

The src/myPlugin.js contains the following:

var setup = {
    template: "//BUILD_INCLUDE('src/template.html')[asJsString]",
    styles: "//BUILD_INCLUDE('src/styles.css')[asJsString]"
}; 

The above setup object will have its properties values replaced with the content of files in src/template.html and src/styles.css respectively. Note the use of asJsString option at the end of the build include string.

The Gruntfile.js includes the function below and defines a copy target similar to the following:


// includeFile function is define above this code

grunt.initConfig({
    copy: {
        build: {
            options: {
                expand: true,
                process: includeFile
            },
            files: {
                "src/myPlugin.js": "dist/myPlugin.js",
                "demo/myPlugin.html": "dist/myPlugin.html"
            }
        }
    },
});

Running grunt copy will generate a dist/myPlugin.js that includes both the HTML and the CSS file content assigned to the variables shown above. It will also generate dist/myPlugin.html that also includes the content of the dist/myPlugin.js file.

If wanting to look at a working example of this in a real project, take a look at my jquery.todoList plugin over at github. It uses this approach to build the distribution files.

How to Scope 3rd Party Cascade Style Sheets (CSS) with Grunt

Tags

, , , ,

Every client side web developer or even the occasional advanced user knows what a closure is suppose to do and why it is important to keep all variable within a private scope. Snippets like this are common when working with jQuery:

(function($){
    var myPrivateVariable = 'abc';
    // $ is private here

})(jQuery);

It allows you to code freely inside of the above IIFE (Immediately-Invoked Function Expression) knowing that anything properly declared (with a `var`) inside will not leak out to the global space as this possibly interfere with other logic running on the page.

What about Style Sheets?
Scoping stylesheets is easy if you are the author of that stylesheet and you know exactly what location of your user interface (UI) that style applies to. Stylesheet scoping means defining your selectors to a specific location on the page. That location is simply defined as an additional selector that is prepended to every other selector in the Stylesheet.
Example: let’s say I’m defining a Stylesheet like this:

h1 {
    font-size: 30px;
    color: red;
} 

This would affect all Heading 1 elements on the page. But I need it only to impact the h1 I define inside a `DIV` that has an ID of my_widget. To do that, simply prepend that selector to the rule sets:

#my_widget h1 {
    font-size: 30px;
    color: red;
} 

Ok. What about 3rd Part Libraries, Like jQuery UI and Bootstrap?

What if you’re trying to use a 3rd party UI stylesheet framework and are trying to have those styles only apply to elements inside a specific selector. I came across that need recently when wanting to use a jQuery UI theme inspired by Bootstrap. The app I was creating was going to be inserted into another application (Mingle) and was going to have to play nice with that application’s existing look. I certainly did not want it to interfere with that application’s User Experience (UI). The only answer is to scope all of the styles from the above theme to the container that holds my app.

HTML5 to the Rescue (almost)

HTML5 does have a feature called ‘scoped’ which allows you to use definitions inside HTML elements and have its rules apply only to the children of that element. But unless you are currently (as of this writing) building your code to run on Firefox only, it’s just not an option. There is a jQuery plugin that attempts to pollyfill this feature. But in reading the information on the site, it sounds like it may not be reliable when using the @import directive, which I may need in some occasions.

Grunt Task to the Rescue
Doing this manually is just not efficient so what I needed was a build time grunt task that would parse the stylesheet and insert a prefix to every selector. After trying a few plugins and getting near the point of ‘I’ll just create one myself‘, I found grunt-css-selectors (by Eric Ferraiuolo @ericf) which does the job.

The setup is just like any Grunt plugin.

– install the task

npm install grunt-css-selectors --save -dev

– configure the task (Gruntfile.js)


grunt.initConfig({
    css_selectors: {

        options: {
            mutations: [
                {prefix: ".my-app"}
            ]
        },

        build: {
            files: {
                "build/css/jquery-ui.custom.scoped.css": [
                    'src/css/jquery-ui/jquery-ui.custom.css'
                ]
            }
        }

    }
});

grunt.loadNpmTasks('grunt-css-selectors');

– Run grunt

The configuration above would take the stylesheet located in `src/css/jquery-ui/jquery-ui.custom.css`, prepend the value `.my-app` to every selector and save the new CSS file as `build/css/jquery-ui.custom.scoped.css`. The style rules selectors will look like the following in this new file:

.my-app .ui-button:active,
.my-app .ui-button.ui-state-active {
    background-image: none;
}

Now when, I include the new CSS file on the targeted (Mingle) page, I’m assured that it’s style rules will apply only to the content inside of elements having the `my-app` class and thus not interfering with the remainder of the UI.

How To: Load a Private Version of jQuery with Require.JS

Tags

, , ,

AMD Loaders Rock!

I have been using require.js (an AMD loader) to do allot of client side development and can’t really imagine starting any decent size project (App) without it.  It allows you to break up your code into modules that are loaded along with their dependencies (other modules). This design patters allows for greater code maintainability as well as improve overall application development by abstracting away the dependency loading mechanism (think deep dependencies: module A is depended on Module B, but B is dependent on C, D, E…). The patterns also encourages keeping the global scope clean and ensuring that all variables are defined to only the executing scope – a pattern that everyone should follow – regardless of AMD – so that conflicts with other modules/libraries/frameworks are not introduced.

A Private Version of jQuery

One of the needs I came across in the last week was how to load a specific version of jQuery via require.js and keep that version private. I’m familiar how to do this in a non-AMD way, but I wanted keep to the AMD design pattern. The app I was developing was going to be added to a page that already had jQuery loaded, so I needed to ensure I did not interfere with it or overwrite it. jQuery itself already supports AMD loaders, but even in the instances where it detects an AMD loader on the page, it still adds two variables to the global space: jQuery and $. The answer obviously is to use  jQuery’s noConflict() method.

The documentation over at require.js provides an entire chapter on how to work with jQuery, including how to obtain a private version of it by using jQuery’s noConflict() method, which is the ideal method for when wanting to load jQuery from a CDN.  I was hosting my own copy of jQuery for this project and thus found the approach detailed there to be overkill. As it turns out, there is a simpler (IMO) setup if you are going to host the copy of jQuery: wrap it in a define() statement and immediately call noConflict().  Here is the content of my jquery.js file:

define(function(){

    // jQuery's code here

    return jQuery.noConflict(true);

})

So this includes the jQuery code inside of the module and immediately calls jQuery.noConflict(true), which essentially reverts the jQuery and $ global variables to their prior values (if they were set), thus ensuring I don’t interfere with any other version already loaded on the page.

Like I said: if you are loading jQuery from a CDN or a location where you don’t have control over the file’s content, then the instructions detailed in the require.js documentation should be followed.

What About jQuery Plugins

One thing I realized, as I was implementing the above code, is that most jQuery plugins (mine included) are not AMD aware. I have not tried (will soon), but I think require.js provides a mechanism for handling that as well. And then again: if hosting those locally along with your App, then the following should also work:


define(['jquery'], function(jQuery){

    // jQuery Plugin code here. Example:
    (function($){

        ...

    })(jQuery);

})

 

One of the tasks I took way from this effort was to make my jQuery plugins AMD aware the next time I make a change to them.

 

 

Follow

Get every new post delivered to your Inbox.

Join 40 other followers