David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞. http://davidwalsh.name Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞. 2012-12-19T17:56:03Z hourly 1 2000-01-01T12:00+00:00 Introduction to dcl http://davidwalsh.name/intro-dcl 2012-12-19T17:56:03Z eugenelazutkin I’m incredibly honored to have Eugene Lazutkin author for David Walsh Blog. Eugene has written much of the vector graphic code for the Dojo Toolkit’s dojox/gfx (and subsequent charting and drawing resources) library, a library I consider to be mind-blowingly awesome. Eugene chose to write about dcl, an ultra-flexible, tiny OOP JS library. dcl is [...]

Read the full article at: Introduction to dcl

Hosted by Media Temple, domain from Name.com.

I’m incredibly honored to have Eugene Lazutkin author for David Walsh Blog. Eugene has written much of the vector graphic code for the Dojo Toolkit’s dojox/gfx (and subsequent charting and drawing resources) library, a library I consider to be mind-blowingly awesome. Eugene chose to write about dcl, an ultra-flexible, tiny OOP JS library.

dcl is a minimalistic yet complete JavaScript package for node.js and modern browsers. It implements OOP with mixins + AOP at both “class” and object level, and works in strict and non-strict modes.

The simplest way to learn something is to dive right in. Let’s implement a simple widget based on reactive templating: when we change parameters of a widget, they are immeditely reflected in a web page.

Assuming that we run our code using AMD format in browser, our “code shell” will look like that:

require(
  ["dcl", "dcl/bases/Mixer", "dcl/mixins/Cleanup", "dcl/advices/memoize"],
  function(dcl, Mixer, Cleanup, memoize){
    // our code goes here
  }
);

As the first step let’s code our data model:

var Data = dcl(Mixer, {
  declaredClass: "Data",
  updateData: function(data){
    dcl.mix(this, data);
  }
});

We derived our class using single inheritance from Mixer, which comes with dcl. Mixer is a very simple base. All it does is it copies properties of the first constructor argument to an instance.

Obviously in this simple example we could just call updateData() from our constructor, but let’s assume that a constructor and an updater can do (slightly) different things and we want to keep them separately.

declaredClass is completely optional, yet recommended to be specified (any unique human-readable name is fine), because it is used by debugging helpers included with `dcl`.

Now let’s code our nano-sized template engine, which substitutes strings like this: ${abc} with properties taken directly from an instance (this.abc in this case). Something like that:

var Template = dcl(null, {
  declaredClass: "Template",
  render: function(templateName){
    var self = this;
    return this[templateName].replace(/\$\{([^\}]+)\}/g, function(_, prop){
      return self[prop];
    });
  }
});

We specify what template to use by name, which is a property name on an object instance, and it fills out a template string using properties specified on an object.

This is another demonstration of single inheritance: our Template is based on a plain vanilla Object, like any JavaScript’s object, which is indicated by using null as a base.

What else do we need? We need a way to manage our DOM node:

var Node = dcl([Mixer, Cleanup], {
  show: function(text){
    if(this.node){
      this.node.innerHTML = text;
    }
  },
  destroy: function(){
    if(this.node){
      this.node.innerHTML = "";
    }
  }
});

The code above provides a way to show some HTML, and clears out its presentation when we destroy() a widget.

It uses two bases: already mentioned Mixer is used to get a property in during initialization (node in this case), and Cleanup, which again comes with dcl. The latter chains all destroy() methods together and provides a simple foundation for clean up management, so all resources can be properly disposed of.

What we did up to this point is we came up with very small manageable orthogonal components, which reflect different sides of our widget, and can be combined together in different configurations. Let’s put them all together now:

var NameWidget0 = dcl([Data, Template, Node], {
  declaredClass: "NameWidget0",
  template: "Hello, ${firstName} ${lastName}!"
});

var x = new NameWidget0({
  node:      document.getElementById("name"),
  firstName: "Bob",
  lastName:  "Smith"
});

x.show(x.render("template")); // Hello, Bob Smith!
x.updateData({firstName: "Jill"});
x.show(x.render("template")); // Hello, Jill Smith!

It works, but it is not very coherent, and way too verbose. Don’t worry, we will fix it soon.

Some readers probably noticed that we have three bases now: Data, Template, and Node, and two of them (Data, and Node) are based on Mixer. How does it work? It works fine, because underneath dcl uses C3 superclass linearization algorithm (the same one used by Python), which removes duplicates, and sorts bases to ensure that their requested order is correct. In this case a single copy of Mixin should go before both Data and Node. Read more on that topic in dcl() documentation.

Now let’s address deficiencies of our implementation #0:

  • As soon as a widget is constructed, we should show text.
  • As soon as data is updated, we should show text.

Both requirements are simple and seem to call for good old-fashioned supercalls:

var NameWidget1 = dcl([Data, Template, Node], {
  declaredClass: "NameWidget1",
  template: "Hello, ${firstName} ${lastName}!",
  constructor: function(){
    this.showData();
  },
  updateData: dcl.superCall(function(sup){
    return function(){
      sup.apply(this, arguments);
      this.showData();
    };
  }),
  showData: function(){
    var text = this.render("template");
    this.show(text);
  }
});

var x = new NameWidget1({
  node:      document.getElementById("name"),
  firstName: "Bob",
  lastName:  "Smith"
});
// Hello, Bob Smith!

x.updateData({firstName: "Jill"}); // Hello, Jill Smith!

Much better!

Let’s take a look at two new things: constructor and a supercall. Both are supposed to be supercalls, yet look differently. For example, constructor doesn’t call its super method. Why? Because dcl chains constructors automatically.

updateData() is straightforward: it calls a super first, then a method to update a visual. But it is declared using a double function pattern. Why? For two reasons: run-time efficience, and ease of debugging. Read all about it in dcl.superCall() documentation, and Supercalls in JS.

While this implementation looks fine, it is far from “fine”. Let’s be smart and look forward: in real life our implementation will be modified and augmented by generations of developers. Some will try to build on top of it.

  • Our call to showData() in construct is not going to be the last code executed, as we expected. Constructors of derived classes will be called after it.
  • updateData() will be overwritten, and some programmers may forget to call a super. Again, they may update data in their code after our code called showData() resulting in stale data shown.

Obviously we can write lengthy comments documenting our “implementation decisions”, and suggesting future programmers ways to do it right, but who reads docs and comments especially when writing “industrial” code in a crunch time?

It would be nice to solve those problems in a clean elegant way. Is it even possible? Of course. That’s why we have AOP.

Let’s rewrite our attempt #1:

var NameWidget2 = dcl([Data, Template, Node], {
  declaredClass: "NameWidget2",
  template: "Hello, ${firstName} ${lastName}!",
  constructor: dcl.after(function(){
    this.showData();
  }),
  updateData: dcl.after(function(){
    this.showData();
  }),
  showData: function(){
    var text = this.render("template");
    this.show(text);
  }
});

var x = new NameWidget2({
  node:      document.getElementById("name"),
  firstName: "Bob",
  lastName:  "Smith"
});
// Hello, Bob Smith!

x.updateData({firstName: "Jill"}); // Hello, Jill Smith!

Not only we got a (slightly) smaller code, now we are guaranteed, that showData() is called after all possible constructors, and after every invokation of updateData(), which can be completely replaced with code that may use supercalls. We don’t really care — we just specified code, which will be executed *after* whatever was put there by other programmers.

Now imagine that our user wants to click on a name, and get a pop-up with more detailed information, e.g., an HR record of that person. It would make sense to keep the information in one place, yet render it differently. And we already have a provision for that: we can add another template property, and call render() with its name:

var PersonWidget1 = dcl(NameWidget2, {
  declaredClass: "PersonWidget1",
  detailedTemplate: "..."
});

var x = new PersonWidget1({
  node:      document.getElementById("name"),
  firstName: "Bob",
  lastName:  "Smith",
  position:  "Programmer",
  hired:     new Date(2012, 0, 1) // 1/1/2012
});
// Hello, Bob Smith!

var detailed = x.render("detailedTemplate");

In the example above I skipped the definition of a detailed template for brevity. But you can see that we can add more information about person, and we can define different templates when a need arises.

Imagine that we profiled our new implementation and it turned out that we call render() method directly and indirectly very frequently, and it introduces some measurable delays. We can pre-render a template eagerly on every data update, yet it sounds like a lot of work for several complex templates, and some of them are not even going to be used. Better solution is to implement some kind of lazy caching: we will invalidate cache on every update, yet we will build a string only when requested.

Obviously such changes involve both Data and Template. Or it can be done downstream in NameWidget or PersonWidget. Now look above and please refrain from doing those changes: so far we tried to keep our “classes” orthogonal, and caching is clearly an orthogonal business.

dcl already provides a simple solution: memoize advice. Let’s use it in our example:

var PersonWidget2 = dcl(NameWidget2, {
  declaredClass: "PersonWidget2",
  detailedTemplate: "...",
  // memoization section:
  render:     dcl.advise(memoize.advice("render")),
  updateData: dcl.advise(memoize.guard ("render"))
});

With these two lines added our render() result is cached for every first parameter value (“template” or “detailedTemplate” in our case), and the cache will be invalidated every time we call updateData().

In this article we presented dcl package. If you plan to use it in your Node.js project install it like this:

npm install dcl

For your browser-based projects I suggest to use volo.js:

volo install uhop/dcl

The code is an open source on github.com/uhop/dcl under New BSD and AFL v2 licenses.

This article didn’t cover a lot of other things provided by dcl:

  • Avoid the double function pattern in your legacy projects using inherited() supercalls.
  • Use AOP on object-level — add and remove advices dynamically in any order.
  • Specify “before” and “after” automatic chaining for any method.
  • Use debug helpers that come with dcl.
  • Leverage a small library of canned advices and mixins provided by dcl.

If you want to learn more about it, or just curious, you can find a lot of information in the documentation.

Happy DRY coding!

Read the full article at: Introduction to dcl

Hosted by Media Temple, domain from Name.com.

]>
CSS calc http://davidwalsh.name/css-calc 2012-12-17T16:40:54Z David Walsh CSS is a complete conundrum; we all appreciate CSS because of its simplicity but always yearn for the language to do just a bit more. CSS has evolved to accommodate placeholders, animations, and even click events. One problem we always thought we’d have with CSS, however, was its static nature; i.e. there’s really no logic, [...]

Read the full article at: CSS calc

Hosted by Media Temple, domain from Name.com.

CSS is a complete conundrum; we all appreciate CSS because of its simplicity but always yearn for the language to do just a bit more. CSS has evolved to accommodate placeholders, animations, and even click events. One problem we always thought we’d have with CSS, however, was its static nature; i.e. there’s really no logic, per se. The CSS calc routine bucks that trend, providing developers an ounce of programming ability within CSS.

The CSS

The calc routine is especially useful when calculating relative widths. Calculations can be additions, subtractions, multiplications, and divisions. Have a look:

/* basic calc */
.simpleBlock {
	width: calc(100% - 100px);
}

/* calc in calc */
.complexBlock {
	width: calc(100% - 50% / 3);
	padding: 5px calc(3% - 2px);
	margin-left: calc(10% + 10px);
}

WebKit and Opera currently require a browser prefix for calc(). Be sure to use whitespace around operators so that they aren’t construed as positive and negative notations.

CSS calc is another example of CSS taking over the role of JavaScript in layout, and I think it’s a great thing. As we move more toward responsive design, calc allows us to use percentages for overall block widths, with just a touch of pixel help for some of its components. Have you used calc for your apps? Share how you used calc!

Read the full article at: CSS calc

Hosted by Media Temple, domain from Name.com.

]>
Placeholders and Overflow http://davidwalsh.name/placeholder-overflow 2012-12-13T22:56:29Z David Walsh Oftentimes our search boxes and other form fields get drastically shortened on mobile devices.  Unfortunately in some circumstances the INPUT element’s placeholder text doesn’t fit within the length of the element, thus displaying an ugly “cut off.”  To prevent this ugly display, you can use CSS placeholder styling and text-overflow: ellipsis! input[placeholder] { text-overflow: ellipsis; [...]

Read the full article at: Placeholders and Overflow

Hosted by Media Temple, domain from Name.com.

Oftentimes our search boxes and other form fields get drastically shortened on mobile devices.  Unfortunately in some circumstances the INPUT element’s placeholder text doesn’t fit within the length of the element, thus displaying an ugly “cut off.”  To prevent this ugly display, you can use CSS placeholder styling and text-overflow: ellipsis!

input[placeholder] { text-overflow: ellipsis; }
::-moz-placeholder { text-overflow: ellipsis; } /* firefox 19+ */
input:-moz-placeholder { text-overflow: ellipsis; }

Most developers are unaware of each of the properties and even fewer are aware that they are so perfectly complimentary!

Read the full article at: Placeholders and Overflow

Hosted by Media Temple, domain from Name.com.

]>
pointer Media Query http://davidwalsh.name/pointer-media-query 2012-12-11T18:37:19Z David Walsh This media query has not yet been implemented and is currently only a proposed spec. I’ve written this post to raise awareness of it and get general thoughts about it. As more devices emerge and differences in device interaction are implemented, the more important good CSS code will become.  In order to write good CSS, [...]

Read the full article at: pointer Media Query

Hosted by Media Temple, domain from Name.com.

This media query has not yet been implemented and is currently only a proposed spec. I’ve written this post to raise awareness of it and get general thoughts about it.

As more devices emerge and differences in device interaction are implemented, the more important good CSS code will become.  In order to write good CSS, we need some indicator about device capabilities.  We’ve used CSS media queries thus far, with checks for max-width and pixel ratios.  One new proposed CSS media query is the pointer media query;  the pointer media query provides information about how accurate the device pointer is (if present).

The pointer media query has three values:

  • none – device has no pointer
  • coarse – pointer has limited accuracy
  • fine – pointer has high level of accuracy

A fine pointer would be a mouse or a stylus-based touch screen, while a coarse pointer would be a finger-based touch screen, like an iPad, iPhone, or other tablet.  The example provided within the spec shows enlarging checkboxes and radio buttons on coarse-pointered devices:

/* Make radio buttons and check boxes larger if we have an inaccurate pointing device */
@media (pointer:coarse) {
	input[type="checkbox"], input[type="radio"] {
		min-width:30px;
		min-height:40px;
		background:transparent;
	}
}

I envision this API being used to enlarge navigation items and other prominent links when the pointer is coarse.  What would you do with the pointer media query?

Read the full article at: pointer Media Query

Hosted by Media Temple, domain from Name.com.

]>
How to Create a Twitter Card http://davidwalsh.name/twitter-cards 2012-12-10T15:19:47Z David Walsh One of my favorite social APIs was the Open Graph API adopted by Facebook.  Adding just a few META tags to each page allowed links to my article to be styled and presented the way I wanted them to, giving me a bit of control over how my content is presented on Facebook.  Twitter’s new [...]

Read the full article at: How to Create a Twitter Card

Hosted by Media Temple, domain from Name.com.

One of my favorite social APIs was the Open Graph API adopted by Facebook.  Adding just a few META tags to each page allowed links to my article to be styled and presented the way I wanted them to, giving me a bit of control over how my content is presented on Facebook.  Twitter’s new Twitter Cards API allows for the same idea:  add META tags to your pages to allow links to your site to be more informational when tweeted.  Implementing Twitter Card META tags on your site takes five minutes, applying for approval from Twitter takes another five minutes, and from that point forward, your content is presented much more professionally.  Let’s get started!

Twitter Card META Tags

There are three types of Twitter Cards:  summary, photo, and video.  The summary Twitter Card is for articles and text-based content, while photo and video cards are self-explanatory  (YouTube uses the video card type, for example).  There are a few META tags used for all card types, then a few more that are card-type-specific.  All META tag name attributes are prefixed with twitter:.

Generic META Tags

META tags you would use in all card cases include:

  • twitter:card – The type of card to be created: summary, photo, or video.
  • twitter:url – The URL that should be used for the card.  This will likely be the same URL as the page’s canonical link.
  • twitter:title – The title as it should display in the Twitter Card.
  • twitter:description –  A 200 character summary of the content at the given URL.
  • twitter:image – A representative image URL for the content.  In many cases, simply providing your logo’s URL will be just fine.

Each of these items get their own META tag, so  the Twitter Card META tags for this page would look like:

<meta name="twitter:card" content="summary">
<meta name="twitter:url" content="http://davidwalsh.name/twitter-cards">
<meta name="twitter:title" content="How to Create a Twitter Card">
<meta name="twitter:description" content="Twitter's new Twitter Cards API allows developers to add META tags to their website, and Twitter will build card content from links to a given site.">
<meta name="twitter:image" content="http://davidwalsh.name/demo/openGraphLogo.png">

Twitter also provides attribution META tags for content, providing an opportunity for authors to get credit within the TwitterCard:

  • twitter:site - The Twitter username used by the given site including the ‘@’
  • twitter:creator – The Twitter username of the individual author of the content

I use the same handle for the site and author, though I could use my @davidwalsh account for the creator if I wanted:

<meta name="twitter:site" content="@davidwalshblog">
<meta name="twitter:creator" content="@davidwalshblog">

These are the basic META tags you’ll want to use whenever creating Twitter Cards.  Let’s have a look at the tags specific to image and video cards!

Image and Video META Tags

Media-specific cards require a bit more information about the media itself, so for image and video cards, these additional tags are useful:

  • twitter:image:width – The width of the image
  • twitter:image:height – The height of the image
  • twitter:player – URL to the IFRAME’d player, must be HTTPS
  • twitter:player:width – The width of the player IFRAME
  • twitter:player:height – The height of the player IFRAME
  • twitter:player:stream – The URL to stream as video
  • twitter:player:stream:content_type – The content type of the stream

Twitter video cards are much more involved than the other card types, but well worth configuring so that users can watch their videos within their Twitter app.  Sample tags could look like:

<meta name="twitter:image:width" content="600">
<meta name="twitter:image:height" content="600">

<meta name="twitter:player" content="https://davidwalsh.name/video-embed/12345">
<meta name="twitter:player:width" content="435">
<meta name="twitter:player:height" content="251">
<meta name="twitter:player:stream" content="https://davidwalsh.name/raw-stream/12345.mp4">
<meta name="twitter:player:stream:content_type" content="video/mp4; codecs="avc1.42E01E1, mpa.40.2"">

Twitter provides a Card Preview utility so that you can ensure your META tags are used in a valid fashion.  I recommend using this utility for all card types, but especially for video card types, as they require the most information.

Now that the Twitter Card META tags are in place, the next step is applying for approval from Twitter.

Applying for Twitter Card Approval

Twitter requires that your domain be approved before they will allow Twitter Cards for your site;  this is likely to combat abuses like pornography and sites promoting illegal activity.  When you apply for Twitter Card approval, you provide simple information about your site, like the Twitter username associated with the domain, which cards you intend on using, and so on:

Twitter Card Application

Twitter mentions the approval process can tween five and ten days, but my site was approved in two days.  Once your site is approved, links to your site containing the appropriate META tags will provide Twitter clients enough information to build Twitter Cards!

Twitter and Robots.txt

If you’re running into issues with your card content not being pull correctly, ensure that your robots.txt file isn’t blocking Twitter. Twitter’s bot is aptly named Twitterbot so check your robots.txt file for incorrectly Disallow rules!

Sample Twitter Card

The following image shows a Twitter card for this site:

Twitter Card

At first I was upset about Twitter’s idea of a Twitter Card because I assumed it would close down the platform, and to this point, no one knows if that will be the case.  What I do know is that implementing Twitter Card META tags is incredibly easy and provides another way for business / site owners to effectively market their site.  Twitter Cards are also nice for the user, allowing them to play videos within their Twitter client, or simply provide a visual associated with a given tweet.

Want to see Twitter Cards in action?  Tweet a link to this or any other post on the site, then click/tap the tweet for the detailed view!

Read the full article at: How to Create a Twitter Card

Hosted by Media Temple, domain from Name.com.

]>
Vibration API http://davidwalsh.name/vibration-api 2012-12-06T15:43:30Z David Walsh Many of the new APIs provided to us by browser vendors are more targeted toward the mobile user than the desktop user.  One of those simple APIs the Vibration API.  The Vibration API allows developers to direct the device, using JavaScript, to vibrate in a pattern for a given duration. View Demo Detecting Vibration API Support [...]

Read the full article at: Vibration API

Hosted by Media Temple, domain from Name.com.

Many of the new APIs provided to us by browser vendors are more targeted toward the mobile user than the desktop user.  One of those simple APIs the Vibration API.  The Vibration API allows developers to direct the device, using JavaScript, to vibrate in a pattern for a given duration.

Detecting Vibration API Support

It’s always good to check for the presence of API support before using it;  here’s how you can detect the Vibration API’s presence:

// Standards ftw!
var supportsVibrate = "vibrate" in navigator;

The Vibration API consists of only one method provided to the window.navigator object:  vibrate.

Vibration API Basics

The navigator.vibrate function accepts either a single number or an array of numbers for a series of vibrations. When using the array method, the even indices represent vibration duration, the odd indices represent a delay before the next vibration.

// Vibrate once for one second
navigator.vibrate(1000);

// Vibrate multiple times for multiple durations
// Vibrate for three seconds, wait two seconds, then vibrate for one second
navigator.vibrate([3000, 2000, 1000]);

To stop vibration when active, simply pass a 0 or an empty array to the navigator.vibrate method:

// Either of these stop vibration
navigator.vibrate(0);
navigator.vibrate([]);

Realize that vibrations do not loop until stopped with 0 or an empty array;  the single number vibration occurs once and then becomes silent, the array of vibration durations run and becomes silent again.

Continued Vibration

Some basic setInterval and clearInterval action will allow us you to create persistent vibration:

var vibrateInterval;

// Starts vibration at passed in level
function startVibrate(duration) {
	navigator.vibrate(duration);
}

// Stops vibration
function stopVibrate() {
	// Clear interval and stop persistent vibrating 
	if(vibrateInterval) clearInterval(vibrateInterval);
	navigator.vibrate(0);
}

// Start persistent vibration at given duration and interval
// Assumes a number value is given
function startPeristentVibrate(duration, interval) {
	vibrateInterval = setInterval(function() {
		startVibrate(duration);
	}, interval);
}

Of course the snippet above doesn’t take into account the array method of vibration;  persistent array-based vibration will require calculating the sum of the array items and creating an interval based on that number (with an additional delay, probably).

Why Use the Vibration API?

This API is clearly targeted toward mobile devices.  The Vibration API would be good for alerts within mobile web applications, and would be especially awesome when used in games or media-heavy applications.  Imagine watching a video on your mobile device, and during an explosion scene, your phone got a bit of a shake.  Or playing Bomberman and feeling a gentle kick when a block explodes!

What do you think of the Vibration API:  immediately useful or not quite yet?

At the time of writing, Firefox BETA for Android is the only browser which supports the Vibration API. WebKit landed the Vibration API a while back, but in my testing of iOS Chrome and Safari, as well as Android Chrome and standard browser, I could not find a working vibration property. Opera doesn’t appear to support vibration yet either.

Read the full article at: Vibration API

Hosted by Media Temple, domain from Name.com.

]>
Disable Autocomplete, Autocapitalize, and Autocorrect http://davidwalsh.name/disable-autocorrect 2012-12-06T04:39:53Z David Walsh Mobile and desktop browser vendors do their best to help us not look like idiots by providing us autocomplete, autocorrect, and autocapitalize features.  Unfortunately these features can sometimes get in the way;  we don’t always want or need the help they provide.  Luckily most browsers allow the developer to remove these features in the cases [...]

Read the full article at: Disable Autocomplete, Autocapitalize, and Autocorrect

Hosted by Media Temple, domain from Name.com.

Mobile and desktop browser vendors do their best to help us not look like idiots by providing us autocomplete, autocorrect, and autocapitalize features.  Unfortunately these features can sometimes get in the way;  we don’t always want or need the help they provide.  Luckily most browsers allow the developer to remove these features in the cases they aren’t desired!

The HTML

Disabling these three native mobile features is as easy as a few simple HTML attributes:

<input autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />

<textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>

Any or all of the autocorrect, autocomplete, and autocapitalize attributes can be used on a given element to prevent the given corrective feature.

While I love these features, they aren’t always applicable and when they aren’t, users get frustrated.  Keep these attributes in mind when using forms on your desktop or mobile site!

Read the full article at: Disable Autocomplete, Autocapitalize, and Autocorrect

Hosted by Media Temple, domain from Name.com.

]>
spellcheck Attribute http://davidwalsh.name/spellcheck 2012-12-06T04:39:33Z David Walsh Many useful attributes have been provided to web developers recently:  download, placeholder, autofocus, and more.  One helpful older attribute is the spellcheck attribute which allows developers to  control an elements ability to be spellchecked or subject to grammar checks.  Simple enough, right?  Let’s take a look at how it’s used! View Demo The HTML The spellcheck [...]

Read the full article at: spellcheck Attribute

Hosted by Media Temple, domain from Name.com.

Many useful attributes have been provided to web developers recently:  download, placeholder, autofocus, and more.  One helpful older attribute is the spellcheck attribute which allows developers to  control an elements ability to be spellchecked or subject to grammar checks.  Simple enough, right?  Let’s take a look at how it’s used!

The HTML

The spellcheck attribute uses values of true or false (you cannot simply add the spellcheck attribute to a given element):

<!-- spellcheck everything! -->
<input type="text" spellcheck="true" /><br />
<textarea spellcheck="true"></textarea>
<div contenteditable="true" spellcheck="true">I am some content</div>

<!-- spellcheck nothing! -->
<input type="text" spellcheck="false" /><br />
<textarea spellcheck="false"></textarea>
<div contenteditable="true" spellcheck="false">I am some content</div>

You can use spellcheck on INPUT, TEXTAREA, and contenteditable elements.  The spellcheck attribute works well paired with the autocomplete, autocapitalize, and autocorrect attributes too!

We’ve all filled out form fields on our mobile and desktop devices which check spelling or grammer and probably shouldn’t.  The spellcheck attribute can save us from that embarrassment when used properly!

Read the full article at: spellcheck Attribute

Hosted by Media Temple, domain from Name.com.

]>
Telephone Link Protocol http://davidwalsh.name/phone-link-protocol 2012-12-05T18:40:27Z David Walsh We’ve always been able to create links with protocols other than the usual HTTP, like mailto, skype, irc ,and more;  they’re an excellent convenience to visitors.  With mobile phone browsers having become infinitely more usable, we can now extend that convenience to phone numbers: View Demo The tel protocol is used for phone numbers: <a [...]

Read the full article at: Telephone Link Protocol

Hosted by Media Temple, domain from Name.com.

We’ve always been able to create links with protocols other than the usual HTTP, like mailto, skype, irc ,and more;  they’re an excellent convenience to visitors.  With mobile phone browsers having become infinitely more usable, we can now extend that convenience to phone numbers:

The tel protocol is used for phone numbers:

<a href="tel:18008675309">Call Jenny!</a>

If you’d like to create a link for SMS text messaging, that’s easy enough too:

<a href="sms:18008675309">Text Jenny!</a>

The sms protocol is used for text.

Many mobile browsers automatically linkify phone numbers on webpages but with the snippet above you can forcibly create phone links!  Since said links don’t work on desktop browsers, it’s probably wise to create a JS snippet to replace spans with a given CSS class with phone links.

Read the full article at: Telephone Link Protocol

Hosted by Media Temple, domain from Name.com.

]>
Mighty Deals 5x Giveaway! http://davidwalsh.name/mighty-deals-5x-giveaway 2012-12-05T15:33:04Z David Walsh I’m a huge fan of Mighty Deals because they partner with other vendors to provide designers and developers with products and bundles at a fraction of their normal price.  eBooks, icon sets, services, themes, images;  Mighty Deals has put together a well-rounded offering for you.  Usually I get to share with you a larger discount than [...]

Read the full article at: Mighty Deals 5x Giveaway!

Hosted by Media Temple, domain from Name.com.

I’m a huge fan of Mighty Deals because they partner with other vendors to provide designers and developers with products and bundles at a fraction of their normal price.  eBooks, icon sets, services, themes, images;  Mighty Deals has put together a well-rounded offering for you.  Usually I get to share with you a larger discount than normal but today I get to give away any item at Mighty Deals!

Mighty Deals

Here’s how it works:

  • Check out what Mighty Deals has to offer
  • Find something you like
  • Visit this post and leave a comment with a link to which deal you want
  • (Hopefully win)

Remember to use your real name and email address.  Five winners will be chose and announced next week!  Good luck!

Read the full article at: Mighty Deals 5x Giveaway!

Hosted by Media Temple, domain from Name.com.

]>
Generating Dojo GFX Drawings from SVG Files || http://davidwalsh.name/svg-dojo 2012-12-04T14:28:48Z ericbrown Eric Brown was my first boss at SitePen and was one of my go-to vector graphic creation men. Eric created an awesome tool for converting SVG images to JSON, useful for creating vector graphics of all rendering engines (Canvas, SVG, VML, etc.) that Dojo’s GFX library supports. The original script had a few issues, so [...]

Read the full article at: Generating Dojo GFX Drawings from SVG Files ||

Hosted by Media Temple, domain from Name.com.

Eric Brown was my first boss at SitePen and was one of my go-to vector graphic creation men. Eric created an awesome tool for converting SVG images to JSON, useful for creating vector graphics of all rendering engines (Canvas, SVG, VML, etc.) that Dojo’s GFX library supports. The original script had a few issues, so Eric’s here to clear those up.

This article builds on the earlier article Generate Dojo GFX Drawings from SVG Files. If you’ve not yet read that article, go and do it now. I’m not going to repeat what’s already in it, and this article won’t make a lick of sense without reading that one first. Really, go ahead, don’t worry, go read it now. I’m a patient sort of guy and will still be here when you get back.

So you’ve read it now? Good. You understand that the technique being discussed here is a way of making images that’ll handle resizing gracefully without quality loss, regardless of whether they’re being shown on giant desktop monitors or minuscule phone displays. With this technique you get full retina quality without the full retina download. Now you’ve got got the basics down and are ready to learn a handful of new tricks.

Tip #1

The first is a work-around for a gotcha that may have bitten you on some of the SVG images you tried to convert. Oftentimes when you do a conversion there will be errors in the resulting JSON file that will cause IE grief. Don’t fret! This is a known limitation that has always been in svg2gfx.xsl, but it’s trivially corrected post-conversion. All that one needs to do is remove occurrences of ,] and ,} from the JSON and the problem is solved. This can be pretty easily done with your favorite text editor, but it’s also easily done with a one-liner that works on all Linux systems, Macs, and other UNIX-like machines. Starting with the file you converted per the earlier article, type the following at the command line:

sed -e 's/,}/}/g' -e 's/,]/]/g' output.json > correctedoutput.json

This will make your JSON play nice with IE. (Yeah experts, I know this can be done more succinctly with more complicated regular expressions, but this version works with pretty much any SED.)

Tip #2

[FTW Logo]

This second trick is really easy but will get you better results. Say for instance you’re making a logo for your new company, "FTW", and you want a few letters incorporated into the logo. Use whatever graphics tool you’re using to generate outlines for the letters prior to conversion, and your logo will display properly on every machine regardless of what fonts they’ve got installed. See? I told you this one was simple.

Tip #3

This third trick is nearly as simple as the second one. If you put id values on objects within your source SVG, they’ll get carried through as name values within the resulting JSON. This can make debugging much easier should something go wrong. It also enables easier manual tweaking after the conversion should it be desirable. Setting id values can sometimes be done directly within your drawing application, but can also be done directly to the resulting SVG with a text editor.

Tip #4

If you’re using your image in just one page, there’s a performance advantage to embedding it within the JavaScript for your page. This is easily done, and best shown by example. I’ll walk through the entire process of using the FTW image above into an embedded resizable logo on a page.

<?xml version="1.0" encoding="utf-8"?>
<svg version="1.2" baseProfile="tiny" id="FTW"
 xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 width="400px" height="400px" viewBox="0 0 400 400" xml:space="preserve">
<g id="FTWLogo">
<polygon id="Pentagon" fill="#1B1464" stroke="#000000" stroke-width="5"
         points="105.232,340.097 41.442,151.479 201.116,32.524 363.591,147.625 304.331,337.715" />
<polygon id="Star1" fill="#FFFF00" stroke="#FBB03B" stroke-width="2"
         points="212.992,48.754 200.967,42.751 189.205,49.255 191.198,35.963 181.377,26.787 194.635,24.574 200.328,12.399 206.528,24.324 219.867,25.976 210.441,35.558" />
<polygon id="Star2" fill="#FFFF00" stroke="#FBB03B" stroke-width="2"
         points="53.874,168.643 41.849,162.64 30.087,169.144 32.08,155.853 22.259,146.676 35.517,144.463 41.209,132.289 47.41,144.213 60.749,145.865 51.323,155.447" />
<polygon id="Star3" fill="#FFFF00" stroke="#FBB03B" stroke-width="2"
         points="377.663,163.829 365.638,157.826 353.876,164.33 355.869,151.039 346.049,141.862 359.306,139.649 364.998,127.475 371.199,139.399 384.538,141.051 375.112,150.633" />
<polygon id="Star4" fill="#FFFF00" stroke="#FBB03B" stroke-width="2"
         points="117.066,356.964 105.041,350.961 93.279,357.465 95.272,344.174 85.452,334.997 98.709,332.784 104.402,320.609 110.603,332.533 123.941,334.186 114.516,343.768" />
<polygon id="Star5" fill="#FFFF00" stroke="#FBB03B" stroke-width="2"
         points="317.365,353.679 305.34,347.676 293.578,354.18 295.57,340.889 285.75,331.712 299.008,329.499 304.701,317.324 310.901,329.248 324.24,330.9 314.814,340.482" />
<g id="FTW">
  <path id="F" fill="#FFFFFF"
        d="M137.14,198.674h-28.076v27.392h-20.41v-67.675h48.486v13.574h-28.076v13.086h28.076V198.674z" />
  <path id="T" fill="#FFFFFF"
        d="M215.754,174.846h-24.805v51.22h-20.361v-51.22h-24.805v-16.455h69.971V174.846z" />
  <path id="W" fill="#FFFFFF"
        d="M337.287,158.391l-29.297,68.554h-11.816l-17.578-39.892l-18.018,39.892h-11.914l-28.711-68.554h21.143 l14.062,37.5l16.113-37.5h14.6l15.82,37.5l14.697-37.5H337.287z" />
</g>
</g>
</svg>

Notice that per Tip #2 this SVG has had its FTW replaced with outlines. In lieu of three letters, it has three paths. This effectively embeds the font so it’ll render the same everywhere. Also, per Tip #3 portions of the drawing have been given id attributes.

Now we do the full conversion in just one command line by first converting it as covered in the earlier article, and then piping it directly into the postprocessing step we discussed above in Tip #1:

xsltproc svg2gfx.xslt ftw.svg | sed -e 's/,}/}/g' -e 's/,]/]/g' > ftw.json

This will give us the GFX JSON we need. It’ll all be in one line. We can now copy and paste this line into a page. We’ll show it copied into a page as part of the next trick.

Tip #5

With just a little bit of clever hackery it’s easy to work vector graphics magic into a site that features unobtrusive JavaScript. While virtually every modern environment both mobile and stationary will use the vector graphic version, folks without JavaScript will still see at least an appropriate bitmap image. The code below makes it happen; it’s pretty heavily commented and thus speaks for itself. You can use it as a template for your own pages. Normally one would use a bitmap image that approximates the vector image, but here we’re using two distinctly different images to make the workings of the trick more obvious.

<!DOCTYPE html>
<html>
  <head>
    <title>FTW</title>
    <!-- We're embedding this CSS in here to make this demo easier.
         Normally you'd put this in its own file. -->
    <style>
    h1 {
      margin:1em;
      padding:1em;
    }
    #Logo {
      width:5em;
      height:5em;
      float:left;
    }
    </style>
  </head>
  <body>
    <!-- This bitmap image will only get displayed if the viewer has JavaScript
         turned off. For this example we've made it distinct for illustration
         purposes; when you're doing it for real, use a low-res bitmap version of
         your vector image for good graceful degradation. -->
    <img id="Logo" alt="FTW Logo" src="ftl.png">
    <h1>This Company Is FTW!</h1>
    <p>Blah blah blah, blah blah.</p>
    <script data-dojo-config="async:true"
      src="//ajax.googleapis.com/ajax/libs/dojo/1.8.0/dojo/dojo.js"></script>
    <!-- We're embedding the following JavaScript in here to make this demo easier.
         Normally you'd put this in its own file. -->
    <script>
    require(["dojo/dom", "dojo/dom-construct", "dojo/dom-style", "dojo/behavior",
             "dojox/gfx", "dojox/gfx/utils", "dojo/domReady!"],
      // This code works on desktop browsers including recent versions of
      // Chrome, Safari, Firefox, Opera, and IE.  It works on iOS.  It works
      // on Android.  It even works on some more exotic systems like the
      // OLPC XO.
      function(dom, domConstruct, domStyle, behavior, gfx, utils) {
        behavior.add({
          '#Logo':function(node) {
            var logoNode=dom.byId('Logo');
            var surfacePos=dojo.position(logoNode);
            var surfaceWidth=surfacePos.w;
            var surfaceHeight=surfacePos.h;
            // The following 400 comes from the size of our original SVG image.
            var scale=surfaceWidth/400;
            // We're going to make the bitmap placeholder image hidden.
            domStyle.style(node,{'visibility':'hidden'});
            // Now we make a new div to take its place on the screen.
            var extraDiv=document.createElement('div');
            domStyle.style(extraDiv,{'position':'absolute','display':'block',
                       'width':surfaceWidth+'px','height':surfaceHeight+'px',
                       'top':surfacePos.y+'px','left':surfacePos.x+'px'});
            domConstruct.place(extraDiv,node.parentNode,'first');
            // We put a GFX surface into this new div.
            var surface=gfx.createSurface(extraDiv,surfaceWidth,surfaceHeight);
            var logo=surface.createGroup();
            // This next line has your JSON copied into it between the two '
            var logoShape='[{name:"FTWLogo",children:[{name:"Pentagon",shape:{type:"polyline",points:[{x:105.232,y:340.097},{x:41.442,y:151.479},{x:201.116,y:32.524},{x:363.591,y:147.625},{x:304.331,y:337.715},{x:105.232,y:340.097}]},fill:"#1B1464",stroke:{color:"#000000",width:"5",style:"Solid"}},{name:"Star1",shape:{type:"polyline",points:[{x:212.992,y:48.754},{x:200.967,y:42.751},{x:189.205,y:49.255},{x:191.198,y:35.963},{x:181.377,y:26.787},{x:194.635,y:24.574},{x:200.328,y:12.399},{x:206.528,y:24.324},{x:219.867,y:25.976},{x:210.441,y:35.558},{x:212.992,y:48.754}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"Star2",shape:{type:"polyline",points:[{x:53.874,y:168.643},{x:41.849,y:162.64},{x:30.087,y:169.144},{x:32.08,y:155.853},{x:22.259,y:146.676},{x:35.517,y:144.463},{x:41.209,y:132.289},{x:47.41,y:144.213},{x:60.749,y:145.865},{x:51.323,y:155.447},{x:53.874,y:168.643}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"Star3",shape:{type:"polyline",points:[{x:377.663,y:163.829},{x:365.638,y:157.826},{x:353.876,y:164.33},{x:355.869,y:151.039},{x:346.049,y:141.862},{x:359.306,y:139.649},{x:364.998,y:127.475},{x:371.199,y:139.399},{x:384.538,y:141.051},{x:375.112,y:150.633},{x:377.663,y:163.829}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"Star4",shape:{type:"polyline",points:[{x:117.066,y:356.964},{x:105.041,y:350.961},{x:93.279,y:357.465},{x:95.272,y:344.174},{x:85.452,y:334.997},{x:98.709,y:332.784},{x:104.402,y:320.609},{x:110.603,y:332.533},{x:123.941,y:334.186},{x:114.516,y:343.768},{x:117.066,y:356.964}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"Star5",shape:{type:"polyline",points:[{x:317.365,y:353.679},{x:305.34,y:347.676},{x:293.578,y:354.18},{x:295.57,y:340.889},{x:285.75,y:331.712},{x:299.008,y:329.499},{x:304.701,y:317.324},{x:310.901,y:329.248},{x:324.24,y:330.9},{x:314.814,y:340.482},{x:317.365,y:353.679}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"FTW",children:[{name:"F",shape:{type:"path",path:"M137.14,198.674h-28.076v27.392h-20.41v-67.675h48.486v13.574h-28.076v13.086h28.076V198.674z"},fill:"#FFFFFF"},{name:"T",shape:{type:"path",path:"M215.754,174.846h-24.805v51.22h-20.361v-51.22h-24.805v-16.455h69.971V174.846z"},fill:"#FFFFFF"},{name:"W",shape:{type:"path",path:"M337.287,158.391l-29.297,68.554h-11.816l-17.578-39.892l-18.018,39.892h-11.914l-28.711-68.554h21.143 l14.062,37.5l16.113-37.5h14.6l15.82,37.5l14.697-37.5H337.287z"},fill:"#FFFFFF"}]}]}]';
            // Now we can load the shape onto the surface.
            utils.fromJson(logo,logoShape);
            // This transform converts from our original SVG image size to
            // the size we need for our display.  It's a vector transformation,
            // so there's no loss of quality.
            logo.setTransform(gfx.matrix.scale(scale));
          }
        });
      }
    );
    </script>
  </body>
</html>

Congratulations!

Now you’re ready to go out and incorporate vector graphics for all your sites. You no longer have to just dream of having logos that render on any size display in crystal clear quality. You now have the power to make it happen.

Read the full article at: Generating Dojo GFX Drawings from SVG Files ||

Hosted by Media Temple, domain from Name.com.

]>
Dojo DeferredList http://davidwalsh.name/deferredlist 2012-12-03T16:02:56Z David Walsh Deferreds are all the rage in the JavaScript community these days and who can argue?  Deferreds, an object representing an asynchronous action, make working with AJAX requests incredibly easy — no callback hell, no problem passing request information around.  What if you want to work with multiple Deferreds though?   For example, say you want [...]

Read the full article at: Dojo DeferredList

Hosted by Media Temple, domain from Name.com.

Deferreds are all the rage in the JavaScript community these days and who can argue?  Deferreds, an object representing an asynchronous action, make working with AJAX requests incredibly easy — no callback hell, no problem passing request information around.  What if you want to work with multiple Deferreds though?   For example, say you want to execute functionality once multiple AJAX requests complete.  The Dojo Toolkit has you covered with dojo/DeferredList, a resource whose API mirrors a single Deferred object but is capable of handling multiple Deferreds.

Using Deferreds

Dojo returns Deferred objects from many operations, including animation and XHR requests.  With the Deferred object, you can use the then property to react to the response once the async interaction is completed:

// A very basic usage of dojo/request
request("service.php?id=someid").then(function(response) {
	console.log("request result is:", response);
});

The example above shows a basic AJAX request and handling of the resulting Deferred.  Easy, right?  But what if you want an action to execute only after multiple Deferreds have resolved?

Using dojo/DeferredList

The DeferredList is a manager for multiple Deferreds, making handling multiple Deferreds a breeze:

// Require the Dojo dependencies
require(["dojo/request", "dojo/DeferredList"], function(request, DeferredList) {
	console.log("Request loaded!", request);

	// Request 1
	var promise1 = request("/endpoint/1").then(function(response) {
		console.log("request 1 result", response);
	});

	// Request 2
	var promise2 = request("/endpoint/2").then(function(response) {
		console.log("request 2 result", response);
	});

	// Create a DeferredList to manage both of them
	var list = new DeferredList([promise1, promise2]);
	// When they're both resolved...
	list.then(function(result) {
		// result is:  [Array[2], Array[2]]
		// result item[0] is the result of each request

		// Do something!
		
	});
});

The example above represents all roses:  all successful Deferreds.  What if a Deferred fails;  a 404 error, request timeout, or a Deferred rejection?  A little validation cures all that:

// Require the Dojo dependencies
require(["dojo/request", "dojo/DeferredList"], function(request, DeferredList) {
	console.log("Request loaded!", request);

	// Request 1
	var promise1 = request("/endpoint/1").then(function(response) {
		console.log("request 1 result", response);
	});

	// Request 2
	var promise2 = request("/endpoint/2").then(function(response) {
		console.log("request 2 result", response);
	});

	// Request 3:  A request that will fail...
	var promise3 = request("/endpoint/noexist").then(function(response) {
		console.log("request 3 result (fail)", response);
	});

	// Create a DeferredList to manage both of them
	var list = new DeferredList([promise1, promise2, promise3]);
	// When they're both resolved...
	list.then(function(result) {
		if(request[0][0] && request[1][0] && request[2][0]) { // request[2][0] is false
			// Success!
		}
		else {
			// React to a failure
		}
	});
});

If the promise for a given Deferreds returns false, you know the request (or async action) failed.  The second argument returned by the Deferred provides information about the request and why it failed:

{
	"message": "Unable to load noexist.php status: 404",
	"response": {
		"url": "/endpoint/noexist",
		"options": {
			"headers":{}
		},
		"xhr": {
			"statusText": "Not Found",
			"status": 404,
			"response": "{404 page html}"}
		}
}

The example here is oversimplified.  One realistic example is the one I used to create the dojox/mobile TweetView example, sending multiple JSONP requests (Twitter profile and Twitter timeline list) for a client-side Twitter widget.  The dojo/DeferredList resource makes handling multiple asynchronous actions easy and enjoyable.  Just another reasons to use the Dojo Toolkit in your next web application!

Read the full article at: Dojo DeferredList

Hosted by Media Temple, domain from Name.com.

]>
HTML5 Datalist http://davidwalsh.name/datalist 2012-11-30T18:12:07Z David Walsh One of the most used JavaScript widgets over the past decade has been the text box autocomplete widget.  Every JavaScript framework has their own autocomplete widget and many of them have become quite advanced.  Much like the placeholder attribute‘s introduction to markup, a frequently used functionality has been moved from a JavaScript-only utility to HTML [...]

Read the full article at: HTML5 Datalist

Hosted by Media Temple, domain from Name.com.

One of the most used JavaScript widgets over the past decade has been the text box autocomplete widget.  Every JavaScript framework has their own autocomplete widget and many of them have become quite advanced.  Much like the placeholder attribute‘s introduction to markup, a frequently used functionality has been moved from a JavaScript-only utility to HTML via the new DATALIST element.

The HTML

A DATALIST element gets an ID attribute and contains numerous OPTION elements, just as a SELECT element would:

<datalist id="frameworks">
	<option value="MooTools">
	<option value="Moobile">
	<option value="Dojo Toolkit">
	<option value="jQuery">
	<option value="YUI">
</datalist>

Once the DATALIST element is in place, a list attribute gets added to an INPUT element which refers to the list ID:

<input name="frameworks" list="frameworks" />

What’s provided is a very rudimentary but useful autocomplete list of existing items that match given text.  Of course the lack of styling that comes with OPTION elements isn’t optimal, and there’s no method to hook DATALIST‘s up to a service endpoint for more dynamic suggestions, but this new element is a step in the right direction!

Read the full article at: HTML5 Datalist

Hosted by Media Temple, domain from Name.com.

]>
CSS :target http://davidwalsh.name/css-target 2012-11-29T06:43:09Z David Walsh One interesting CSS pseudo selector is :target.  The target pseudo selector provides styling capabilities for an element whose ID matches the window location’s hash.  Let’s have a quick look at how the CSS target pseudo selector works! View Demo The HTML Assume there are any number of HTML elements with a given ID: <h2 id="section1">Section 1</h2> [...]

Read the full article at: CSS :target

Hosted by Media Temple, domain from Name.com.

One interesting CSS pseudo selector is :target.  The target pseudo selector provides styling capabilities for an element whose ID matches the window location’s hash.  Let’s have a quick look at how the CSS target pseudo selector works!

The HTML

Assume there are any number of HTML elements with a given ID:

<h2 id="section1">Section 1</h2>

<h2 id="section2">Section 2</h2>

Take note of the ID values of the elements above — to trigger the :target pseudo selector, the window.location.hash will need to match.

The CSS

The :target pseudo selector may be applied to classes, tags, or any other selector:

/* would apply to all targetted elements */
:target {
	color: #000;
}

/* applies to H2's */
h2:target {
	color: #f00;
}

When the window.location.hash is “section2″, the element color will become red and underlined.  Simple!  Much like you can animate elements upon hover or even between media queries, you could even animate the element when targeted; Chris Coyier provides an excellent example of target animating.

:target is neat but I haven’t seen it abused to do anything groundbreaking.  For a site that doesn’t strive for ultimate dynamism, however, the :target pseudo selector could add a bit of native class when using window hashes.

Read the full article at: CSS :target

Hosted by Media Temple, domain from Name.com.

]>
Animated 3D Flipping Menu with CSS http://davidwalsh.name/3d-menu 2012-11-26T14:48:39Z David Walsh CSS animations aren’t just for basic fades or sliding elements anymore — CSS animations are capable of much more.  I’ve showed you how you can create an exploding logo (applied with JavaScript, but all animation is CSS), an animated Photo Stack, a sweet 3D CSS flip card, and much more.  Today’s we’ll create a simple [...]

Read the full article at: Animated 3D Flipping Menu with CSS

Hosted by Media Temple, domain from Name.com.

3D Menu

CSS animations aren’t just for basic fades or sliding elements anymore — CSS animations are capable of much more.  I’ve showed you how you can create an exploding logo (applied with JavaScript, but all animation is CSS), an animated Photo Stack, a sweet 3D CSS flip card, and much more.  Today’s we’ll create a simple but awesome 3D flipping menu as featured here!

The HTML

The HTML structure consists of a list with links, as you would expect from a navigation menu, however there are a few extra SPAN elements to aid the 3D effect:

<ul class="block-menu">
	<li><a href="/" class="three-d">
		Home
		<span aria-hidden="true" class="three-d-box">
			<span class="front">Home</span>
			<span class="back">Home</span>
		</span>
	</a></li>
	<li><a href="/demos" class="three-d">
		Demos
		<span aria-hidden="true" class="three-d-box">
			<span class="front">Demos</span>
			<span class="back">Demos</span>
		</span>
	</a></li>
	<!-- more items here -->
</ul>

Beside the basic A element, a series of SPANs are used to represent the “front” and “back” faces of the 3D box during animation.  Each should be given the same text as the A element.

The CSS

The animation centers around transitions and transforms.  The actual A element wont move — the parent SPAN element will. Each inner SPAN is initialized to its position and doesn’t change. Each element animates upward and backward, using CSS transforms and CSS transitions, though one is on the rotation back while the other animates up into view.

/* basic menu styles */
.block-menu {
	display: block;
	background: #000;
}

.block-menu li {
	display: inline-block;
}

.block-menu li a {
	color: #fff;
	display: block;
	text-decoration: none;
	font-family: 'Passion One', Arial, sans-serif;
	font-smoothing: antialiased;
	text-transform: uppercase;
	overflow: visible;
	line-height: 20px;
	font-size: 24px;
	padding: 15px 10px;
}

/* animation domination */
.three-d {
	perspective: 200px;
	transition: all .07s linear;
	position: relative;
	cursor: pointer;
}
	/* complete the animation! */
	.three-d:hover .three-d-box, 
	.three-d:focus .three-d-box {
		transform: translateZ(-25px) rotateX(90deg);
	}

.three-d-box {
	transition: all .3s ease-out;
	transform: translatez(-25px);
	transform-style: preserve-3d;
	pointer-events: none;
	position: absolute;
	top: 0;
	left: 0;
	display: block;
	width: 100%;
	height: 100%;
}

/* 
	put the "front" and "back" elements into place with CSS transforms, 
	specifically translation and translatez
*/
.front {
	transform: rotatex(0deg) translatez(25px);
}

.back {
	transform: rotatex(-90deg) translatez(25px);
	color: #ffe7c4;
}

.front, .back {
	display: block;
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	left: 0;
	background: black;
	padding: 15px 10px;
	color: white;
	pointer-events: none;
	box-sizing: border-box;
}

If you want to a glimpse into which ways the front and back elements move (which I highly recommend you do), set one of them to display: none and hover over the element;  you’ll see what role each plays in the animation.

The only downfall of this technique is the repeated menu label;  it’s easy to duplicate from a technical perspective, but screen readers may read said text three times, even with the aria-hidden="true" directive.  The visual effect, however, is flawless in its style and silky smooth animation.  No JavaScript, Flash, or canvas needed to create this effect — just a few simple CSS directives.  CSS animations…something to be very thankful for.

Read the full article at: Animated 3D Flipping Menu with CSS

Hosted by Media Temple, domain from Name.com.

]>
CSS Transitions http://davidwalsh.name/css-transitions 2012-11-17T22:43:41Z David Walsh There are two ways to create animations with pure CSS:  CSS animations and CSS transitions.  CSS transitions provide a simple method for animation one or multiple properties from one value to another.    CSS transitions do not require @keyframes — simply provide the desired transition properties to a selector.  CSS transitions traditionally occur upon state changes, like :hover or [...]

Read the full article at: CSS Transitions

Hosted by Media Temple, domain from Name.com.

There are two ways to create animations with pure CSS:  CSS animations and CSS transitions.  CSS transitions provide a simple method for animation one or multiple properties from one value to another.    CSS transitions do not require @keyframes — simply provide the desired transition properties to a selector.  CSS transitions traditionally occur upon state changes, like :hover or :focus.

A Basic CSS Transitions

Let’s create a basic CSS transition of opacity (a fade in and out):

/* from */
.myElement {
	opacity: 0.5;
	transition-property: opacity;
}

/* to */
.myElement:hover {
	opacity: 1;
}

In the example above, when the element is hovered over, its opacity animates from 50% opacity to 100% opacity.  When the mouse leaves the element, its opacity animates back down to 50%.

CSS Transition Properties

Outside of simply providing a CSS property to transition, there are a number of other helpful transition properties:

  • transition-property: one or more properties, or “all”, to transition
  • transition-duration: amount of time the transition should take to complete (ex: 2s or 0.5s)
  • transition-delay: delay before starting the transition
  • transition-timing-function: traditional timing curve function for the transition

These transition properties allow complete control over the simple animation.  Here’s a CSS transition example using all of the properties available:

/* from */
.myElement {
	color: #333;

	transition-property: color;
	transition-duration: 1s;
	transition-delay: .2s;
	transition-timing-function: linear;
}

/* to */
.myElement:focus {
	color: #999;
}

/* shorthand: property duration timingFunc delay */
.myElement {
	transition: all 2s linear 0.3s;
}

In most cases, the default duration, delay,and timing function wont need to be changed.

Transitioning Multiple Properties

Multiple transition properties should be separated by commas:

.myElement {
	/* padding-left, opacity, height, and color here */

	transition-property: padding-left, opacity, height, color;
	transition-duration: 1s, 2s, 3s, 4s;
}

The “all” keyword can also be used to signify all properties should be transformed.  Separate transitions may also be strung together in a shorthand syntax:

.myElement {
	transition: padding-left 1s, opacity 2s, height 3s, color: 4s;
}

The property value can get quite long, but the flexibility is quite nice!

Detecting Transition End with JavaScript

If you’re looking to detect transition end with JavaScript, that’s quite easy:

myElement.addEventListener("transitionend", function() {

	// Do something now that the transition has ended

}, true);

The transitionend event on the node will fire once the transition has completed.

CSS Transition Examples

My blog has featured a number of CSS transition examples:

Read the full article at: CSS Transitions

Hosted by Media Temple, domain from Name.com.

]>
Xbox Live Gamer API http://davidwalsh.name/xbox-api 2012-11-17T11:45:49Z David Walsh My sharpshooter status aside, I’ve always been surprised upset that Microsoft has never provided an API for the vast amount of information about users, the games they play, and statistics within the games. Namely, I’d like to publicly shame every n00b I’ve baptized with my sniper rifle. I recently found a great gamer API effort [...]

Read the full article at: Xbox Live Gamer API

Hosted by Media Temple, domain from Name.com.

Xbox Live API

My sharpshooter status aside, I’ve always been surprised upset that Microsoft has never provided an API for the vast amount of information about users, the games they play, and statistics within the games. Namely, I’d like to publicly shame every n00b I’ve baptized with my sniper rifle. I recently found a great gamer API effort by XboxLeaders.com. While their API can’t tell me the titles and emblems I’ve earned in Black Ops II, I can get some relevant information about my user, my status, and the games I’ve recently dominated.

Xbox API

XboxLeaders currently offers data in three formats (XML, JSON, and serialized PHP) at four API endpoints to retrieve information from:

  • GET profile/:gamertag – Returns data pertaining to the requested gamers’ profile on Xbox LIVE.
  • GET games/:gamertag – Returns data pertaining to the requested gamers’ played games. All game data is returned except for achievements.
  • GET achievements/:gamertag/:gameid – Returns all achievement data for the requested gamer and game.
  • GET friends/:gamertag – Returns all friend data for the requested gamer. Will error out if friends list is private.

These endpoints allow developers to access all of the important gamer-specific data available. XboxLeaders is also working on a POST implementation for sendings messages. Authorization may become required for this API, but the API is currently open to anyone that wants to use it.

Calls to the profile API will return the following information:

{
	"Data": {
		"Tier": "gold",
		"IsValid": 1,
		"IsCheater": 0,
		"IsOnline": 1,
		"OnlineStatus": "Online playing COD: Black Ops II - Search & Destroy\r\non Overflow",
		"XBLLaunchTeam": 0,
		"NXELaunchTeam": 0,
		"KinectLaunchTeam": 0,
		"AvatarTile": "https://avatar-ssl.xboxlive.com/global/t.fffe07d1/tile/0/2000b",
		"AvatarSmall": "http://avatar.xboxlive.com/avatar/dwalsh83/avatarpic-s.png",
		"AvatarLarge": "http://avatar.xboxlive.com/avatar/dwalsh83/avatarpic-l.png",
		"AvatarBody": "http://avatar.xboxlive.com/avatar/dwalsh83/avatar-body.png",
		"Gamertag": "dwalsh83",
		"GamerScore": 310,
		"Reputation": 20,
		"Name": "David Walsh",
		"Motto": "Watch your head.",
		"Location": "Madison, WI, US",
		"Bio": "There is, and only can be, Call of Duty."
	},
	"Stat": "ok",
	"In": 2.504,
	"Authed": "false",
	"AuthedAs": null
}

That’s a nice amount of data to work with. The other API calls will return likewise relevant information.

Using the Xbox Gamer API

So what can be created with this Xbox Gamer API? That’s up to your imagination! Let me use this awesome API to create a gamer card!

<?php

	// Vars
	$gamertag = 'dwalsh83';

  /* 
    Would be better to use cURL, but for briefness of code, using file_get_contents
  */

	// Get profile information
	$profile = json_decode(file_get_contents('http://www.xboxleaders.com/api/profile.json?gamertag='.$gamertag));
  $profile = $profile->Data;
  
	// Get game information
	$games = json_decode(file_get_contents('http://www.xboxleaders.com/api/games.json?gamertag='.$gamertag));
	$games = $games->Data;
	
?>
<!DOCTYPE html>
<html>
<head>

<style>
  
  .gamercard {
    border: 1px solid #bdbec1;
    padding: 10px;
    width: 600px;
    font-family: arial, sans-serif;
    font-size: 12px;
    color: #bdbec1;
    
    background-image: -webkit-linear-gradient(#ddd, #fff, #e9fdce);
    background-image: -moz-linear-gradient(top, #ddd, #fff, #e9fdce);
    background-image: -ms-linear-gradient(#ddd, #fff, #e9fdce);
    background-image: -o-linear-gradient(#ddd, #fff, #e9fdce);
    background-image: linear-gradient(#ddd, #fff, #e9fdce);
  }
  
  .gamercard img {
    display: block;
  }
  
  .gamercard .avatar {
    float: right;
    width: 150px;
    height: 300px;
    margin: -60px 0 0 50px;
  }
  
  .gamercard h1 {
    font-weight: normal;
    color: #78BB58;
  }
    
    .gamercard h1 img {
      display: inline-block; 
      padding-right: 10px;
      width: 24px; 
      height: 24px;
    }
      
  .gamercard h2 {
    color: #111;
    font-size: 16px;
    font-weight: normal;
    margin-top: 15px;
  }
  
  .gamercard ul {
    list-style-type: none;
  }
    .gamercard ul li {
      padding-top: 8px;
    }
      
      .gamercard ul li strong {
        color: #666;
      }
      
  .gamercard ul.games li {
    display: inline-block; 
    margin-right: 20px;
    text-align: center;
    font-weight: bold;
    width: 85px;
    vertical-align: top;
  }
    .gamercard ul.games li img {
      margin: 0 auto;
      width: 85px;
    }
  
  .gamercard a {
    color: #78bb58;
  }
  
  .gamercard .clear {
    clear: both;
  }
  
</style>
</head>
<body>

	<!-- gamercard -->
<div class="gamercard">
  
  <!-- profile image -->
  <img src="<?php echo $profile->AvatarBody; ?>" alt="<?php echo $profile->Gamertag; ?>" class="avatar" />

  <!-- gamer name -->
  <h1><img src="<?php echo $profile->AvatarTile; ?>" alt="<?php echo $profile->Gamertag; ?>" /><?php echo $profile->Gamertag; ?></h1>

  <!-- personal info -->
  <h2>The Legend</h2>
  <ul>
    <li><strong>Name:</strong> <?php echo $profile->Name; ?></li>
    <li><strong>Bio:</strong> <?php echo $profile->Bio; ?></li>
    <li><strong>Location:</strong> <?php echo $profile->Location; ?></li>
    <li><strong>Motto:</strong> <?php echo $profile->Motto; ?></li>
    <li><strong>Online:</strong> <?php echo $profile->IsOnline ? 'Online' : 'Offline'; ?></li>
    <li><strong>Status:</strong> <?php echo $profile->IsOnline ? $profile->OnlineStatus : '(none)'; ?></li>
  </ul>

  <?php if(count($games->PlayedGames)): ?>
  <!-- recent games -->
  <h2>Recent Games</h2>
  <ul class="games">
    <?php foreach($games->PlayedGames as $game): ?>
       <li><a href="<?php echo $game->Url; ?>"><img src="<?php echo $game->BoxArt; ?>" alt="<?php echo $game->Title; ?>" /></a><br /><?php echo $game->Title; ?></li> 
    <?php endforeach; ?>
  </ul>
  <?php endif; ?>
  
  <div class="clear"></div>
</div>
</body>
</html>

This is a simple gamer card. An awesome addition would be a side scrolling list of games, and possibly a display of achievements when you click on each game. In any event, XboxLeaders’ API will get you the information you need.

XboxLeaders’ enhanced Xbox Gamer API is easy to use, dependable, and unique. This API fills a gap Microsoft has created by not providing a public Xbox API, and does it incredibly well. As always, do your best to cache requests so as to keep their server load low and your site fast. Let me know if you create something with this API — I’d love to see it!

Read the full article at: Xbox Live Gamer API

Hosted by Media Temple, domain from Name.com.

]>
Add META Tags, Scripts, and Stylesheets to the WordPress Header and Footer http://davidwalsh.name/wp_head 2012-11-16T00:56:53Z David Walsh There are times where you may want to conditionally inject stylesheets or scripts into your header or footer, or you’d simply prefer to inject those resources via PHP instead of place the HTML in template files directly.  WordPress’ ever-powerful add_filter function provides the a method for injecting stylesheets or scripts into the header, as well [...]

Read the full article at: Add META Tags, Scripts, and Stylesheets to the WordPress Header and Footer

Hosted by Media Temple, domain from Name.com.

There are times where you may want to conditionally inject stylesheets or scripts into your header or footer, or you’d simply prefer to inject those resources via PHP instead of place the HTML in template files directly.  WordPress’ ever-powerful add_filter function provides the a method for injecting stylesheets or scripts into the header, as well as scripts into the footer.  Here’s how!

// Add items to the header!
function shimify() {
	echo '<!--[if lt IE 9]><script src="/wp-content/themes/mytheme/shim.js"></script><![endif]-->';
	echo '<style>/* some styles here */</style>';
	echo '<meta http-equiv="content-type" content="text/html;" /&gt';
}
add_filter('wp_head', 'shimify');

// Add items to the footer
function add_requirejs() {
	echo '<script src="/wp-content/themes/mytheme/requirejs.js"></script>';
}
add_filter('wp_footer', 'add_requirejs');

The add_filter function, which accepts the filter type, action function, and optional priority, provides the means to inject stylesheets and JavaScript files wherever desired.  You may want to conditionally inject a different Google Analytics account if you use a WordPress install that loads different content depending on hostname.  Do not use this technique if you’re adding stylesheets or scripts for your plugin — those should be added with the proper WordPress functions!

Read the full article at: Add META Tags, Scripts, and Stylesheets to the WordPress Header and Footer

Hosted by Media Temple, domain from Name.com.

]>
The World Beyond MVC http://davidwalsh.name/beyond-mvc 2012-11-14T12:32:47Z garannmeans This post is a written version of a talk given by Garann Means at LXJS and NYCjs. It has been formatted to fit your screen. There’s no shortage of JavaScript MVC (Model-View-Controller) architectures out there. The best-known is Backbone, but there are others: Spine, Agility, Knockback, etc. And in addition to the range of MVC [...]

Read the full article at: The World Beyond MVC

Hosted by Media Temple, domain from Name.com.

This post is a written version of a talk given by Garann Means at LXJS and NYCjs. It has been formatted to fit your screen.

There’s no shortage of JavaScript MVC (Model-View-Controller) architectures out there. The best-known is Backbone, but there are others: Spine, Agility, Knockback, etc. And in addition to the range of MVC frameworks, there are MV-whatever variants. This stuff, anecdotally, is pretty popular. As of this writing, Backbone is the 7th most watched repo on GitHub. Developers love MVC.

What makes MVC so appealing, especially for JavaScript where it’s still primarily used, on the client? If you’re new to application architectures, it’s definitely very accessible – the model is data, the view is.. the view, and the controller makes them do stuff. Easy! If you started coding on the server-side, MVC is probably already familiar. Most Object-Oriented Programming embraces the pattern and you can find very popular MVC frameworks for Java, .NET, Python, PHP, etc. The pattern itself actually predates and was first implemented in Smalltalk, after being invented by Trygve Reenskaug in the late 70s, so its relationship with OOP has been there from the beginning. Given the unquestioned supremacy of OOP until fairly recently, it’s unsurprising that MVC makes immediate sense to many of us.

JavaScript, however, is not exactly OOP. We can do OOP with it, but the two hardly go hand-in-hand. Therefore, the appropriateness of MVC varies by use case. For data entry, content management systems, and situations where we can pick out clear and obvious “models”, it tends to work very nicely. But where the state of an application is more amorphous and not always tracked in the same place, in applications with lots of user interaction before any data actually changes, and in apps with very complex widgets or complex, it’s less clear that it’s the right choice. And if your site is JS-heavy but still static, obviously, forget it. There’s no benefit in doing all that setup on a page that’s going to reload and lose it all.

The issue we run into when talking about MVC, or any other architectural pattern, is that, as web developers, these things were not created for us. We can trace the most common patterns back to Design Patterns (aka the Gang of Four book), which was published in 1995. The dawn of our field, literally. These patterns were for programmers building programs primarily for their own use, and certainly not for programmers whose work was easily revealed by going up to the menu and clicking View Source. While those patterns all made their way in some form to the back-end, that canon predates JavaScript completely.

MVC, though, was one of the few ancient methods that made immediate sense. Because it has a clear place for the UI to exist, it’s easily applied to the front-end (although, again, that application is not canon). Because any pattern we want to use has to be fudged a bit to get it to fit our context, MVC is a great place to start. But it’s not the only option we have.

It seems fair to call Event-Driven Architectures the second most obvious pattern. We use event-driven patterns all over the place in JS, and even in combination with MV* patterns. They work well where we need a lot of messaging, and have less need for clear-cut, classical “objects”. For the objects we do have, getters and setters (and soon, Object.observe()) can be used as publishers and subscribers, decoupling events, the core of the application, from the things they affect. The value, though, is that these decoupled events don’t need to affect only objects, but can also affect the DOM, or server interactions, or other events, and none of that needs to be packaged up in a Model-View-Controller triad if it doesn’t make sense as one.

The Naked Objects pattern bears closest relation to MV*, and it would not be unfair to call it a variant of Presentation-Abstraction-Control (a more distant relative). This one’s good for big meaty widgets that need to contain and render their own data, and whose visual representation maps directly to the data they contain. It bears similarity to the drag-and-drop IDEs we used to use to build desktop applications, but without the drag-and-drop bit. Rebecca Murphey used a similar pattern in building the Mulberry mobile app framework, which is a perfect use case because Naked Objects is a great way of organizing a composable framework whose implementations will be better served by a different pattern.

The third pattern I think deserves more examination is Pipelines. This should be familiar to jQuery developers or anyone who deals with a lot of callbacks. Pipelines chain operations together to affect a shared state, which might be a visual representation or just a set of data (or both!). The interesting thing to me is that we can use this pattern both synchronously and asynchronously, for example applying global functions to initialize, render, and wire-up a page, then use instance-specific functions to wait for user interaction, validate it, attempt to save it, and render again, all the while modifying the state of an abstraction of that page. Anything with a state can have a corresponding state diagram in code, with the ability to modify the path it takes depending on the result of each step.

With all of these, as with MVC or any other pattern, you have to consider how and where you want your application tightly or loosely coupled, and whether you need a centralized snapshot of the application, or it’s better stored in the components it affects. Things like Naked Objects would be overkill if even your most complex controls are only used once. Things like EDA would be pointless if most of your code is setup and initialization code. And if your site is static, whatever introduces the least framework code while still helping you establish clear conventions would be preferable.

At the end of the day, you should still use Backbone rather than not use anything. However, if you find yourself with an application that fits more easily into some other pattern, you shouldn’t be afraid to use it. Sadly, for most of these patterns (and the myriad I haven’t even mentioned), you’re going to have a hard time finding anything as robust and accessible as Backbone. So, more importantly, if you’re sitting down to write a new JS application framework, you’d do all of us a service by exploring an alternative to MVC, so picking the right tool for the job won’t be a matter of choosing from a selection of nice hammers with different brandnames to tighten screws. Whatever you choose, and whatever the application, though, remember that all implementations decay and it’s just as important to leave the opportunity to improve architecture as it is to leave ways to improve the code itself.

Read the full article at: The World Beyond MVC

Hosted by Media Temple, domain from Name.com.

]>
Force SSL with WordPress http://davidwalsh.name/ssl-wordpress 2012-11-14T00:42:44Z David Walsh WordPress, the popular blogging CMS platform, is used as an all-purpose site software these days.  The difficulty in using all-purposes solutions is that they are often difficult to customize when edge cases pop up;  one of those edge cases can be forcing SSL.  Many form pages, for example, will be secured to gain user trust [...]

Read the full article at: Force SSL with WordPress

Hosted by Media Temple, domain from Name.com.

WordPress, the popular blogging CMS platform, is used as an all-purpose site software these days.  The difficulty in using all-purposes solutions is that they are often difficult to customize when edge cases pop up;  one of those edge cases can be forcing SSL.  Many form pages, for example, will be secured to gain user trust before filling them out.  WordPress provides an excellent method to secure individual pages!  Here’s how you can force SSL within specific WordPress pages!

The PHP

To secure a specific WordPress post or page, you’ll need to know its ID.  When you know its ID, it’s securing the page is easy:

function force_ssl($force_ssl, $id = 0) {
	// A list of posts that should be SSL
	$ssl_posts = array(1, 12, 19);

	if(in_array($id, $ssl_posts)) {
		$force_ssl = true;
	}
    return $force_ssl;
}
add_filter('force_ssl' , 'force_ssl', 1, 3);

The force_ssl hook allows for us to check the post ID and force SSL if the post ID is in array of posts that should be secured!  Aren’t WordPress hooks great to work with?

Read the full article at: Force SSL with WordPress

Hosted by Media Temple, domain from Name.com.

]>