Derby.js – The Ready() Function, and Adding Client-Side Scripts to your App

I’ve found a neat feature of derby dealing with the ready() function.

I’ve been creating a derby app, and in my application I need to load up a client-side calendar. With a standard HTML web page this is straightforward thing to do. On the page you wanted the calendar, you would include the client js for the calendar, some code to load it, and that would be that.

Derby introduced some complexity to this relatively simple task.

On my first attempt, I put my scripts in the section of the page that I needed the calendar on. I added a script to load the calendar as well. When I went to the url of the page, it loaded immediately. Success! (I thought).

Then I clicked a link away from my calendar, and then clicked back. No calendar.

What happened? When I loaded the link originally, the page was rendered from the server. The second time, the page was rendered client side. Something wasn’t working with loading the calendar on the client-side render.

You need a place to put your code that guarantees that it will load on the client-side. The app.ready() function is designed to handle this scenario.

What is the purpose of the app.ready() function? From the derby documentation:

Code that responds to user events and model events should be placed within the app.ready() callback. This provides the model object for the client and makes sure that the code is only executed on the client.

This function is called as soon as the Derby app is loaded on the client. Note that any code within this callback is only executed on the client and not on the server.

I’ve bolded the part I think is particularly important. This code is run as soon as the client is loaded. Which means if you have more than a single-page app, using app.ready() to load a feature might not work out.

So what to do? An undocumented feature of Derby – app.on().

What does it do? It allows you to load code AFTER a specific page has loaded. Which is exactly what I’m looking for.

So here’s what I ended up writing in my app.ready():

  app.on('render:calendar', function(ctx) {
    logger.log("rendering calendar client-side...");
    new Timeline("timeline", new Date());
  });

In this example this code will run after rendering the calendar view. On the Calendar page, there is a script block which loads the Timeline function.

After writing this code, I tried my page again. Still no luck. I wasn’t getting the calendar to load on both the client and server load.

On a lark, I moved the block containing my Timeline javascript to my index view, and tried again. Success.

Which makes sense. If you are rendering pages via the client side load, additional resources aren’t going to be loaded. So by putting my script into the index view, it’s unfortunately loaded for all my pages, but at least it’s available for both the client and server side rendering of my cool control.

Advertisements

Derby.js – Starting out with Components; Creating a Twitter Bootstrap Input Component

In working with Twitter Bootstrap Forms, one of my favorite ways to lay out a form is using the Horizontal form layout. The layout requires a bit of css/html to get each of the form elements (the text boxes and what not) to play nicely.

To add form elements to the horizontal form layout, you need the following html structure for each field:

 
<div class="control-group"><!-- additional classes here to change state -->
  <label class="control-label">INPUT_LABEL_TEXT_HERE</label>
  <div class="controls">
    <input type="text" /> <!-- This is the control you want to display -->
    <span class="help-inline">ERROR_OR_INFORMATIONAL_MESSAGE_HERE</span>
  </div>
</div> 

That’s a hefty amount of markup to copy and paste all over your pristine views. Which makes this a great place to use a Component.

So what’s a Component?

A component is basically a derby template you can supply parameters to. Those parameters are supplied in the form of HTML attributes and HTML content.

There are two types of components: application and library. Application components can only be used in a single project. Library components can be re-used across multiple projects.

For my project I’m going to create an application component. Eventually if I need the component on another project I’ll add it to a component library. But that process is more complicated and less documented so I’ll save that for another day.

There are two ways to create an application component:

  • Inline
  • If your component is only being used on a single view, you can add it to the same file as your view.

  • External
  • If your component is going to be used on multiple views, you should create a separate file for your component.

Apparently there are two ways to create a library component as well:

The ui directory contains a component library, which can be used to create custom components for the containing project. These are re-usable templates, scripts, and styles that can be used to create custom HTML tags for use in applications. General purpose component libraries can be created as separate npm modules.

All components run under the scope of the context in which they are called. Which means you can bind model data to your component without having to pass your component any values.

For example:

<h2>All toys:</h2>
  {each toys as :toy} <!-- Alias :toy available to the component -->
    <app:toyStatus> <!-- All application components live in the app namespace -->
  {/}

<toyStatus:>  <!-- this tag says I am a component -->
  <!-- I'm using alias :toy here, defined above -->
  <span>The toy is located at {:toy.location}</span> 

If all of this “Model-Bindy” stuff is foreign to you, check out my post Working with Views, Models, and Bindings.

I don’t like the way you used a scoped alias from your view in your component. What if my component is in another file? What if I want to use a field with a different name? Is there a better way to pass values to a component?

From the derby documentation:

Literal values or variable values can be passed to components. These component attributes are available through “macro” template tags, which have triple curly braces.

What does that look like? Again, from the docs:

<Body:>
  <h1><app:greeting message="Hello"></h1>

<greeting:>
  I was passed this message as an attribute: {{{message}}}

You can also pass html to your component as well. That is a two-part trick: First, write your component with an opening and closing tag. Put the value you want to pass to your component between the tags.

Then, in your component, you use the special triple-curly bracket {{{content}}} macro-tag to reference what you passed in.

For example:

<Body:> 
  <app:fancyButton>
    <b>Click me now!</b>
  </app:fancyButton>

<fancyButton: nonvoid>
  <button class="fancy">
    {{{content}}}
  </button>

But I already knew all that. How do I make a component?

The easiest way is to just add the component to your page, as show in the simple example above. This example is taken from the derby website, and it shows you how to reference a component in a separate file:

shared.html

(This is your component, which is located in your views folder.)

<profile:>
  <div class="profile">...</div>

home.html

(This is the view that will use your component.)

 <!-- This line imports your component into the view -->
<import: src="shared">

<Body:>
  Welcome to the home page
  <!-- include component from an imported namespace -->
  <app:shared:profile>

The <import> tag at the top, used to include your component into your view, can be called with variety of parameters. For more information on the  <import>  tag go to http://derbyjs.com/#importing_templates.

Didn’t you say something about Twitter Bootstrap?

Oh yeah. Got sidetracked there.

As you can see, creating a component is relatively easy. Since I already have all the Twitter Bootstrap markup ready, I might as well create a Twitter Bootstrap Component for Derby.

To do this, all you have to do is figure out what you want to be able to customize.

boot.html

<input:>
{{{#with data}}} 
  <div class="control-group {{cssClass}}">
    <label class="control-label">{{label}}</label>
    <div class="controls">
      <input type="{{type}}" value="{{value}}" />
      <span class="help-inline">{{message}}</span>
    </div>
  </div> 
{{{/}}}

As you can see, I added bindings for {{cssClass}}, {{label}}, {{type}}, {{value}}, and {{message}}.

Why did I use a #with block to set the scope of my object being passed in? There is a bug in the derby code right now (documented here) where you can’t reference an object’s child properties with the triple curly brackets syntax. So {{{data}}} will work, but {{{data.value}}} won’t.

The object being bound to the component:

var data = function(value, label, type) {
	this.label = label;
	this.value = value;
	this.message = "";
	this.cssClass = "";
	this.type = type || "text";
};

And I call it in my view like this:

<app:boot:input data="{:person.firstName}">

Where firstName is an object like data described above.

So, in a just a little bit of markup and code, I have a great reusable component that I can use to style the look and feel of my application without having to copy and paste code everywhere.

I hope this it helps some of the fledging Derby developers out there.

BTW, code samples from this post can be found here.

Derby.js – Integrating Twitter Bootstrap into your Application

As I’ve mentioned in a previous post, I’m a big fan of Twitter Bootstrap.

Lately I’ve been playing been with JavaScript and Derby. I want to integrate bootstrap with the POC site I’m building, and the creators of Derby have already figured out a way to do this.

Step 1: Add a dependency to the derby-ui-boot package, which is a Derby component library based on Twitter Bootstrap.

{ 
....
  "dependencies": {
    "derby": "*",
    "derby-ui-boot": "*",
    "express": "3.0.0beta4",
    "gzippo": ">=0.1.7" 
  },
....
} 

Step 2: Update your project with the downloaded ui-boot code

This is as simple as running
npm update
in your project folder, which will read package.json, and download any missing dependencies (like the derby-ui-boot entry you just added).

Step 3: Add the derby-ui-boot component to your project.

At the top of your application JavaScript (for me, this is the file located at /lib/app/index.js), after your var derby = require("derby"); line, add the following line of code to your file:

var derby = require("derby");
derby.use(require('derby-ui-boot'));

Step 4: Profit!

That should be it for you. When you load your application up, the default twitter bootstrap css and js should have loaded. To correctly style your application, you’ll have to follow the guidelines laid out here and here.

Derby.js – Working with Views, Models, and Bindings

In my previous post about derby, I talked a bit about how to create a model in derby and one rule you need to follow when creating models (the first two path segments should be an object).

I’m creating a test application to help me learn derby here. In the process of doing absolutely everything wrong to start I’ve learned a bit about how Derby binds to models.

Let’s say you’re got some markup like this that you’d like to bind to.

 
      <div> 
        <div> <input type="text" id="firstName" /> </div>
        <div> <input type="text" id="lastName" /> </div>
        <div> <input type="tel"  id="phoneNumber" /> </div> 
        <div> <input type="date" id="birthDate" /> </div>
      </div>

Nothing sexy but you get the idea. You can post this information into a view and everything will show up the way you’d expect it to.

If you want to bind this to a model, such as myApp.stuff.newGuy, changing the code is straight forward.

 
      <div> 
        <div> <input type="text" id="firstName"   
                     value="{myApp.stuff.newGuy.firstName}" /> </div>
        <div> <input type="text" id="lastName"   
                     value="{myApp.stuff.newGuy.lastName}" /> </div>
        <div> <input type="tel"  id="phoneNumber"   
                     value="{myApp.stuff.newGuy.phoneNumber}" /> </div> 
        <div> <input type="date" id="birthDate"   
                     value="{myApp.stuff.newGuy.birthDate}" /> </div>
      </div>

Note that you don’t have to write any js code in your /lib/ folder to create this model. The binding [the {} information in the value attribute] will automatically wire up these fields to the myApp.stuff.newGuy model.

If you want to add some default values to these fields you could accomplish this like so:

  
get('/', function(page, model, params) {
  
  //set some default values for my model
  model.set('myApp.stuff.newGuy', { firstName: 'John', lastName: 'Smith' }); 

  //render my template containing the model above
  page.render();
});

When you browsed to the page you would see John in the firstName input and Smith in the lastName input.

How would you render a similar collection of models? There are a couple of ways. To iterate through a collection of objects, you’ll most likely want to use the #each binding.

 
      {#each myApp.stuff.people}
      <div> 
        <div> <input type="text" value="{.firstName}" /> </div>
        <div> <input type="text" value="{.lastName}" /> </div>
        <div> <input type="tel"  value="{.phoneNumber}" /> </div> 
        <div> <input type="date" value="{.birthDate}" /> </div>
      </div>
      {/}

Several things to note here. First, you have to remove the id’s from the html inputs you are binding to. Each input needs to have a unique id. If you omit the id field from the markup, derby will generate a unique id for you. Otherwise you’ll be repeating the same id over and over again (and get strange behaviour as a result).

Second, in an #each binding you don’t use the full path to the model field you want to bind to (e.g. {myApp.stuff.people.firstName}), just the field with a dot prepended. (e.g. {.firstName}).

Note that the dot is very important. If you just put {firstName} as your binding, because of the automatic model creation we noticed above, you will bind to a model called {firstName} for every item in the myApp.stuff.people collection. This will show itself by the very annoying behaviour of every edit being mirrored in every row (since every row is binding to the same model).

Another way to do binding with #each is by using an alias. The documentation of creating an alias:

Aliases to a specific scope may be defined, enabling relative model path references within nested sections. Aliases begin with a colon (:), and can be defined at the end of a section tag with the as keyword.

What would this look like?

 
      {#each myApp.stuff.people as :person}
      <div> 
        <div> <input type="text" value="{:person.firstName}" /> </div>
        <div> <input type="text" value="{:person.lastName}" /> </div>
        <div> <input type="tel"  value="{:person.phoneNumber}" /> </div> 
        <div> <input type="date" value="{:person.birthDate}" /> </div>
      </div>
      {/}

Note that when you declare your alias with your each statement (as :person) you have to keep the colon for your subsequent bindings ({:person.firstName})

HTML5 ‘formaction’ attribute – An easy Modernizr test

EDIT NOTE: This no longer needs to be done outside of Modernizr. This was added to the Modernizr package about a month ago.
Link to issue

I’ve been writing some Html Forms, and in playing with submit buttons came across an interesting attribute in the HTML 5 specs: formaction.

The definition, from HTML Living Standard Doc

The action and formaction content attributes, if specified, must have a value that is a valid non-empty URL potentially surrounded by spaces.

The action of an element is the value of the element’s formaction attribute, if the element is a submit button and has such an attribute, or the value of its form owner’s action attribute, if it has one, or else the empty string.

What does that mean? It means you can have a form on your page, and supply the formaction attribute to various buttons, and each button will post the same form to a different URL!

Pretty neat, and has global acceptance in all browsers but one; Internet Explorer. Whoops.

I really want to use this functionality, so I’ll come up with a shim to replace the functionality that IE is missing. For now, the only part of this problem I’ve solved is how to detect whether or not your browser supports this feature, via Modernizr

// input[formaction] attribute
// When used on an <input type='submit'>, 
// this attribute signifies that the form containing 
// the input should post to the URL contained in the attribute 
// rather than the URL defined in the form's 'action' attribute. 
// By Matt Blair - 

Modernizr.addTest('inputformaction', 'formAction' in document.createElement('input'));

Derby.js – Playing with Models

Been playing around with Derby in my spare time. The idea behind the platform is excellent – using node and express, you write one set of code, and that code automatically syncs data between browsers, servers, and a database.

So far, Derby is still very raw, and the documentation, while comprehensive, puts important information about the same topic in various places. I’ve culled the following eight lines of documentation of defining models from the documents:

Racer Paths

Racer paths are translated into database collections and documents using a natural mapping:

collection.documentId.document

All synced paths (anything that doesn’t start with an underscore) must follow this convention.

In other words, all model data stored at the first two path segments should be an object and not a string, number, or other primitive type.

Private paths

Paths that contain a segment starting with an underscore (e.g. _showFooter or flowers.10._hovered) have a special meaning.

These paths are considered “private,” and they are not synced back to the server or to other clients.

Private paths are frequently used with references and for rendering purposes.

Now, this information is VERY useful if you’re trying out the model system for the first time. The most important line (at least for my initial playing around), was this one:

In other words, all model data stored at the first two path segments should be an object and not a string, number, or other primitive type.

What this means: if, in creating your first model, you trying something like this:

model.set('people', []);

Eventually you will get an error. However,

model.set('myApp.containers.people', []);

will work just fine.

A follow up to this post is here.

Why use Twitter Bootstrap?

I’m a huge fan of Twitter Bootstrap, the simple and flexible CSS, HTML, and JavaScript user interface framework.

And what’s not to like? Out of the box, you’ll get:

  1. Cross-Platform Support
  2. IE 7 to IPhone and everything in between (sorry IE6)

  3. 12-Column Grid
  4. A good grid system takes most of the pain out of laying out your site. Getting labels, inputs, and other pieces of your ui to layout consistently and gracefully across different browsers at different resolutions can be one of the most painful parts of web development. Save yourself the work of trying to figure this stuff out on your own. The twitter kids have it under control.

  5. Responsive design
  6. One of my favorite parts. If you use the css/html correctly, as the size of your browser changes (you can see this just by resizing the browser on your desktop), the layout adapts to display the information in a consistent manner as the screen size drops. Want to hide a left nav bar if your site is viewed on a tablet? No problem. Want to hide the menu bar at the top of your site if viewed on a phone? Too easy.

  7. Baked In Best Practices
  8. Basically, if you want to get anything out of Bootstrap, you’ll have to adhere to their best practices. Following someone’s best practices is better than just hacking away at your CSS.

  9. jQuery Plugins
  10. Great interactive components, built on everyone’s favorite JS framework, that look and interactive fantastically with the rest of Bootstrap.

  11. LESS Infrastructure
  12. I am a huge proponent of LESS/SASS/Stylus etc. If you’ve never used these type of CSS frameworks, they allow you to do all sort of great software developy things with your CSS. Like set variables in one place for all the colors and sizes used by your app. Or re-use common styles in multiple places without copy and paste. Or only display certain styles if certain conditions are met.

So what are you waiting for? Check out some of the docs here and here to get started.