Showing posts with label Web. Show all posts
Showing posts with label Web. Show all posts

Sunday, January 3, 2016

Increasing Conversion Rate in Web Forms with these 3 HTML5 features

1 

Users hate typing. Most of them will abandon your app when they’ll see a long and frustrating form causing you to miss a potential new user or something important like a purchase.

Users have almost Zero patience. They want to complete what they have started as fast as possible or else they’ll ditch it. This is why you must strive to make the forms as short as possible and allow them to fill them as fast as possible.

 

Autofocus

The current page has a form that the user should fill. Remember that the user patience is short and that’s why you want immediately to focus him on the form.

If you’ll add the “autofocus” attribute to the first element of your form then the element will get focus after the page is ready. In mobile it will immediately show the keyboard.

<input type="text" autofocus>

It is so simple and it puts the user right where you want him.

 

Autocomplete

Users hate to repeat themselves. How many times did you type your full name/address/age/telephone in the last week or month? It’s frustrating! The user has to refill these details over and over again!

There must be a better way.

clip_image004

clip_image006

You’ve definitely seen this before – this is the Chrome’s AutoComplete feature which allows to automatically fill inputs that were filled in the past.

I love it!

You must ask yourself how come that not all the forms allow you to autocomplete this data, after all they all probably use

<input type="email" />and perhaps even give it a useful name attribute <input type="text" name="firstName/">

They just need to add a tiny HTML5 attribute that goes by the name “autocomplete”. The autocomplete attribute can be set with one of these values:

· country

· fname

· lname

· email

Click here for the complete list.

Each element with an autocomplete attribute tells the browser that this element can be autocompleted with a value previously used for this kind of element.

So all you need to do to enable this option and make your users happy is to add autocomplete=”on” and set the right values in the autocomplete attributes. Like so:

<form autocomplete="on"> <label for="firstName"> First Name <input id="firstName" type="text" name="fname" /> </label> <br /> <label for="lastName"> Last Name <input id="lastName" type="text" name="lname" /> </label> <br /> <label for="email"> Email <input id="email" type="text" name="email" /> </label> <br /> <label for="country"> Country <input id="country" type="text" name="country" /> </label> </form>

Wait a second, the label field surrounds the whole input element! Why?

It’s a nice trick that allows your users to click the textbox or the label to get focus to the textbox. Less clicks for the user means better chances that he completes the whole form Smile

 

Geolocation

The last HTML5 feature that can really help your user is geolocation. It allows you (if the user enables it) to get the user’s current location. This means that if your form has some location inputs like shipping address or Zip code then you could autofill them using the user’s location.

Think about all the times you had to look for your Zip code…

Now you can ask the user:

clip_image008

And if he allows it then all this data will be auto filled! The users will love it!

 

With these 3 simple feature you will increase your conversion rate!

 

Feel free to comment if you have another tips.

Wednesday, August 19, 2015

Creating Masked Input Directive with TDD–part2

In the previous post we started implementing the masked input directive. We’ve written tests and the implementation of the directive’s controller. Now it’s time to add the directive itself and of course we’ll start form the tests.

Testing the directive means testing it’s interaction with the UI. These are your integration tests. We’ll want to test the controller logic and the way it reflects in the UI.

First we’d like to test that the directive’s isolated scope has the provided “mask” and “skip” values (keep in mind that in a real application you would test the existence of all the DDO values):

image

Some key notes from this test:

1. In order to test a directive we must create a string that represents its DOM (an element which has the directive attribute i.e.).

2. $compile service parses the element’s DOM and executes the directive function with the provided scope. So the “element” variable is now the directive with all its properties and methods.

3. We can access the scope properties using the element’s “ísolateScope” method.

Now let’s define the DDO:

image

Then we’d like to test that the element’s value will have the provided mask value after the DOM compiles.

image

And now with the link function:

image

In order to change the UI (the element’s value property) you have to call to $setViewValue that is a special angular method that is in charge of setting the value property of the directive element (<input type=”text” value=”this one”/>). $render is called for the UI changes to take place.

Now we add the directive to an html file and actually see all the stuff that we were testing. Add an index.html file, include angular and all the client folder except the spec files!

image

Run it:

clip_image002

That’s what I’m talking about!

All that’s left is connecting our tested (TDD baby) controller functionality to every time the user presses a key.

image

I’ve created a keydown event using the private createKeyDownEvent method and fired it.

The implementation:

image

We subscribe to the keydown event, get the new char, call editMask and if successful re-render the UI.

That’s it! You have a functional masked input element which is fully tested.

clip_image002[5]

As you can see, writing TDD with angular is extremely easy and straight forward. If you are not writing tests then you most definitely should! Just begin, it’s worth it.

Have fun TDDing,

Tuesday, August 18, 2015

Creating Masked Input Directive with TDD–Part 1

In the next two posts I’d like to show you three things:
1. What is a “masked input”.
2. How to create a masked input custom angular directive.
3. And the cherry on top – implement it applying TDD!
So what it is “masked input”?
It allows users to easily enter fixed length input where you would like them to enter the data in a certain format (dates, phone numbers, ids, credit card number and more).
Most of forms out there don’t supply the users any hints about the data’s format and make the users guess it (most of the time the input fields will be  blank textboxes). If there’s a format mismatch then the user will receive an error and will try again.
Using masks allowclip_image003 us to show the users the exact format and force them to enter it correctly.
Let’s implement it!
Remember that we’ll do it using TDD.
So first let’s define the desired API:
image
We want to create a custom attribute directive that will have three properties:
1. Mask – the mask that the user will see in the textbox. These values will be replaced by the user’s input as they type.
2. Skip – an array of chars that we want to be left along with the user’s input like ‘/’ in a date textbox – 01/06/1991
3. Ng-model – the associated model from some controller.
Great! Now after we know our goal we can start writing code.
1. Create ASP.NET Web API project
Add the following nuget packages:
- Angularjs.core
- jasmineTest – this is the jasmine.js testing framework for ASP.NET MVC
- angularjs.TypeScript.DefinitelyTyped
- jasmine.TypeScript.DefinitelyTyped
The last two packages include definition files used generally for TypeScript for the 3rd parties intellisense. However I found that even if you don’t write TypeScript there intellisense is pretty helpful.
clip_image002[6]
Now let’s add a Client directory, index.html file, app.module.js, app.controller.js and a InputMask directory (all the angular code is style accordingly the John’s Papa style guide).
clip_image004[6]
2. Enter TDD
Before we implement the controller we’ll add a spec file to test the controller, we will add a basic test, let it fail and only then implement the controller and the module.
Add a form.controller.spec.js file (this is a style guide naming convention, formControllerSpec.js is also fine). Now we’ll add a basic jasmine test for testing that our controller is defined.
image
Nothing special here: we inject the $controller service in order to get our controller, inject it with a new scope and assert that the controller is defined.
Now let’s add all the files into the SpecRunner.cshtml file:
image
I’ve added angular, angular.mocks, the module and the controller.
The test fails since there’s no module or a defined controller– let’s add them.
First the module:
image
I’m using IIFE to prevent my functions getting into the global scope and prevent the tests get to my private methods.
And the controller:
image
I’m using the $inject pattern in order to make sure that my controller parameters won’t get ruined after minifying the code.
Let’s run the test:
clip_image002
Now let’s add another test to validate that the scope works:
image
Notice that even in js tests I still use the AAA pattern. It makes the tests readable, especially when they get complex.
Run and pass:
clip_image002[5]
1. Adding the directive’s controller
The logic regarding the mask’s chars replacement will be inside the controller (the logic regarding the display will be inside the link function. We’ll get there later).
Add an InputMask directory and place the controller and its spec file in it:
clip_image004
And the first test:
image
I’m placing the specs files near the source files so that the specs will be immediately noticed when someone looks at the solution and so that it will be extremely easy to see that a file is lacking its tests.
Add the controller and the test will pass.
Now let’s start adding some functional tests.
Every time a user enters a letter a controller function must be called in order to edit the mask, it will check the current input length – it shouldn’t be longer than the defined mask and it should replace the mask characters while skipping the values provided in the “skip” array.
Let’s go:
image
And the implementation:
image
Replacing the mask as the user enters input:
image
Notice that the controller sets the ngModel with the mask value on its initialization. We’ll provide the mask value for the ngModel before calling for the editMask method from out test.
The implementation:
image
Now let’s add a test and its implementation for the “skip” characters functionality.
Test:
image
Implementation:
image
Pretty straight forward. Notice how the controller doesn’t do any UI logic– just the way it supposed to be.
In a real life application you should add as many test you can for your controllers in order to achieve maximum code and use cases coverage, in this post (which is already quiet long) we’ll stop here and move towards the next topic – testing the directive.

Friday, June 12, 2015

Aligning Elements using CSS3 “Flex” options

CSS3 introduces the “Flex” options that makes aligning elements extremely easy! It is currently supported in all the major browsers (not supported in IE 11 and below);

Let’s say that I want to align four elements in a line:

clip_image002[4]

The CSS:

.container {
padding
: 0;
margin
: 0;
list-style
: none;
display
: flex;
}

.item
{
background
: green;
padding
: 5px;
width
: 150px;
height
: 150px;
margin
: 10px;
line-height
: 150px;
color
: white;
font-weight
: bold;
font-size
: 3em;
text-align
: center;
-ms-border-radius
: 30%;
border-radius
: 30%;
}


The only new property here is “display: flex”. Not only that flex aligns the elements in a single line it also makes them responsive when the container size changes (overriding the element’s explicit width property;

clip_image003[5]

If you wish to keep the element’s original width you can add the flex-wrap:wrap property which will break the line if needed:

clip_image004[5]

You can reverse the order of the elements that break the line using flex-wrap:wrap-reverse:

clip_image005[5]

You can align the whole line to center or to the first/last item (flex-start/flex-end) using the justify-content property. By default it is set to flex-start:

clip_image007[5]


.container {
padding
: 0;
margin
: 0;
list-style
: none;
display
: flex;
flex-wrap
: wrap;
justify-content
: center;
}


There are two more options for justify-content: space-between and space-around which adds equal spaces between each element:

clip_image009[9]


.container {
padding
: 0;
margin
: 0;
list-style
: none;
display
: flex;
flex-wrap
: wrap;
justify-content
: space-between;
}


If you choose space-around then the first and the last elements will also have the same spaces from the borders.

Vertical Alignment

You can vertically align the elements using flex-direction:column.

clip_image010[4]


Using align-items you can control the vertical starting point (the same like justify-content):

clip_image011[4]


.container {
padding
: 0;
margin
: 0;
list-style
: none;
display
: flex;
flex-wrap
: wrap;
align-items
: center;
flex-direction
: column-reverse;
}


So far we’ve applied the flex properties only to the elements container. We can also apply some flex properties directly on the elements, like making some item be 3 times bigger than the rest:

clip_image013[4]


.container > .grow {
flex-grow
: 3;
}


I’m using the flex-grow property on the wanted item and setting it’s value to 3 as for 3 times bigger.

Flex has more properties that can help you easily align your elements . Go ahead and try!

Wednesday, May 20, 2015

Chrome Developer Tools Tips and Tricks

In the last ALT.NET meetup @Shay Friedman talked about “Chrome Developer Tools Tips & Tricks”. All the audience, myself included were amazed from the features that Shay has shown that neither of us knew.

The Tips & Tricks:

1. Functions navigation in JavaScript source file:

You’re all familiar with this window:

clip_image002

Some of you might know that if you hit Ctrl + P you can open a JS source file from your workspace. However did you know that if you hit Ctrl + Shift + P you can navigate to a function which is included in the opened file!

clip_image004

No more endless scrolling!

2. Style search

This window is also pretty common.

clip_image006

We scroll down in order to figure out which Style messes our element’s css. However did you notice that you can Search (!!!) for a style property or value???

clip_image007

clip_image009

3. Color picker

This is a color property.

clip_image011

Usually in order to change a color you will double-click the area and manually write the new color. However if you click on the colored box itself you will get a color picker dialog!

clip_image013

And if you move the cursor over the page you could even pick a color!!!

clip_image015

4. Disable Cache and reload cache

You remember that time tried your best to hit F5 to refresh the page but had no luck? And then you realized that your cache wasn’t disabled. First and foremost disable it. However if for some reason you still think that your changes are not loaded to the browser you can right click the refresh icon (while the developer tools is open) and try the Hard Reload or the Empty cache and Hard reload it. That should do it.

clip_image017

5. Filtering the network files

If you click on the filter icon in the network tab you could filter all the request’s files by a wanted file type. Hold Ctrl and you can multi select the file types

clip_image019

6. Black box script in Call Stack

When you debug your app and hit a break point you’ll sometimes want to check the call stack window to see previous calls.

clip_image021

Since I use angular this call stack has a lot of angular’s calls which I couldn’t care less about them. However, if I right-click on the angular script file I can select it as a Blackbox script.

clip_image022

And now I won’t see its calls in the call stack window J

clip_image023

If you don’t know some of those features you don’t need to feel embarrassed. Google uses tons of UX best practices in all its products in order to reveal all the available features, but not in Chrome. Here I think they actually tried to hide some of those features. J

If you have more tricks and tips then feel free to comment