Entries Tagged as 'Web development'

Introducing Sparker: A Codebase Library Management Tool Showcasing AngularJS, Protractor, and Grunt Techniques

AngularJS , Grunt , JavaScript , Web development No Comments »

Sometimes projects take on a life of their own, and you end up with something unexpected.

I set out to create an template for CRUD-focused single page AngularJS web applications, something I and perhaps my colleagues could use as a foundation for writing new applications.  But under the momentum of self-applied scope creep, what I ended up creating was a Grunt-powered codebase library management tool, with my original template concept as the first codebase of potentially multiple foundational codebases.

Read more...

Using Grunt to Concatenate Only the JavaScript/CSS Files Used in Index.html

Grunt , JavaScript , Web development 10 Comments »

One of the most common uses of the Grunt task runner is to build a deployment package out of your development code for your website or web application, and part of that build process is usually a task that concatenates the CSS and JavaScript files into singular (or at least fewer) files for optimal download.

The grunt-contrib-concat Grunt plugin allows you to configure a concatenation task to target individual files or entire directories, like so:


concat: {
            js: {
                src: [ 'dev/jquery/jquery.js', 'dev/angular/services/*.js', 'dev/angular/directives/*.js' ],
                dest: '../build/combined.js',
                options: {
                    separator: ';'
                }
            },
        }

The only drawback is that you have to update the task's "src" property as you add or remove CSS and JavaScript assets from your web application.

As I was playing around with Grunt on a personal project, I came to wonder: could I create a Grunt task or set of tasks that could figure out which files to concatenate based on the <link> and <script> tags in my code?  Here's what I came up with.

Read more...

Quick AngularJS Tip: Relating User Input Data to Metadata

AngularJS , JavaScript , Web development 1 Comment »

I started learning AngularJS a few weeks back because I thought it would work well for an internal tool I was building (more on that in a later post).

Many AngularJS examples, including those in the current AngularJS tutorial (like this one), illustrate how to use the ng-repeat and ng-options directives using a typical Javascript array of objects.  So given such an array in the model:

$scope.plans= [
  {"name": "Basic", "cost": "$250.00"},
  {"name": "Deluxe","cost": "$325.00"},
  {"name": "Premium","cost": "$335.00"}    	
];

...you can output a list of the data like so:

<ul ng-repeat="plan in plans">
  <li>
    {{plan.name}}: {{plan.cost}}
  </li>
</ul>

But, as noted in the AngularJS API, you can also use ng-repeat and ng-options to loop through a set of properties/keys in an object, and that works even if each property references another object.  So you can accomplish the same thing with this model object:

$scope.plans= {
  "Basic": {"cost": "$250.00"},
  "Deluxe": {"cost":"$325.00"},
  "Premium": {"cost": "$335.00"}    	
};

...and this HTML:

<ul ng-repeat="(planKey,planObject) in plans">
  <li>
    {{planKey}}: {{planObject.cost}}
  </li>
</ul>

The advantage to using the latter technique comes into play when you want to relate something in the part of the model you want to preserve / process with a part of the model that provides metadata.

Taking the above examples a step further, say you wanted to create a short conference registration form. The user has to select a conference package, and you want to provide information about each package (what it entails and the cost) but you don't want that information to be part of the form submission. You can do this by having the user's conference selection pull the related data from the plan metadata.

So with the following AngularJS controller function:

function ConfReg($scope, $http) {
  $scope.reg= {};
  $scope.reg.plan= "Basic";
  
  $scope.plans= {
    "Basic": {
      "description": "Access to all first-run conference sessions on Thursday and Friday.",
      "cost": "$250.00"
    },
    "Deluxe": {
      "description": "Access to all first-run conference sessions on Thursday and Friday, access to repeat sessions on Saturday.  Complimentary breakfast included all three days.",
      "cost": "$325.00"
    },
    "Premium": {
      "description": "Access to all first-run conference sessions on Thursday and Friday, access to repeat sessions on Saturday.  Complimentary breakfast included all three days.  Also includes conference t-shirt and kazoo.",
      "cost": "$335.00"
    }

  };
}

...and the corresponding HTML:

<h3>Conference Registration</h3>
  <form name="regForm" id="regForm" ng-controller="ConfReg">
    <p>
      <label>First Name:</label>
      <input type="text" name="firstName" id="firstName" ng-model="reg.firstName" />
    </p>
			
    <p>
      <label class="control-label" for="lastName" id="lblLastName">Last Name:</label>   
      <input type="text" name="lastName" id="lastName" ng-model="reg.lastName" />
    </p>
				
    <p>
      <label class="control-label" for="plan" id="lblPlan">Conference plan:</label>   
      <select name="plan" id="plan" ng-model="reg.plan" ng-options="planName as planName for (planName,planObject) in plans"></select>
    </p>
    <div>
      <p>{{plans[reg.plan].description}}</p>
      <strong>Price:</strong> {{plans[reg.plan].cost}}
    </div>
				
</form>

...The user's selection of plan determines which plan object data is pulled from the "plans" part of the model for display in that div block, yet the data sent as the form submission (the "reg" object) only includes the plan name.

A (nicer) demo of this example can be seen here: http://www.thoughtdelimited.org/thoughts/demos/angularMetadata.

Some Words About the New jQuery Plugins Registry

JavaScript , jQuery , Web development No Comments »

In case you missed it, last week the jQuery team announced the launch of the long-awaited jQuery Plugin Registry (http://plugins.jquery.com/).  This new site is designed to address the issues that were present in the old jQuery plugins site and make it easier for plugin authors to share their creations via an authoritative listing.

I like what they ended up doing with the registry.  Instead of hosting copies of the plugins, it leverages GitHub.  Plugin authors put their plugins up on GitHub, add a manifest JSON file to their project that provides descriptive metadata about the plugin, and then add a webhook for the registry to the GitHub project (all of these steps are well-documented on the registry site).  Once all that is set up, every time someone creates a new GitHub tag for the plugin and pushes it up to the repo, GitHub will notify the plugin registry of the change and the registry will be automatically updated.  In other words, updating the project on GitHub updates the plugin registry as well.

Finally having a robust centralized, official listing of jQuery plugins is really going to help the plugin ecosystem.  It'll hopefully give lesser-known plugin authors more exposure and give plugin users a central place to search for plugins that returns results with quality, up-to-date information.

I've already added my recently updated dirtyFields plugin to the registry.  Not sure if I'll add my older, simpler plugin for counting characters/words in a textarea; I'll have to look and see what's already out there in that regard to see if my implementation fills a niche need for that sort of thing.

Adding a Time Selector to the jQuery UI Datepicker Widget

jQuery , Web development 6 Comments »

One of the functional requirements for the voter registration application I blogged about recently was that the application should not allow further registrations between the registration deadline (October 16 at 9pm) and a date after the election specified by the state Board of Elections.  For the initial run of the application, I simply hard-coded the deadline and restart date into the application logic, knowing full well I couldn't leave it that way unless I wanted to personally change the code year after year....which I don't.

So this week I set out to write a tool within the administrative interface of the application that would allow a non-programmer to update the deadline and restart date every year.  The jQuery UI Datepicker widget is my tool of choice when it comes to having users enter or edit a date, but I've used a few different approaches to having users enter a time of day.  This time around, I decided to see I if could find something comparable to the Datepicker widget for setting the time.

What I found was a rather sweet plugin called the Timepicker Addon that adds a set of time controls to the jQuery UI Datepicker.  If you customize your jQuery UI download to include both the Slider and Datepicker widgets, you can present the time controls as sliders, like so (without the Slider widget, you get select boxes):

Example of time picker

The plugin comes with a number of configuration settings so you can do things like adjust the time increments, change how the time is displayed, and allow the user to denote the time zone associated with the time value.  Once I had the plugin configured the way I wanted, I simply had to write some code to validate the date and time string submitted from the form field, and I was done.  Very cool.