Monthly Archives: January 2014

Bootstrap accessibility plugin: making the popular web development framework better

By

Bootstrap Accessibility Plugin is an extension for the Bootstrap 3 web development framework that makes many of the components of this library accessible for keyboard and screen reader users. Today we are launching this plugin on Github under the BSD license. We hope that this extension will make it very simple for website developers who use Bootstrap 3 components to provide great user experience for as many users as possible.

If you develop websites or web applications using Bootstrap components and want it to be accessible with a minimal development effort, this accessibility plugin may be the perfect solution. By adding the JavaScript plugin in your Bootstrapped HTML pages, you extend the stock components with an additional mark-up and events without modifying the original Bootstrap code. In doing so, you make those widgets keyboard-navigable and introduce the compatibility with screen reader software used by people who are visually impaired.

Features

This plugin provides enhancements to the Bootstrap 3 components in two areas: keyboard navigation and screen reader compatibility. There are also minor changes to improve color contrast in alert messages.

Keyboard Navigation

For some widgets, like tab panel, carousel, drop-down menu, etc, the onKeyDown event is employed in various places in order to make the desktop-style keyboard navigation possible. This enables someone who does not or cannot use the mouse navigate those components using tab and arrow keys. To further enhance the seamless navigation for keyboard users the plugin manages keyboard focus wherever appropriate.

Compatibility With Screen Readers

Once the plugin is loaded into your page, it will search for any available Bootstrap components and, if found, append the necessary ARIA roles and states to provide the enhanced semantics to those widgets. This is primarily useful for screen readers. Without ARIA mark-up it is difficult for this technology to express the meaning of dynamic elements, such as modeless alerts, tab panels, popup menus, carousels, etc, to users who cannot see the screen.

Color Contrast

We found that the foreground-to-background color contrast ratio for a Bootstrap alert message is too low. To make it easier for users to read, the color contrast has been increased.

Please see the README file for the list of components and more implementation details.

Try it out

If you want to use the Bootstrap Accessibility Plugin in your project, simply include the JavaScript file right after Bootstrap’s JavaScript file. The exact instructions of how to do this can be found in the README.

Also, play around with the live demo of the Bootstrap Accessibility Plugin. For better effect, you may want to get hold of one of the popular screen readers if you would like to immerse yourself into the screen reader user experience. Seeing and hearing how “accessified” widgets work in this demo will help you verify whether the plugin is installed correctly on your website.

We look forward to improvements and suggestions from the community. To learn more about how Bootstrap Accessibility Plugin works, check out our detailed documentation.

To stay in touch with us, follow @PayPalInclusive and submit issues on GitHub.

The Bootstrap Accessibility Plugin was primarily authored by Nawaz Khan ( @mpnkhan ) from the PayPal Accessibility Team. The README file provides the full list of contributors.

Resources

Dust is eloquent – the logic wars

By

There are classic feuds like the Hatfields and McCoys, vi versus emacs, and PC vs Mac. In the world of templating, there seems to be just one such dispute: logic-less template languages versus template languages providing logic constructs. So why the fuss?

If you consider the Model-View-Controller (MVC) paradigm, work is divided up among the three parts and compartmentalized. Each part has its own concerns. The view takes data from the model to render the presentation. The controller receives requests, marshalls data to send to the model, and selects a view to be rendered. The model usually has business rules and application logic plus provides data to the view for rendering. The goal is to maintain a “separation of concerns” among the three parts.

Separation of concerns and logic in the template

Maintainability and flexibility are key reasons for using an MVC-like architecture. If business logic is partially in the model and partially in the view, it becomes difficult to figure out where to make changes when fixing or enhancing the system. This is where the “logic-less” proponents take their stand. If you can’t do logic in the template language, then you can’t accidentally have business logic in the template implementing the view.

Logic-less template languages

On the face of it, logic-less sounds fairly extreme. How can you do anything that is conditional if you can’t have any logic? It turns out, if you restrict the logic to just if-exists and if-not-exists, you won’t be able to do any business logic but can still have the template provide different output for different values in the data model. This is the minimal logic provided by Mustache, one of the earliest logic-less template languages. Here is an example of using all the logic forms you have in Mustache. The snippet will output a list of names or output “No names provided” if there are no names in the model data.

{{#names}}
  <b>{{name}},</b>
{{/names}}
{{^names}}
  No names provided
{{/names}}

Mustache’s section notation, {{#foo}}, is similar to that of Dust except Dust uses fewer “mustaches”, e.g. {#foo}. Both languages skip rendering the content if foo is non-existent or is an empty list thus providing a form of logic wrapped in the idea of iterating over data. Mustache adds one more construct, the {{^foo}}text{/foo} which will output the text body if foo does not exist, is false or is an empty list. There you have it. That is the total extent of logic in Mustache. This deliberate minimalism makes it impossible for the template writer to add any business logic to the view. It does mean that any variation in output must be catered to via the model having extra values (or omitting them when not present is used to control the output).

The slippery slope of logic

Adding logic capabilities to template languages is an easy thing to do and tempting since the asceticism of Mustache often chafes the template writer. The downside of adding logic capabilities was not well understood in the early days of template languages. If you look at this JSP hideosity, it becomes clear how bad it can get.

<script type="text/javascript">
var myConfig = {
     modal:true,
   <% if (lastPage) { %>
     showPreviousButton  :true,  
     showNextButton : false ,
   <%}  else  {%>
   showPreviousButton  :true,  
     showNextButton : true ,
   <%} %>
</script>

This mixes three languages in just a few lines (HTML, JavaScript and JSP) and relies on the fact that JSP is compiled down to Java code. Even if you don’t use scriptlets which are generally acknowledged to be a bad thing, JSP still has full conditional logic via the Java Standard Tag Library’s tag. The EL expressions it provide gives you the full power of Java conditionals so the path is wide open to add business logic to the template.

There is an interesting paper by Terence Parr, “Enforcing Strict Model-View Separation in Template Engines” that formalizes the study of template engines using results from formal language theory. In the paper, he defines an “entanglement index between model and view”. The index ranges from 1 (low entanglement) to 5 (maximal entanglement). Each of 5 rules violated increases the index value. The rules are:

  1. Model data must be read-only
  2. No computations can be performed on model data, e.g. price*.90 to get sale price
  3. No comparisons on model data, e.g. numAccounts < 5
  4. No assumptions or dependencies on the type of the model data
  5. Model data must not contain information to control the display/layout

His survey of a number of template languages showed they are polarized. Either they have minimum entanglement of 1 or a maximal entanglement of 5 — the slippery slope seems clear. Dust with the current set of Dust helpers has an index of at least 3 and maybe 4 depending on what the application puts in the model. If you restrict yourself to the main Dust language and avoid the helpers, you can be at an index of 1

For minimum entanglement, these are the only features a template language should provide:

  • attributes (called keys in Dust)
  • conditional processing based on presence/absence of an attribute
  • recursive template references
  • template application to multi-valued attribute

What logic capabilities does Dust offer?

The Dust base language is very similar to Mustache with a few tweaks to make it more readable. If we rewrite the above Mustache example in Dust it would be:

{#names}
  <b>{name},</b>
{:else}
  No names provided
{/names}

This is more concise and readable than the Mustache version. If you want to write it Mustache-style Dust still has the {^foo} form. Further, Dust offers {?foo} as the inverse of {^foo} allowing a test without committing to iteration at the same time. In the spirit of Mustache and logic-less, none of these forms permit comparison.

Be aware of how model values intended for such tests work exactly in Dust. It is not exactly the same as JavaScript.

  • Empty strings, “” or ” evaluate to false, boolean false, null, and undefined all evaluate to false. This corresponds with how these values are treated in JavaScript
  • Numeric 0 evaluates to true, as does any non-zero length string value. The treatment of numeric 0 is different from JavaScript where is it is considered false.
  • Empty array -> [] is evaluated to false. All other objects evaluate to true.

This means that using 1 and 0 for model value of true and false is a bad choice for Dust as both are considered true. Your best bet for a false representation is to just omit the value from the model or make the value an empty string.

In case you are curious what Dust has added that increases the entanglement index, it’s the following helpers: @if, @select, @eq, @ne, @gt, @lt, @gte, @lte, @math. We will take a look at these in a future post on helpers.

Why do developers need to write logic in templates?

Let’s look at the other side of the coin. Most UI developers are not maliciously looking to jam business logic into their templates. Largely, they are trying to deliver a designated UI design and user experience in a productive way and leave a flexible/maintainable solution. Why might a UI
developer feel they need logic in the template?

The data model is inadequate to do my job

If the model data is not sufficient for just exist/not-exists tests then you have only two choices: a) use template logic to do compares or b) ask the owner of the model to make changes to meet your presentation needs. Often the model construction is done in a language not known by the UI developer (like Java) or it comes from some external third party and is just a “given”. This prevents a “dive in and fix it yourself” solution.

But suppose the model is built within the scope of your overall project. What might you, the UI developer, need to ask the model owner to change and why? Here are some samples:

  • In the list of state names and abbreviations, please add “selected: true” to the U.S. state this user has in the address information. Why: I cannot mark the element “selected” without logic in the template.
  • In the list of account records, add a property “even: true” to entries that are even numbered. Why: I can’t add a class to even rows without logic in the  template. Well, not quite true. I could use nth Child CSS pseudo selector but not all browsers support it.
  • If the likesCount is zero, add an extra item to the model, “noOneLikesYou: true”. Why: I can’t test the model value, that would require logic in the template.
  • If the values are 0 and 1, could you make them ” and 1 (see Dust true/false testing above). Why: I can’t test explicit 0 and 1 values without logic.

Of course, the response from the owner of the model logic might well be “Why should I add presentation-oriented data into the model? That violates the separation of concerns and bloats the model.”

So in an effort to keep all logic out of the template, we have introduced view-oriented logic into the model. If in the future, the view needs to change, the model logic will be impacted or even more tweaks to the model will be required. So we have broken the “separation of concerns”, just in a different way.

So what if we allow logic? I poked around in some of our template code and found this example where having logic is being abused.

{@if cond="parseInt('{expirationYear}') < new Date().getFullYear()"}
    stuff to output
{/if}

This is using the full power of eval in @if to do a bunch of JavaScript logic to determine what should have been a “isExpired” value in the data model.

The horns of our dilemma

We can either:

  1. severely restrict our template language to be certain careless UI developers can’t inadvertently introduce some business logic, or
  2. allow some logic in our template language to avoid presentation-oriented data having to be added to the model but ensure the logic is used only for pure UI matters.

I favor option 2,  not crippling the UI developer’s just to be sure they don’t mess up. We don’t treat other developers in this way. Instead we use mechanisms like good training, peer programming, and code reviews to be sure the code is high quality and robust. Similar techniques for UI developers can ensure that business logic stays where it should, even if we occasionally have to apply the Mallet of Loving Correction.

The following simple questions could form a checklist for UI developers employing logic beyond the simple attribute tests.

  • If you are comparing a model value to something else, is the purpose purely presentational?
  • If your logic tests involves && and ||, think hard about whether there might be some business logic going on. The more complex the test, the more suspect it should be.
  • If you are doing any math operation, make certain it is only for presentation purposes

So there you have the arguments for logic-less and what some call “less logic” template languages. You’ve seen some pros and cons and I’ve stated my preference. If you feel strongly about it one way or the other, go make a comment on Twitter with the hashtag #logicless. We’ll be interested to see your thoughts.

If you want to read more on the logic-less debates, here are some other links to peruse.

The case against logic-less templates
Logicless template redux
Cult of Logic-less template
StringTemplate

New Year. New Family.

By

2013 was a busy year for the PayPal Developer Relations team. We kicked off our first-ever global hackathon competition, Battle Hack, and we created the first startup program at PayPal — Start-up Blueprint — to help developers succeed and grow. But, what we were most excited about was that we welcomed Braintree into the PayPal family last year.

As we start off the New Year, we’re excited to share that the PayPal Developer Relations team is joining the Braintree team. Braintree has specialised in working with the top start-ups and developers like Uber, Fab and Airbnb for many years and so moving our Developer Relations team into Braintree makes sense as we will be closer to our customers — the awesome developers and start-ups!

Just because we’re moving over to Braintree doesn’t mean anything changes for PayPal developers. Our team will continue sharing information and best practices for PayPal APIs, but now we’ll be able to do the same for Braintree SDKs. By having knowledge of both sets of tools, we will be able to better help developers find the best payment solution for their needs.

We look forward to what 2014 brings. We’ll continue bringing our Battle Hack competition to more cities around the world, and signing up more start-ups and incubators for our Blueprint Startup program. Feel free to reach out to us @PayPalDev or email us if you have any questions!

Building infinite scrolling in the PayPal mobile web app

By

In this post I will talk about my internship project which consisted of building the infinite scrolling for the user’s activity on the PayPal mobile web app.

Scrolling is often referred to as a painful task. Infinite scrolling, for example, enhances the user’s experience by allowing new content to be fetched as they scroll. However, there are some considerations to make when the content changes inside the scrolling area:

  1. Can the content vary in dimensions? This is required to render the content in order to know how many pixels it will occupy on the screen.

  2. Assuming infinite data, how is the system going to handle the creation of many node elements in the DOM tree?

  1. How often does the app check for the size of the element that wraps all the content?

By looking at some applications we get some sense on how to address these issues:

1. The Web Browser

Chrome divides the web page into tiles called composited layers that then are painted by a given scroll position.

infinitescroll1

2.  Maps

Maps are also divided into tiles, so only certain regions are downloaded and rendered on the screen.

As we can see they both fetch the resources that are needed. They also have the ability to reuse resources by a process called recycling.

In the world of mobile development, recycling is implemented in Cocoa Touch and the Android SDK.

Let’s consider how recycling is handled in Cocoa Touch:

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cell1"];
    if ( cell==nil ) {
      // Allocate a new cell
    }
   // Set the model for the cell
}

This is a delegate method used to request cells. This setup attempts to reuse a cell that is no longer visible or it will create a new one if none is available. The benefits from doing this are less power and memory required to update the rows.

We wanted to implement a similar approach for our mobile web app by loading new transactions as the user scrolls.

Key observations

  1. Each row had the same height, so we could get the position of any given row in constant time without directly asking the browser.
  2. We had two types of rows, odd and even rows. Both rows had specific styles. For instance, odd rows had a lighter background color compared to even rows.

Implementing the scroll

When we started the project there was not a built-in CSS property for scrolling that all the web browsers we were targeting accepted. We wanted to maintain the momentum style that characterizes native applications. For us, the solution was iScroll, a JavaScript library that solves the cross-browser support issue.

Before starting with the infinite scrolling implementation, we required to give certain structure to the data coming in from the RESTful service. We used Backbone.js in the entire app, so we defined the Model, View and Collection as follows:

The Model

The model consists of essential information about the status of a transaction on PayPal.

{
 "id": "1",
 "name": "Pizza Restaurant",
 "status": "completed",
 "amount": "10.0",
 "currency": "USD",
 "date": "2013-12-01T19:20:30+01:00"
}

Part of this information is rendered in the activity list, and the other is supplementary for the details interaction.

The View

The app has a main view called the CellView which is extended by an OddCellView and EvenCellView views.

var CellView = Backbone.View.extend({
  tagName: "div",
  className: "ui-cell-view"
});

var OddCellView = CellView.extend({
  className: "ui-cell-view ui-cell-view-odd"
});

var EvenCellView = CellView.extend({
  className: "ui-cell-view ui-cell-view-even"
});

The two child classes are meant to represent different objects that share the same functionality but different looking as their className suggests. The benefit from explicitly defining this in the code rather than letting the browser guess it (using :even and :odd pseudo classes) is the Cell Recycling process that will be covered next.

Since all the cells have the same height and are the only one in a row, we can determine the total number of rows we need given a scrolling area height.

TotalRows = (ScrollingAreaHeight / RowHeight) * 3/2

The 3/2 factor means that it will have 1.5 times more rows than the visibles to the user.

The Collection

As PayPal users may have lots of activity status, the app needed to fetch them efficiently. Backbone collections was the structure that helped us to keep the data organized in the client. We built a paging mechanism that fetches models on-demand, so as the user scrolls it will ask for data when there is not enough models to cover the scrolling area. The collection had a limit of 100 contiguous models.

One of the benefits of this separation in the client is that once a model is stored in the client, there’s no need to ask the server for more information about that particular transaction which helps to reduce the stress on the servers.

Putting all pieces together

Now that we have the structure of the data and the views, we can start working on the implementation of the infinite scroll. The core of the infinite scroll is the ability to reuse cells that are no longer visible.

When a cell (DOM element) is rendered in the browser, we create its own composited layer by adding the 3D transform property that gives its position on the scrolling area. This composited layer is then uploaded to the GPU as the cell represents the smallest portion of the scrolling area that can be split into tiles. The implementation also had a composited layer for the scroller (implemented by iScroll) which gives the momentum feeling.

We wanted to avoid operations like: change the background color, change the class selectors, or change the entire subtree of the cell because they invalidate the texture in the GPU causing overhead and in some situations a disgraceful blinking effect.

infinitescroll2

 

The recycling process consists on moving the least recently seen cell to the space that needs a new cell. The following graph illustrates the process:

infinite3

 

The implementation only updates the Y component of the transformation matrix that gives the position of the cell on the screen. This update is really fast since the texture is hardware accelerated.  Next, it updates the model of the cell which indeed requires to paint the new name, status and amount of the transaction, but on a much smaller area.  Another consideration is that web browsers are highly optimized to handle modifications to Text Nodes when those do not involve alterations to the DOM structure.

Results

The scrolling feels responsive. This implementation achieved an average of 60 frame per seconds on an iPhone 5, and here’s what the frame graph looked like on Chrome after fetching about 300 transactions.

infinite4

Here’s a screenshot of the PayPal User’s Activity.

 infinite5

 

 

If you’re interested in an internship at PayPal please visit our Student Careers site.

A sweet toggle switch

By

In today’s world of front-end web development, it’s becoming increasingly complex to create custom interface elements. A common scenario is when your design team has required a non-standard web-based form component. This time it’s a toggle switch which seems to be becoming more popular in the web design world.

toggle_switch_comp

Winging the development of a toggle switch for a prototype is one thing, but for production a gracefully degradable and fully accessible version is required. Let’s walk through the strategy and code for developing a sweet toggle switch. We’ll create a control where the user can select either a “checking” or “savings” account.

Coding Strategy

As we should with any front-end project, let’s start with HTML semantics. Because the switch is essentially selecting between two options, let’s use two radio inputs each of course with a label. Using basic form elements will also make submitting the form simple and not require any scripting. At first glance, it may seem that a single checkbox element may work; but two labels are required, and the form data to be passed may need to be more than a simple Boolean value. The radio inputs and labels are contained in a div and then within a form. The labels are styled to create the toggle switch effect. Paragraph text provides the instructional text which tells the user what the toggle switch is for.

Marking It Up

Below is an example of the basic HTML. The checked attribute is optional; if removed, the toggle switch renders as expected on page load (neither option selected). The labels will be floated left in the next step, so a “clearfix” class is added to the container. The radio inputs are hidden visually using an “accessAid” class (which uses the clipping technique to hide rather than off-screen).

<form>
  <p>Select the type of account:</p>
  <div class="toggle-btn-group clearfix">
    <input type="radio" id="checking" name="accountType" value="checking" class="accessAid" checked="checked" />
    <label for="checking">Checking</label>
    <input type="radio" id="savings" name="accountType" value="savings" class="accessAid" />
    <label for="savings">Savings</label>
  </div>
</form>

For accessibility and structure, sets of radio or checkbox elements many times require a fieldset and legend elements or an ARIA substitute. But in this case, it’s not needed because the labels by themselves are clear. Web accessibility experts at WebAIM say “basic radio buttons (such as male/female for gender) that make sense from their labels alone do not require fieldset and legend.” If a use case requires the added clarification of the controls, use the aria-describedby attribute. Here’s an example:

<p id="p1">Select the type of account:</p>
  <div class="toggle-btn-group clearfix">
  <input type="radio" id="checking" name="accountType" value="checking" class="accessAid" checked="checked" aria-describedby="p1" />

Styling

The CSS of course will transform the appearance of the radios to a toggle switch; well, more accurately, the radio inputs are visually hidden and their labels create the visual effect.

.toggle-btn-group label {
  padding: .5em;
  display: inline-block;
  width: 8em;
  float: left;
  text-align: center;
  cursor: pointer;
  color: #000;
  background-color: #ddd;
  border: #999 2px solid;
}

Rounded corners are added to create the pill-like shape.

.toggle-btn-group label:first-of-type {
  border-top-left-radius: .5em;
  border-bottom-left-radius: .5em;
}
.toggle-btn-group label:last-of-type {
  border-top-right-radius: .5em;
  border-bottom-right-radius: .5em;
}

With some fun CSS selectors, the selected/checked state of the label is created through the “checked” pseudo class of the associated radio element (the adjacent sibling). The focus state is normally indicated by the radio inputs; but since they are visually hidden, we return that functionality.

.toggle-btn-group input[type="radio"]:checked+label {
  background-color: #00a1ff;
  border: #000 2px solid;
  color: #000;
}
.toggle-btn-group input[type="radio"]:focus+label {
  outline: 2px #999 dotted;
}

And then the default hover and focus states.

.toggle-btn-group label:hover,
.toggle-btn-group label:focus {
  background-color: #ccc;
  border: #000 2px solid;
  color: #000;
}

Falling Back and IE8

In modern browsers, JavaScript is not required so the toggle switch will function fine when JavaScript is not available. If CSS is not available for any reason, the toggle switch simple renders as the basic radio inputs with the associated text labels.

Internet Explorer versions 8 and below do not support the checked CSS pseudo-class selector (input[type="radio"]:checked+label). To make it work, JavaScript is required. A listener on the labels can be implemented to add and remove another class which gives the same styling.

Putting it all together

You can view an example of this toggle switch here. Feel free to model the code and share with your peers.

Summary

Native web components are always the best way to go. But when it’s not possible due to design requirements, there’s usually a good way to solve while keeping degradation and accessibility in mind. In the toggle switch example, we started with fundamental radio inputs within a form and enhanced the design with CSS.

Thanks to fellow PayPals Victor Tsaran and Dereck Quock for input in this article.