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.

 

 

A JSDoc Template to Output SDOCML Files

Tags

, , ,

In one of my recent posts, I wrote about how to create a SDOCML file to extend Aptana (JavaScript IDE) content assist. This is part of my quest to find an IDE that can provide content assist as well as Eclipse’s Java IDE. But creating these files manually is just too cumbersome. What I needed was a way to auto generate these from my code base.

JSDoc To The Rescue

Jsdoc is a great tool if you are developing plugins or libraries that will be used by other people. It runs against your source code, picks up the jsdoc dockets (tokens that describe your functions and variables) and builds up documentation for it – normally in HTML format – essentially generating API documentation for your code. The output of the tool is controlled by a jsdoc template that can be defined on input and whom receives all of the information jsdoc was able to read from your source files.

I’m a big fan of documenting code. I personally think it helps in quickly understanding how to use a piece of code, and prevents wasted time in reading other people’s code just to try and figure out how to use it. JSDoc doclet can be seen all through out my code, thus creating a template that will output that documentation in the format that Aptana needs quickly became a necessity.

The Template

After searching the web for a template that would allow me to produce SDOCML formatted XML files, I found none. So I created my own. The template can be downloaded from github (here) and produces one single file – the SDOCML formatted file ready to be used with Aptana. It’s purpose is to output JavaScript Classes along with its instance and static methods.

Use it like any other JSDoc template, by using the –template input options and pointing to the folder that contains the template (the one with the publish.js file):

jsdoc --template ./jsdoc-sdocml-template/template ./src

There are a few things that this template alters in the output. These were needed in order for the file to be compliant with Aptana’s SDOCML definition. They are:

  • It outputs (currently) only Classes and Namespaces, along with their members
  • JSDoc Module names are stripped from the XML file due to unsupported characters. So something that may be annotated like this – module:widget/computers.Mac – will be output as: Mac
  • Some Type definitions are adjusted so that Aptana can recognize them

So does it work?

In a sense, for simple Classes, yes it does work. But Aptana seems to be very sensitive to the format used on type inference and to the content of the SDOCML files.

Example: Classes attached to namespaces (ie. Object) don’t seem to get recognized:


/** @namespace my */
var my = {};

/**
 * A widget factory
 * @class my.Widget
 */
my.Widget = function(){}

Also, Type inference is not consistent and as detailed in my prior post, Aptana is just too sensitive as to when it show content assist and when it does not. I had high hopes for this solution. The thought of being able to add good content assist to a JavaScript editor by simply dropping in a file is an awesome concept. It avoids depending on editor-dependent conventions that may not match the style of code you are working with.

Maybe I need to give up on Aptana!

What’s Next?

I’m not done yet.  In trying NetBeans IDE recently I found that not every editor has a “drop-in file” concept for augmenting content assist. It (and other IDEs/Editors) do however, have good support for reading and understanding the classic way of building a JavaScript Class:


function Widget() {}

Widget.prototype.getParam = function() {};

Widget.prototype.setParam = function(){};

We all know that in today’s OO JavaScript programing, you are always most likely going to have a Class Constructor instead of defining them the way detailed above. I realize now that what I need is for a JSDoc template that output JavaScript code. Yes, generate code from code. I need the output to simply provide a stub representation of the Classes and Namespaces using the standard “classic’ way of defining these.

So the stage is set for the next post on this topic.

 

MyBoard – A SharePoint Task Management App

Tags

,

Almost a year ago I started to (finally) gain interest in learning Grunt – the Node.js task execution framework most used in building JavaScript projects. I have been a long time user of Ant, mainly because I use the Eclipse IDE, where support for Ant is built in. But as my work with front end web projects increases significantly (I recently accepted a position as a web GUI engineer) the need to become familiar with these type of build tools was essential to ensuring a productive and streamlined workflow. In addition, I wanted to continue working with the SharePoint platform and specifically, attempt to understand how the Ribbon is composed and whether I could create my own plugin for adding custom Ribbon tabs.

For this, I stared to develop a project I call MyBoard – a SharePoint Single Page Application (SPA) that turns any SharePoint list into a list board (Kanban) complete with drag-and-drop and easy access widgets for managing the cards on the board. This is now a fully working “app” (not a SharePoint App) that I am using in several different projects where we needed to manage a list of work items across a small group of people. It’s simple and efficient and all it takes to get it going is uploading one single ASPX page to a document library. Oh, yeah: and it works on SP2010 and 2013 (and probably even SP 2007 if the proper document header is used).

MyBoard - AppIn working this app, I have ended up with several reusable components that I’m sure I’ll take advantage of in future projects. Some of which I’m also thinking of also making available as open source projects on github – along side some of my other projects, including the SharePoint widgets library.

About MyBoard

I like Trello. It’s clean, fast and efficient as it allows you to apply several action on the cards via each card’s menu. With that service as the model, my requirements for MyBoard were the following:

  • simple to setup and configure including support for zero-configuration
  • adaptive of site’s existing data (lists, Document libraries)
  • multi-user support and bookmarkable urls
  • integrated into the site’s look and feel
  • quick actions available from each card

The app works by having the user select the current site’s List to be used in retrieving data for display, along with the list Column that will be used to build the Board. The Column needs to of type Lookup or Choice, so that its values can be used as the Kanban board’s columns.

A little more on these, including what I have learned and where I currently stand with them:

Simple to Install, Setup and Configure

As I already mentioned above, the entire app is contained within a single ASPX file, which includes all needed dependencies include a private version of jQuery – thus there is no issue or conflict with deploying this to a SharePoint site that already uses jQuery. You drop that file into a Document Library and everything else is configured from the app once you click on the file.

This single file is the result of the build process, which uses grunt as the task execution tool. It takes all if the code files, it combines them into one file, minimizes it and finally inserts the code into the ASPX file. In addition, I have a grunt task that also copies the built ASPX file to the document library on SharePoint – essentially “deploying” the app. Grunt tasks were strait forward to setup and there are tons of examples online on how to achieve any task. I did have to write some functions for embedding contents of one file into another, something that I could not find good example on. There are tons of concatenation examples – but I needed to include the content in specific locations. Perhaps I’ll write about that in the future.

The project source, however, is laid out very differently on disk, with several individual files. For development and debugging I have a special ASPX file that loads each file individually so that I can easily use the browser development tools to focus on the set of functionally I’m working with rather than having to browse through a long list of code all in one place.

So this allowed me to become very familiar with Grunt – just as Gulp is starting to gain some ground. I have not tried it, but the approach it uses seems allot more attractive to me: code-over-configuration.  Perhaps that tool is another excuse for me to create a new project where I can apply it.

Adaptive of site’s existing data (lists, Doc libraries)

I wanted the app to be able to use the site’s existing data and not impose a specific format to be followed or predefined structure. The only requirement is that the List or Document Library have a column of type Lookup or Choice, which is needed to build the board. This design makes it feasible to use this app immediately with existing site’s data.

The only portion of this design I am not happy with is how slow the editing of a card is. When editing the card content, the SharePoint list Edit form is shown in in a dialog, thus loading all the bloat that makes up that form. I may implement my own edit form and add some of the features found in Trello (like inline editing, and progressive saving).

Multi-user support

Multi-User support here simply means that updates by others users are near-instantly seen by others whom may also have the card displayed on their board. For this I built a library that provides data persistence between the SharePoint list data and the web application. This layer is so cool (if I can tune my own horn here) that I know use it on all SharePoint projects that needs to get data out of SharePoint lists.

It uses the GetListItemsSinceToken API operation and depends on Knockout.js and it’s Observables to achieve its automatic insertion and removal of items from the query result as well as the notification of any bound listeners. You use it the same as SPServices GetListItems, but you get back a Promise that resolves with a Knockout observable array containing the list item matching the defined filter. From that point forward the query continues to check the list for changes on the query used on input and reflects that on the results array if any are found – which in turn are reflected on the UI if the Observable Array is bound to the UI (presentation/view). This library also provides a custom binding called SPField that handles the display of sharepoint data – including the format of it (like lookup, Date Values, etc.).

I’m considering releasing this library as open source via github. The code is pretty solid right now, but I need to spend some time documenting the external API and provide some usage examples – maybe even a sample app.

In addition to having constantly updated data displayed on the board, the app also needed to support the ability for the user to “preserve” the setup, so that they did not have to create it on every page visit. This is supported with two approaches:

Predefined Board Setups

An administrator (one having write permissions to the folder where the MyBoard ASPX file is stored) can create boards and then save them as predefined setups. These show up on the Ribbon menu, under the ‘Board’ button:

MyBoard - pre-defined

Stateful URLs

This is a very common approach with SPAs – using the hash portion of the URL to represent the “page” the user is visiting – also called routes.  MyBoard uses the Sammy.js library to achieve this functionality and thus any user can create and configure a Board and then bookmark the page. As they configure the board, the URL is updated to “maintain state” and thus will recreate the view once loaded again. This also makes it ideal to send the url to others, if wanting to share information. Here is an example of such a URL:

/MyBoard.aspx#!/v/Tasks/Task+Status/Status[matchType]=Eq&Status[logicalType]=Or&Status[values][]=Completed

 

Integrated into the site’s look and feel

This is a work in progress, but the primary thing I wanted to accomplish was to utilize the Ribbon to provide navigation and controls for this app. With time, I’ll look to also use the styles used to brand the given site so that the entire apps feels integrated.

Customizations of the Ribbon are well covered now a days in blog posts, which is done through declarative XML. This is the official and supported way of doing it. But this does not mean it’s the only way. I thought: there has to be a way to create these via JavaScript from a client side script – after all, the entire Ribbon is made up of HTML, CSS and JavaScript. After much searching of the web and debugging of the various ribbon JavaScript files, I have been able to come up with a library that allows you to create your own custom ribbons – or to clarify: add tabs to the OOB SharePoint ribbon. The screen capture above shows the MyBoard Ribbon created with this library.

It does not support all the possible controls that the Ribbon can provide – a vast and rich set. Currently I have support for large buttons, small buttons (usually stacked vertically), Flyout Menus (pop out menu with buttons) and Flyout Areas (my own creation – a pop out are that can be used to display anything). All of this in a client side JavaScript library that frees you from having to use the declarative XML approach and place files on the server side. I am currently using it with SharePoint online O365) as well as SharePoint 2010 on premises.

This is yet another library that I’m thinking making available as open source via github. For the most part, much like the data persistence library, the code is pretty solid. The documentation effort, however will be significant and will delay when I make this available (I don’t like to release a half-baked library :) ).

Quick actions available from each card

Having to open each card just to make a small changes, like setting a value in a column is overkill. Simple tasks like that should be possible right from the card menu – just like Trello. So each cards menu (currently) supports:

  • assigning users to the card
  • email the card
  • showing the cards direct URL

MyBoard - quick actions

Other actions that are In the backlog and will be implemented sometime in the near future are:

  • set categories (labels)
  • subscribe to alerts
  • ability to set any single value columns (those of type Lookup or Choice)

Most of these action are possible only after the user configures the board, which once created, allows the user to set which of the selected list columns will support the action (ex.: which column should be used as the card Assignee, which column should be used for labels, etc.)

So what am I going to do with this app?

Right now I’m keeping this app private and using it in a few projects. I was thinking about converting it to a SharePoint App, but I’m not a VisualStudio person and with my ever decreasing focus on building tools/apps on SharePoint, not sure that will happen (Ps. Would love for Microsoft to support packaging SharePoint apps outside being forced to use their own toolset). The thought of putting up for sale has crossed my mind. Nothing outrageous, but a small fee. But perhaps in the end, I might make available a free “closed source” limited functionality version with an option to license the full version. That last option may be the one I ultimately pursue. It will give the opportunity/excuse to convert this project to use Require.JS and split up the code into modules. Once they are in place, using a (Grunt) build task that creates both versions will be fairly strait forward.

If you have made it this far in reading, let me know what you think I should do it. Do you think there is a market for a paid version?

Special Thank You

I have asked a set of folks who are much more involved with SharePoint than I am, to evaluate this app and received some feedback – specifically from Stefan Bauer (@StfBauer, blog at http://www.n8d.at/blog/). His UI/UX constructive feedback was outstanding and although I have not yet followed up on all of his feedback, I will at some point in the future.

I also have to give kudos to Daniel Walker (@spevilgenius, blog at http://spevilgenius.blogspot.com/ ), whose blog post on how to create Ribbon tabs and buttons via JavaScript helped and inspired me kick start the Ribbon library I reference above.

 

Whats New in v2.3 of SPWidgets – SharePoint Client Side Widgets

Tags

, , ,

Its been a long time since I tagged a new version of SPWidgets. Too Long. I really should not wait so long between versions, specially when I was making changes all along.  Most of the changes done were in response to issues opened on github as well as in support of a side project I have going called MyBoard. More on that project is forthcoming on a separate post.

This version does not introduce any new widgets, but rather builds upon those that currently make up the library.  If you are a current user of SPWidgets, I don’t foresee any issues with upgrading.  Version 2.3 can be downloaded here: https://github.com/purtuga/SPWidgets/archive/v2.3.zip

The library, both the regular and minified version, is located in the plugin directory.

Are you currently using SPWidgets? If so, drop a comment below to let me know which widget(s).

Enjoy!

Change Log

People Picker Widget:

  1. Support for defining a token that represent current user (ex. [ME]), which translates to caml value <UserID/>
  2. Introduce input option that allows user to control the container where the autocomplete results will be displayed.
  3. Allow user to override jQuery UI’s Autocomplete widget minLength option. See issue #20
  4. BUG: Picker does not handle un-resolved users. See issue #21
  5. Allow input options to be set globally for this widget
  6. BUG: getSeleted does not work. Switch statement does not have ‘getselected’ in lowercase, thus it never matches. See issue #15
  7. BUG: When input element already has a value set, init of widget fails. See issue #14
  8. Support for other types of accounts like groups. Possible values are: [None | User | DistributionList | SecurityGroup | SharePointGroup | All]
  9. BUG: When used on a element that has z-index set suggestions show behind the input element.

Filter Panel Widget

  1. Display columns of Type ‘Attachments’, as a YES/NO dropdown. Column is of type of Boolean.
  2. Remove the focus on the first element when a reset is done.
  3. Does not support a column of Type Choice with Multiple values. Internal type is ‘MultiChoice’
  4. BUG: Created and Modified columns do not display the time picker – only date.

Board Widget

  1. New method to return a list of available columns for the board. Such method will be useful when wanting to create custom UI’s for showing/hiding board Columns.
  2. BUG: if an item is changed by someone else so that it no longers appears in the board being displayed, the Board State column total number of items is not updated to reflect the number of item under it.
  3. Enhancement to include a new input option that will display the board with fixed height colummns. Similar to how Trello works today: All column bodies are fixed height and user is able to scroll through each column’s content independently.
  4. Make each Column Title be “attached” to the column content. In other words, remove the spacing between them. (Feedback provided by Stefan)
  5. Enhance the Headers so that the title of the Column is Left justified and the Number of items is Right justified. (Feedback provided by Stefan)
  6. Change code so that the Column picker button is NOT automatically displayed when calls include visible columns. Options should be driven by developer.
  7. SPShowBoard(“setVisible”) should support a keyword of ‘all’, allowing the developer to automatically make all columns visible. This could also be an empty array ([]).
  8. Consider removing the ui-widget-content class from the container that holds the board columns. Some styles of jQuery UI have a background that throws off the styles between headers and body of kanban
  9. When making all column equal height, use ‘min-height’ instead of height css attribute.
  10. Change the Column selector “all/none” button to use jquery UI icon ‘ui-icon-radio-off’ instead of the current checkbox.

Upload Widget

  1. BUG: Post upload page (if checking is needed) fails to display for SP sites in non-English locale. See issue #16
  2. BUG: Widgets does not work on SP2007. See issue #9.
  3. fillTemplate() utility seems to use a redundant regex [\{\{\}\}]. Reported by Alexey with Issue #10

Date and Time Widget

  1. Support an ‘inline’ option that allows you to display the widget on a page at all times. With inline, the use of an input field should be optional by the user.
  2. BUG: When Allow Multiples is set and field is setup to display only date (no time), removing selected dates does not work.

 

A New Professional Focus – Web GUI Developer

Tags

I’m moving on to a new role as a Web GUI Developer !

I have been a Program/Project manager on large scale provisioning software systems for close to 10 years. I ran the Software Release Management cycle and also played an integral role in process definition and productivity improvements initiatives. During that time, I would always insert myself into projects that needed some web development done (but no one to do it) because of my passion for it. That’s how I picked up SharePoint client side customization knowledge – I use it as the back-end services to the web apps I create. I enjoyed the work I did as a Program/Project manger, mainly because the position in most cases allowed me work very close to the development teams where I was given the room to address problems together – rather than to just track that a problem existed and assign it to someone else.

I have been working with HTML since version 3 (circa 1997) but have never really held a position whose sole responsibility was development. Always wanted to, but the right opportunity never came up – until about two months ago. The company I work for is now advocating the creation of front end applications using HTML5, CSS3 and JavaScript – a big shift from the Java based development that has been in use for decades. When a position opened up on a new cutting edge application (in the cloud computing space) that required these exact skills, I was quick to put my name in the running and thrilled when I was offered the position.

I started on the new project in May and I’m now working with the technologies that I enjoy and building my competency in areas that I have wanted to explore but had not had dedicated time to do it. Items like CSS3 animations and transitions, charting and graphics using the SVG standard, testing frameworks such as Mocha and Chai, and the use of Node and the Express framework.

This is a great new phase of my career and one that I will certainly enjoy. Not many get to do what they love and get paid for it, so I feel fortunate.

Creating (Eclipse) Aptana JavaScript Content Assist Files (sdocml)

Tags

, , , , ,

I have a been a long time user of Aptana (I use the Eclipse plugin; there is also a self-contained Aptana IDE which wraps eclipse), and find it to be a very good (free) IDE for web development (JavaScript, CSS, HTML). JavaScript editors today don’t seem to be as good or advanced as other languages like Java, C# or just about any strongly-typed language and thus good content assist is hard to get.  Content assist for me is a big feature specially when working with a large code bases or many libraries or frameworks. Yes, you can have a second page open with the API documentation visible, but having as you type your code is a big productivity tool.

Aptana, for the most part, seems to do (IMO) a good job at it by picking up methods and variables available in the scope/context as well as suggestion for browser globals and the JavaScript language. One the more powerful features, however, is the ability to drop in documentation files that can help with content assist if the source is not available. Kind of an extension point, so that we are not limited to only having suggestion come from source files.  A good example is jQuery which Aptana provides support out of the box. The files, written in XML using ScriptDoc 2.0 Specification, allow library writers to provide these along with their work and thus automatically enable content assist in this popular editor. Here is a sample file:

<?xml version="1.0"?>
<javascript>
    <class type="Widget">
        <description>Widget base class. Provides a foundation for other more specific widgets.</description>
        <constructors>
            <constructor scope="instance">
                <parameters></parameters>
                <return-types>
                    <return-type type="Widget"/>
                </return-types>
            </constructor>
        </constructors>
        <methods>
            <method name="init" scope="instance">
                <description>Initializes the widget.</description>
                <parameters>
                    <parameter name="options" type="Object" usage="optional"></parameter>
                </parameters>
            </method>
            <method name="onReady" scope="instance">
                <description>Callback function called when widget is ready.</description>
                <parameters></parameters>
            </method>
            <method name="extend" scope="instance">
                <description>Extends this class and returns a new class constructor</description>
                <parameters></parameters>
                <return-types>
                    <return-type type="Widget"/>
                </return-types>
            </method>
        </methods>
    </class>
</javascript>

For a long time I have been generating these SDOCML files and they work just fine for global and static members, but I was not able to trigger content assist for class instances. With the increasingly popular use of classes and modules using the AMD patterns in JavaScript projects, having this work as expected in these cases would be a huge plus.
The need to make these work became even more important to me professionally in the last month or so as a took on a new role as a GUI Web Developer and started working with a large internal framework.  If I am going to make a different quickly in this project, I needed my tools (editor) to cooperate.

So what is the problem? Here is a code sample

var wdg;

/** @type {Widget} */
wdg = new Widget();

Typing wdg. should suggest the three methods you see above in the SDOCML file (init, onReady and extend).  Instead I get the following:

aptana-no-content-assist

In the last few days I got a break through after interacting with a developer named Jocki on github (thread here). He has a patched version of Aptana that adds a few improvements to jQuery’s content assist. In that discussion, he was kind enough to suggested that I add the <type-maps> declaration to my file and map the Class Names to the internal way Aptana handles the looks ups (which they are looking to fix, according to this – I think).

With that tip, I changed my SDOCML file to this:


<?xml version="1.0"?>
<javascript>
    <class type="Widget">
        <description>Widget base class. Provides a foundation for other more specific widgets.</description>
        <constructors>
            <constructor scope="instance">
                <parameters></parameters>
                <return-types>
                    <return-type type="Widget"/>
                </return-types>
            </constructor>
        </constructors>
        <methods>
            <method name="init" scope="instance">
                <description>Initializes the widget.</description>
                <parameters>
                    <parameter name="options" type="Object" usage="optional"></parameter>
                </parameters>
            </method>
            <method name="onReady" scope="instance">
                <description>Callback function called when widget is ready.</description>
                <parameters></parameters>
            </method>
            <method name="extend" scope="instance">
                <description>Extends this class and returns a new class constructor</description>
                <parameters></parameters>
                <return-types>
                    <return-type type="Widget"/>
                </return-types>
            </method>
        </methods>
    </class>
    <type-maps>
          <type-map source-type="Widget" destination-type="Function&lt;Widget&gt;"/>
    </type-maps>
</javascript>

And voila! Content assist in the editor.

aptana-content-assist

I found that the type-maps needed to be added to the end of the file or after the class definitions. Placing it at the top of the file did not seem to work for me.

In my use of the @type declaration I have found only 1 issue: if you use it together on the same line as the ‘var’ declaration, content assist does not seem to display. Example:


var /** @type {Widget} */ wdg = new Widget();

Aside from that, which is a small tweak to how you code, the use of these help files along with @type declarations work pretty well, including placing these next to Function input parameters:


function doSomething ( /** @type {Widget} */ wdg) {

}

aptana-content-assist-function-param

 

Generating SDOCML files

These files can be created manually but for large projects, that’s just not feasible. The ideal would be to run a tool against the code and generate such file. I have always annotated my code with jsdoc tags, which makes it a fairly easy task to now just generate the content assist file by using template. And that’s what I created: a jsdoc3 template that outputs a SDOCML file from source files annotated with jsdoc tags. I’ll save this topic and the introduction/availability of that template for a subsequent post.

 

 

How To Get Information About a SharePoint List Item Using its URL

Tags

, , , , ,

I recently had the need to get information about an Document Library item based on that item’s URL. Particularly I was looking to know the item’s ID and the List Name/ID that it belong to so that could the use the GetListItems operation of the Lists web services (using SOAP interface). All I had was the URL, and thus my first inclination was to parse it and get the information. Here is a sample of what my URL looked like:

https://mysite/sites/PT/Shared Documents/TestFolder/sub1/sub2

I could remove the site’s Web URL from the it, and then work with the remainder of the URL string and the output of the GetListCollection operation of the Site Data web service to match it up to a list. The logic could get complicated with the amount of parsing that is needed with this approach and the fact that SharePoint allows you to have URL name components that are different from the List name (in my URL above, ‘Shared Documents’ actually maps to a Document Library named ‘Documents’).

There had to be a better way!

I have worked with allot of API’s, both in consumption and even in managing software releases of (proprietary) products where new API’s where being introduced, which gave me insite into the design of such beasts. I have to say, that SharePoint’s API is one of the most complete and robust that I have seen. Certainly they had already covered this use-case and should have an API for it – Right?

My first stop was over at the excellent SPServices library created by Marc Anderson (@sympmarc). Looking at the documentation, I did not find anything, but remembered that it there is at least one web service operation able to return a Site/Web root URL based on “deeper” URL. Marc uses it in his $().SPServices.SPGetCurrentSite utility. Marc does a tremendous job in wrapping as many API methods as possible, but I don’t think he claims to have full coverage – there are just too many! I have seen him add additional ones over the years that I have been following him and SPServices, specially as folks in lively SPServices forums point out what’s missing. So I kept digging.

In looking at the Microsoft documentation for the Site Data web service, there is in fact an operation in that API that will do exactly what I need – SiteData.GetURLSegments. You give it a URL string to an item, and it returns the List and the Item IDs. I used this method with an Document Library item URL and it worked perfectly (O365, SP2010 and SP2013 front-ends) and SP2007.

I found the operation to work with the following types of items:

  • a List Item
  • a Document Library item
  • and a Document Library Folder

It does not work with List Item’s attachment URLs, nor does it work with a Document Library root url (ex. /yousite/Shared Documents/). I have also found that Document Library URL’s that use the Forms do not work. It needs to be a URL directly to an item in the List.

I went ahead and posted my finding on the SPServices forum, along with the use case, and crated my own utility to use this method. The code below, which is available via this Gist) uses jQuery to make the request and return to the caller a Promise which when resolved will provide not only the XML response but also a javascript object with the parsed output.

Utility to Browse SharePoint Out-of-Box Images for use in Customizations

Tags

, ,

If you do SharePoint front-end UI/UX customizations using HTML and CSS you have probably run across this need: to re-use some of the images already available in the farm in your custom markup or styles sheets. But knowing what is available is not a strait forward process and for a while there I resorted to looking around the out-of-the-box forms see what they displayed and grab the code…

SharePoint has many images (thousands) available. These images are stored in a variety of locations, including /_layouts/images/, /_layouts/1033/images/, /_layouts/15/1033/images/ but does not have any built in way to display what is hosted in these locations.  This is probably not an issue for those that have server level access, since you can browse the physical directories, but I don’t (I do client side customizations using HTML, JavaScript and CSS and often don’t have IT involved) and thus the need for a utility.

I few years ago I had found a page at Bits Of SharePoint Consulting (by Peter Allen – @peterhallen) which did the trick, but a few weeks ago it was not available which caused me some frustration. My most recent need was to find two icons for use in a custom SharePoint Ribbon to represent Next and Previous (data paging) actions.

ribbon-buttons

I had been wanting to create my own reference list of images so that I could remove the dependency on the site referenced above. My goal was to be able to display these images on a customized ASPX page and use it to quickly grab the url path of the desired image. Creating this single ASPX page allows me to drop it into a Document Library of the site I’m customizing and quickly see what’s available.

With a little help from Google and from Marc Andersen (@sympmarc), I collected a list of images and created the reference page. The page allows filtering of images by size – small, medium large – and when an image is clicked, the image’s information is displayed on a static footer area (#1 in screen capture below). In addition, I often find more than one image I like as I browse through the list, so I wanted a way to “remember” an image (#2 in screen capture below) so that I can reference those later (#3 in screen capture below) when I’m done browsing them.

spimage-screencapture

The think that you will realize quickly, when browsing the many images available, is how much duplication there is. I’m going to guess that Microsoft® development teams probably don’t have this type of tool in-house, and thus just keep dumping new images into the folders not realizing the image they ware looking to use may already exist.

I thought about releasing this utility as a one-time GIST, but decide to create a project on github instead to manage this little utility – https://github.com/purtuga/SPImages/. The single aspx page can be downloaded from the ‘utility‘ directory.

Future improvements

As it stands, this utility is serving up the initial needs very well – I have used it now several times and am very happy with version “1.0”. However, there is always room for improvement.

  • I may still be missing some images, specially for SharePoint 2013 – I have found some that are hosted from /_layouts/15/1033/images/, but have not been able to get a list of everything under that directory.
  • I will also be enhancing this utility to provide a way to hover over the sprite images and get the markup for the image of interest – I have a few ideas of how to get that done in a generic way so that it does not have to be done manually for individual images.
  • I may also add a few more filters to the drop-down, like ‘Animated’ since there are not that many images that seem to be animated and perhaps ‘File Types’ icons since SharePoint seems to have a common way to name those (IC<file extension>)
  • It would also be extremely useful to have the ability to search for keywords.  Perhaps I can find a way to have the community help “tag” images, so that a search feature can also be introduced. Tags could be submitted to the project via pull requests to the project’s home on GitHub.

In looking at this list of additional enhancements it does sound ambitious and time consuming, but at the same time it would provide for quite a comprehensive utility… That just goes to show how I always think about building a complete and full feature system – for good or for bad :)  Maybe I’ll just wait to see if it gains interest for others.

JavaScript How To : Deferred Code Execution with jQuery Deferreds

Tags

, , , ,

When building web applications I often need to execute pieces of code only after a certain condition has been met. If you use jQuery, then you are probably aware of the Deferred functionally it provides when working with Ajax calls or animations. But what if your want to use it to check some other condition – like the existence (or disappearance) of a DOM element; or a change to a JavaScript global variable? For this you would need to revert to something else – like the old setInterval – but you loose the chaining ability of the jQuery Deferred class which I love to use.

Take the following use case:

You have a modular application that loads javascript files (modules) asynchronous as it is needed. Those modules, once they are loaded and *ready*, set a variable indicating “done” – for simplicity, lets say it is window.appReady. “Ready” could mean making more asynchronous calls to the server (ie retrieve data to initialize the UI).

What I need is a utility that checks the variable periodically and once it indicates “done”, a code block is executed. The call to this utility looks like this:


$.doWhen({
    when: function(){
        return window.appReady === "ready";
    }
})
.done(function(){ alert("App is ready!!"); })
.fail(function(){ alert("App is not yet ready :("});

The above code keeps checking the window.appReady variable until its value is “ready”, at which point, it will execute the given callback function. The utility has several other input options that can be used to control how often to check the condition and for how long. See below.

I initially came across the need for this utility when I developed a widget plugin that needed to adjust (normalize) element height on that widget. The problem was that the widget could be initialized on hidden (display: none) elements making it impossible to determine the height of the elements. With that, I created this utility to check for when the widget became visible. This utility leverages the jQuery Deferred class so that we can chain multiple code execution blocks and take advantage of the different states.

The code for the utility can found in this gist:

Follow

Get every new post delivered to your Inbox.