Pages

Sunday, 17 April 2011

Modern Web Form Design

This is my outline/notes on Modern Web Form Design by Luke Wroblewski at Mix10

Rich Interactin to enhance standard forms


  1. Dynamic inline forms
    • Inline multi-step (accordion) forms should not efect conversion rates
    • People were fastest with the inline multi-step form
    • People do not think of section headers as form actions/elements
    • Inline multi-step forms do not inherently have more usability issues than single or multipage forms
  2. Unnecessary Inputs
  3. Any question you ask requires people to:
    • Parse it
    • Formulate a response
    • Input their answer
  4. Be vigilant about every question you ask
    • Can it be removed?
    • Can it be postponed?
    • Can it be inferred?
  5. Selection Dependent Inputs
  6. BEST PRACTICE
    • If lots of dependent inputs, use page-level
    • Vertical & horizontal tabs perform well but have mutual exclusivity issues
    • Long lists of initial inputs, few dependent inputs for each, use drop-down menu
    • Short list of initial options & few dependents, exposed inline
    • Maintain clear relationship between initial selection options
    • Clearly associate additional inputs with their trigger
    • Avoid "jumping" that disassociates initial selection options
  7. Inline Validation
  8. Versus a page submit/refresh model
    • 22% increase in completions
    • 31% increase in satisfaction ratings
    • 42% decrease in completion times
    • 22% decrease in errors made
    • 47% decrease in number of eye fixations
    BEST PRACTICES
    • Use inline validation for inputs that have potentially high error rates
    • Validate "open" inputs after people finish
    • Keep validation messages persistent
    • Use suggested inputs to disambiguate
    • Avoiding "jumping" forms around

Forms on mobile devices

The rule of thumb is to limit the use of forms in the mobile context, Mobile Web Design & Development, O'Reilly 2009

  1. Field zoom
  2. Use top aligned fields instead of left aligned
    • When data being collected is familiar
    • Minimize time to completion
    • Flexibility for localization and complex inputs
    • Easier to code: no floats or tables
    • Accessibility: label, field in order
    • Better format for mobile screen
    • Support help/error messaging column
    • Require more vertical space
  3. Input Types
  4. Take advantage of HTML5 input types: Usability suffers when users type in passwords and the only feedback they get is a row of bullets. Typically, masking passwords doesn't even increase security, but i does cost you business due to login failures, Jakob Nielsen, 2009
  5. Pop-Up & Compound Menus
    • Use pop-up and compund controls to simplify data input
  6. Device Capabilities
    • Form Fields
    • Location
    • Gestures
    • Audio
    • Images

More Information
  • @lukewdesign
  • www.lukew.com/ff/

Web Form Design
  • www.rosenfeldmedia.com/books/webforms/

Friday, 15 April 2011

How to warn the user that all unsaved changes will be lost when he is leaving the page Part 3

Here is some progress on my jQuery plugin for warning a user when he is leaving the page and there are unsaved changes.

    1 // Version 0.2

    2 // April 10 2011 22:54

    3 // Julian Vargas

    4 // http://gr8code.blogspot.com

    5 

    6 (function () {

    7     var userIsEditing = false;

    8     var message = "Do you really want to abandon this page?, unsaved changes will be lost.";

    9     var controlsToObserve = ":input, :text, :password, :radio, :checkbox, select";

   10     var eventsToObserve = "keyup change";

   11 

   12     // the function is declared as a 'var' for DRY.

   13     var confirmation = function (event) {

   14         if (userIsEditing && !confirm(message))

   15             event.preventDefault();

   16     }

   17 

   18     $("a").click(confirmation);

   19     $(window).unload(confirmation);// This still needs improvements

   20 

   21     $(controlsToObserve).bind(eventsToObserve, function () { userIsEditing = true; });

   22 

   23 })();

Wednesday, 13 April 2011

Sunday, 10 April 2011

How to warn the user that all unsaved changes will be lost when he is leaving the page Part 2

I come back to show some progress on How to warn the user that all unsaved changes will be lost when he is leaving the page. This is my current implementation.

    1 //Version 0.1
    2 //April 10 2011 22:54
    3 //Julian Vargas
    4 //http://gr8code.blogspot.com
    5 (function () {
    6     var userIsEditing = false;
    7     var message = "Do you really want to abandon this page?, unsaved changes will be lost."
    8 
    9     $("a").click(function (event) {
   10         if (userIsEditing)
   11             if (!confirm(message))
   12                 event.preventDefault();
   13     });
   14 
   15     $(":input, :text, :password, :radio, :checkbox").bind("keyup", function () {
   16         userIsEditing = true;
   17     });
   18 
   19 })();

Thursday, 7 April 2011

How to modify an IFrame behaviour with jQuery

This post is about how I used jQuery to work out a situation regarding two existing
applications.


The situation is this. We have two applications MainApp and SubApp,
MainApp loads SubApp in a IFrame and passes two out of three querystring parameters.


Now the SubApp was modified to use the third parameter but the MainApp is not currently
passing it and we are not allowed to perform any change to MainApp because it is
a legacy application compiled with framework 1.1. So, what we did was edit the MainApp.aspx
file and add the next lines:
<script language="javascript" src="jquery.min.js"></script>
<script language="javascript" src="querySt.js"></script>
<script language="javascript">
    $(document).ready(function () {
        var $frame = $("#IFrameForSubApp");
        var address = $frame.attr('src');
        address = address + 
                '&ThirdParameter=' + querySt('ThirdParameter');
        $frame.attr(
                'src', address);
    });
</script>
 
That's it, this is how The Code Saved The Day.

On "How to Create Effective Facebook Wall Posts"

This morning I read this post called
How to Create Effective Facebook Wall Posts
by Courtney Boyd Myers. The
post summarises the results of a research performed by Buddy Media; the research
was about the "Likes" and comments on all Facebook Wall Posts. My notes on this
are:
  • Marketers work Monday through Friday but Facebook is always available.
  • Post with up to 80 words lenght have a higher engagement raten than longer posts.
  • Engagement rates are 3 times higher for posts that used a full-length URL, rather
    than a URL shortener.
  • Posting outside normal business hours icreasees the engagement rates.
  • Engagement rates on Thursday and Friday are higher than other days of the week.
  • Keywords as "Events" or "Winning" were associated with promotions that had the highest
    engagement, while “buy,” and “shop” had low engagement.

Wednesday, 6 April 2011

A pattern for binding items to a ListControl

Almost every time that I create a webform, I have to put a DropDownList or other
ListControl in order to bind a set of values. Doing this is fairly simple, just
set the properties DataSource, DataValueField and DataTextField to the appropriated
values and then perform a DataBind, but notice that this implies writing four lines
of code just to perform this particular task and when you have more ListControls
in a single webform, the amount of code for doing this binding would be overwhelming.
That is why I developed the BindHelper Pattern, which is simply a set of functions
that perform the binding task for me. For instance, if we have an entity called
CountryBrl (the suffix Brl stands for BusinessRulesLayer) and we want to have a
bindhelper for it, then the code would be like this:



Partial Public Class CountryUil



  Public Shared Sub Bind(ByVal control As ListControl, _
   ByVal objList As List(Of CountryBrl), _

   Optional
ByVal firstItem As ListItem = Nothing, _

   Optional
DataTextField As String = "Name")


   SortList
.SortByProperty(objList,_

      DataTextField, _

      SortOrder.Asc)

   control.DataSource = objList

   control.DataValueField = "ID"
   control.DataTextField = DataTextField
   control.DataBind()

   'Commonly used for a "Select" item

    If
Not firstItem Is Nothing Then

     control.Items.Insert(0, firstItem)
    End If

  End
Sub

 
  Public Shared Function BindToListControl(ByVal control As ListControl, _
    Optional ByVal firstItem As ListItem = Nothing, _

    Optional
DataTextField As String = "Name") _

    As List(Of CountryBrl)


   Dim
objList As List(Of CountryBrl)


   objList = CountryBrl.GetAll()


   Bind(control, objList, _
    firstItem:=firstItem, _
    DataTextField:=DataTextField)


    Return
objList


  End
Function


End
 Class

The code above implements:

  • A class called CountryUil (the suffix Uil stands for User Interface Layer).
  • A static core method responsible for the binding task: this method receives the
    ListControl to bind the data to, a list of entities as the data source, and optional
    parameter to show at the top of the ListControl (Commonly used for “Select”) and
    an optional parameter that specifies the field to be used as the DataTextField in
    the ListControl.
  • A static method called BindToListControl which receives the same parameters except
    for the list of entities. This method loads the data from the model, sorts the data
    by the field corresponding to the parameter DataTextField and then calls the method
    Bind.

To clarify how to use this class I proceed to show some examples:

Protected
  Sub Page_Load(ByVal sender As Object, _  
   ByVal
e As System.EventArgs)


   'ddlCountries is a DropDownList

   'chkCountries is a ChekBoxList
   
   'The default configuration: loads all
   'the countries and binds them to

   'the control showing the name and putting
   'as the first item the "Select"

   CountryUil.BindToListControl(ddlCountries, _
     New
ListItem("Select", 0))



   'Loads all the countries and binds them to

   'the control showing the CountryCode
   'and putting as the first item the "Select"

   CountryUil.BindToListControl(ddlCountries, _
    New
ListItem("Select", 0), _

    "CountryCode")

 
   'Loads all the countries and binds them to

   'the control showing the CountryCode

   CountryUil.BindToListControl(chkCountries, _
    DataTextField:="CountryCode")


   'Loads all the countries and binds them to

   'the control showing the Name

   CountryUil.BindToListControl(chkCountries)


   'performs the binding using a set of data 

   'available in the session
    CountryUil.Bind(chkCountries, Session("Countries"))



End Sub

And that’s it, we performed multiple binds by calling the same utility and this
is saving us a lot of code and time.

It is important to mention that I do not write this kind of code by hand, I use
a code generator to do it for me. The generator creates BindHelpers for every single
table in my database including the methods for binding by foreign keys like this:

CityUil.BindToListControlByCountryId(chkCities, intCountryId,...)
And since the class is generated as partial, I am able to create custom bind methods
in a separate file, very useful when working with code generators.
I hope this Code Saves Your Day as it did with mine.

Tuesday, 5 April 2011

How to warn the user that all unsaved changes will be lost when he is leaving the page

Recently I was asked to implement the following requirement in all my webforms:
"When the user is leaving a page, the application must show a confirm dialog warning the user that if he leaves the page, will lose all unsaved changes"
I decided to implement this with jQuery because I already have included the reference in all my webforms as well as some standard scripts which I use through out my applications.

What I did was add the next lines to an existing script file:


var isEditing = false;
$(document).ready(function () {
  $(":input, :text, :password, :radio, :checkbox")
    .bind("keyup change",function () {
         isEditing = true;
    });


  $("a").click(function (event) {
    if(isEditing)
       if(!confirm("Warning message"))
          event.preventDefault();
  });
});

Certainly this Code Saved the Day, but giving a closer look at this code one can note some issues to bear in mind:
-Global variables are not a good practice
-The dialog does not show up when the user close the window
-The dialog does not show up when the user clicks a button

I will fix these issues shortly, perhaps by implementing the appropriate jQuery plug-in.

Monday, 4 April 2011

Creating PDF Documents with ASP.NET and iTextSharp

I read the article Creating PDF Documents with ASP.NET and iTextSharp by Scott Mitchell and I found it very useful, especially the section where he explains how to create a pdf file from an html template. Now I'm trying to create a helper that receives a URL and creates the pdf for me, this is because I use to create my reports in webforms, and it would be very useful if one could take the content of that report and generate a pdf file with it.
One thing to bear in mind before trying to create the pdf with this approach is that you cannot have any button of link in the page; otherwise the parser will throw an exception. The other thing is that your page has to have inline styles (which is not a good practice) in order to generate the pdf file with all your design.

'This works with URLs in the same site, I got an exception when
'trying others like http://gr8code.blogspot.com

Dim
webPage As System.Net.WebRequest = _
System.Net.WebRequest.Create("http://someurl")

Dim
sReader As New IO.StreamReader( _

webPage.GetResponse().GetResponseStream())

'gets all the response as you
see it in the 'View source'


Dim
strContent = sReader.ReadToEnd()


Dim parsedHtmlElements = _
   HTMLWorker.ParseToList(New
 StringReader(strContent),
 Nothing)


Dim document As New Document(PageSize.LEGAL, 50, 50, 25, 25)

Dim output As FileStream = _
   New FileStream(Server.MapPath("myFile.pdf"), 
 FileMode.Create)

Dim writer = pdf.PdfWriter.GetInstance(document,
output)

document.Open()

For Each htmlElement In parsedHtmlElements
   document.Add(htmlElement)
Next
document.Close()

The helper is still far from being ready but I think this is a good starting point.

10 Essential Web Application Usability Guidelines by Oleg Mokhov

Keypoints on 10 Essential Web Application Usability Guidelines by Oleg Mokhov

1. Have a Consistent and Standardized UI: Keep the interface constant and use standardized elements.

2. Guide the user: Make clear where to click to progress. If one action is more important that other, have the button or action area for it prominently displayed.

3. Make (Call-to-Action) Interactive Objects Obvious: Make click and tap targets as large as possible, make the interactive objects big and obvious. Make the interactive objects noticeably bigger than the surrounding elements.

4. Give Feedback - Both for User's Interacting and Progressing: Give visual feedback then a user's interacting, as well as the user's progress if applicable.

5. Never Have Users Repeat Anything & Keep Signup Info to a Minimum: Ask for any info only once.

6. Always Have Default Values in Fields and Forms: Having a simple default value in a text field will push the user in the right direction as to what they need to type in.

7. Explain How the Inputted Info Will Be Used: Make it clear, comfortable and affirming as possible for the users how the info will be used ("Your email will be your login username", "Your location will be used to *do something*")

8. Don't Have any Reset or Mass-Delete Buttons: There's almost no situation where a user will have to wipe every scrap of data and start again.

9. Have Clear and Explanatory Error & Success Messages: Instead of "Oops, something went wrong" message that doesn't inspire confidence, have something more specific and explanatory like "Our database which holds your account info is temporarily inaccessible and will be back shortly".

10. Include a Clear Visual Hierarchy and Navigation (Breadcrumbs): Make sure your layout and navigation is very clear. Have clear 'breadcrumbs' at the top of the page.

Sunday, 3 April 2011

Number Decimal Separator

Remember, Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator gives us the character used for decimals, then we can :

Dim separator As String = Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator

Dim strNumber As String = "1.0" 'A string number with dot as separator
strNumber = strNumber.Replace(".", separator).Replace(",",separator) 'Replaces dot or comma for the current separator

Dim value As Double = CDbl(strNumber)' Casts the string to Double