Informal proposal for integration of Contacts API with HTML forms

For many use cases of Contacts API the desired functionality is reading 
and processing the data of a specific contact(or set of contacts) 
selected by the user. Example of such a use case would be a news site 
with a "send this article to a friend" functionality. This functionality 
can be achieved using only javascript APIs, but as use cases appear to 
be potentially very strong, it might be reasonable to provide standard 
markup element to handle it.
The use case described above can be met by extending HTML input element 
by a new type. The idea is to reuse forms functionality especially 
<input type="file"> and apply it to contacts.  The advantages of such 
approach
* Having standard UI element vs custom solution for each site.
* Integration with forms
* Possible to use even with javascript disabled
Cons
* Duplicates functionality of javascript API
* Problematic forms upload format

Example markup which could be used in example above:

<input type="contact" name="friend" fields="emails, ims" multiple />

Supported Attributes:
  * required - The required attribute is a boolean attribute. When 
specified, the element is required. -> standard html5 meaning
  * multiple - The multiple attribute is a boolean attribute that 
indicates whether the user is to be allowed to specify more than one 
value. -> standard html5 meaning
  * fields - - The fields attribute is a string attribute which 
indicates which contact fields are passed to the form. The user agent 
MUST present clear visual information about which field access is 
requested by the form. The user agent MAY provide a way for user to 
further limit the fields which are made available by the user. -> A new 
field. It's meaning is the same as search qualifier parameter to 
contacts.find method of Contact API - it narrows down the scope of data 
which is passed from the user.

DOM interface:

interface HTMLContactInputElement : HTMLInputElement {
     attribute Contact[] contacts;
};

Contact input element would expose one new IDL attribute - contacts.

* contacts - Returns a FileList object listing the selected files of the 
form control.  This attribute is set to a list of contact objects 
representing contacts selected by the user. The field set of the 
contacts MUST be narrowed down to the field set specified in 'fields' 
attribute or if the user agent allows user to specify the field set to 
the user specified fields. -> analogous to files attribute  on file 
upload input field.

* value: On getting, it must return id of the first selected contact, if 
any, or the empty string if no contact is selected. On setting, if the 
new value is the empty string, it must empty the list of selected 
contacts; otherwise, it must throw an INVALID_STATE_ERR exception. -> 
The behaviour is analogous to the behaviour of value field on file 
upload input field.

Apart from that, the change events (change and formchange) MUST be 
triggered whenever user modifies the selected contacts(as described in 
HTML5 spec).

Security & privacy considerations

The privacy considerations are mostly the same as for javascript 
contacts API. The only difference is that form based approach has user 
explicit consent baked in - user has to explicitly interact with page to 
select contacts he wants to share. The biggest problem is for ui to 
successfully communicate to user what he is sharing. It is easy to 
imagine situation in which site adds an email field in the form which 
requests all fields of the contact, the user clicks it selects a contact 
and thinks he only shared his email address, but actually he shared full 
contact info. To counter that the user agent MUST clearly express to the 
user to which fields the access was requested. The same considerations 
apply of course to contact picker triggered by contacts.find method.

UI:

The visual representation of a contact input element is implementation 
specific, but in general it should be similar to File Upload - a button 
to trigger contact picker and a field to present chosen contact(s). The 
Clicking the button should trigger contact picker ui. Such an ui MUST 
clearly present to the user which fields of the contact are exposed to 
the site. It MAY allow user to further reduce the set of contact fields 
that are exposed. For example it may present a list of checkboxes for 
fields. Additionally click() method called on such an alement should not 
trigger contact picker ui.
  -> The key point is that UI must give a clear message to the user that 
what he is sharing are contact containing a set of attributes and not 
just their name or email(which is what he will probably see in contact 
chooser), the same as when he is using file upload he is sharing content 
of the file and not just it's name.

The other viable way of implementing it is a edit box which would give 
you list of hints for contacts after typing in few letters - similar to 
browsers addressbar. If such an approach is used it is important that
* the user MUST be informed which fields are being requested
* only change events are triggered and not input events and the value 
attribute should always return only the list of selected contacts and 
not the letters typed in by the user.

Format of data sent on form submit:

The problem with contacts is that as opposed to other form inputs it is 
a set of fields rather than one value. The encodings for sending the 
data to the server assume that an input fields contain only on value. 
This problem can be solved in 2 ways:

A) Serialize the contact in some way(for example in JSON) and send it as 
a single value. The server then has to deserialize it.

Example:
For :
<input type="contact" name="friend" fields="name.givenName" >
with selected contact object with id = "some_id" and 
name.givenName="Bob" url encoded request looks like this:
http://cool.contacts.site.com/process_contact?friend={%20%22id%22%20:%20%22some_id%22,%20%22name%22%20:{%20%22givenName%22%20:%20%22Bob%22%20}

B) treat as if contact fields were separate inputs and send them 
separately. For data from previous example this will be encoded like this:

http://cool.contacts.site.com/process_contact?friend.id=some_id&friend.name.givenName=Bob

The second approach has a disadvantage because it behaves a bit 
differently to other form input fields which may be somewhat confusing, 
but it has the advantage that you can easily maintain a version of the 
the page for old browsers using simple form approach by sending normal 
form based version - for example

@code for new browsers -
<input type="contact" name="friend" fields="name.givenName, 
name.familyName" />
@code for old browsers -
<input type="text" name="friend[0][name][givenName]" />
<input type="text" name="friend[0][name][familyName]" />

the solution for old browsers will require user to manually type all 
contact data and thus will have poorer user experience, but it will have 
the same funcrtionality and can be handled by the same server code.


-- 
Wojciech Masłowski
Engeneering CORE Wrocław
Opera Software ASA
http://www.opera.com

Received on Tuesday, 10 August 2010 12:41:10 UTC