README.md

Best In Place

The Unobtrusive in Place editing solution

##Description

Best in Place is a jQuery based AJAX Inplace-Editor that takes profit of RESTful server-side controllers to allow users to edit stuff with
no need of forms. If the server have standard defined REST methods, particularly those to UPDATE your objects (HTTP PUT), then by adding the
Javascript file to the application it is making all the fields with the proper defined classes to become user in-place editable.

The editor works by PUTting the updated value to the server and GETting the updated record afterwards to display the updated value.

Helper for generating the best_in_place field only if a condition is satisfied

Provided test helpers to be used in your integration specs

Custom display methods using a method from your model or an existing rails
view helper

##Usage of Rails 3 Gem

###best_in_place
best_in_place object, field, OPTIONS

Params:

object (Mandatory): The Object parameter represents the object itself you are about to modify

field (Mandatory): The field (passed as symbol) is the attribute of the Object you are going to display/edit.

Options:

:type It can be only [:input, :textarea, :select, :checkbox, :date (>= 1.0.4)] or if undefined it defaults to :input.

:collection: In case you are using the :select type then you must specify the collection of values it takes. In case you are
using the :checkbox type you can specify the two values it can take, or otherwise they will default to Yes and No.

:path: URL to which the updating action will be sent. If not defined it defaults to the :object path.

:nil: The nil param defines the content displayed in case no value is defined for that field. It can be something like "click me to edit".
If not defined it will show "-".

:activator: Is the DOM object that can activate the field. If not defined the user will making editable by clicking on it.

:ok_button: (Inputs and textareas only) If set to a string, then an OK button will be shown with the string as its label, replacing save on blur.

:cancel_button: (Inputs and textareas only) If set to a string, then a Cancel button will be shown with the string as its label.

:sanitize: True by default. If set to false the input/textarea will accept html tags.

:html_attrs: Hash of html arguments, such as maxlength, default-value etc.

:inner_class: Class that is set to the rendered form.

:display_as: A model method which will be called in order to display
this field.

:object_name: Used for overriding the default params key used for the object (the data-object attribute). Useful for e.g. STI scenarios where best_in_place should post to a common controller for different models.

:data: Hash of custom data attributes to be added to span. Can be used to provide data to the ajax:success callback.

:classes: Additional classes to apply to the best_in_place span. Accepts either a string or Array of strings

Checkbox

The first value is always the negative boolean value and the second the positive. Structure: ["false value", "true value"].
If not defined, it will default to Yes and No options.

Date

<%= best_in_place @user, :birth_date, :type => :date %>

With the :date type the input field will be initialized as a datepicker input.
In order to provide custom options to the datepicker initialization you must
prepare a $.datepicker.setDefaults call with the preferences of your choice.

More information about datepicker and setting defaults can be found
here

Controller response with respond_with_bip

Best in place provides a utility method you should use in your controller in
order to provide the response that is expected by the javascript side, using
the :json format. This is a simple example showing an update action using it:

Then instead of using @user.description to show the actual value, best in
place will call @user.mk_description. This can be used for any kind of
custom formatting, text with markdown, etc...

Using display_with

In practice the most common situation is when you want to use an existing
helper to render the attribute, like number_to_currency or simple_format.
As of version 1.0.4 best in place provides this feature using the
display_with option. You can use it like this:

= best_in_place @user, :money, :display_with => :number_to_currency

If you want to pass further arguments to the helper you can do it providing an
additional helper_options hash:

##Non Active Record environments
We are not planning to support other ORMs apart from Active Record, at least for now. So, you can perfectly consider the following workaround as the right way until a specific implementation is done for your ORM.

Best In Place automatically assumes that Active Record is the ORM you are using. However, this might not be your case, as you might use another ORM (or not ORM at all for that case!). Good news for you: even in such situation Best In Place can be used!

Let's setup an example so we can illustrate how to use Best In Place too in a non-ORM case. Imagine you have an awesome ice cream shop, and you have a model representing a single type of ice cream. The IceCream model has a name, a description, a... nevermind. The thing is that it also has a stock, which is a combination of flavour and size. A big chocolate ice cream (yummy!), a small paella ice cream (...really?), and so on. Shall we see some code?

Imagine we want to have a grid showing all the combinations of flavour and size and, for each combination, an editable stock. Since the stock for a flavour and a size is not a single and complete model attribute, we cannot use Best In Place directly. But we can set it up with an easy workaround.

##Test Helpers
Best In Place has also some helpers that may be very useful for integration testing. Since it might very common to test some views using Best In Place, some helpers are provided to ease it.

As of now, a total of four helpers are available. There is one for each of the following BIP types: a plain text input, a textarea, a boolean input and a selector. Its function is to simulate the user's action of filling such fields.

These four helpers are listed below:

bip_area(model, attr, new_value)

bip_text(model, attr, new_value)

bip_bool(model, attr)

bip_select(model, attr, name)

The parameters are defined here (some are method-specific):

model: the model to which this action applies.

attr: the attribute of the model to which this action applies.

new_value (only bip_area and bip_text): the new value with which to fill the BIP field.

name (only bip_select): the name to select from the dropdown selector.

##Installation

###Rails 3.1 and higher

Installing best_in_place is very easy and straight-forward, even more
thanks to Rails 3.1. Just begin including the gem in your Gemfile:

gem "best_in_place"

After that, specify the use of the jquery and best in place
javascripts in your application.js, and optionally specify jquery-ui if
you want to use jQuery UI datepickers:

//= require jquery
//= require jquery-ui
//= require best_in_place

If you want to use jQuery UI datepickers, you should also install and
load your preferred jquery-ui CSS file and associated assets.

Then, just add a binding to prepare all best in place fields when the document is ready:

$(document).ready(function() {
/* Activating Best In Place */
jQuery(".best_in_place").best_in_place();
});

You are done!

###Rails 3.0 and lower

Installing best_in_place for Rails 3.0 or below is a little bit
different, since the master branch is specifically updated for Rails
3.1. But don't be scared, you'll be fine!

Rails 3.0 support will be held in the 0.2.X versions, but we have planned not to continue developing for this version of Rails. Nevertheless, you can by implementing what you want and sending us a pull request.

First, add the gem's 0.2 version in the Gemfile:

gem "best_in_place", "~> 0.2.0"

After that, install and load all the javascripts from the folder
/public/javascripts in your layouts. They have to be in the order:

jquery

best_in_place

You can automatize this installation by doing

rails g best_in_place:setup

If you want to use jQuery UI datepickers, you should also install and
load jquery-ui.js as well as your preferred jquery-ui CSS file and
associated assets.

Finally, as for Rails 3.1, just add a binding to prepare all best in place fields when the document is ready:

$(document).ready(function() {
/* Activating Best In Place */
jQuery(".best_in_place").best_in_place();
});

Notification

Sometimes your in-place updates will fail due to validation or for some other reason. In such case, you'll want to notify the user somehow. Best in Place supports doing so through the best_in_place:error event, and has built-in support for notification via jquery.purr, right out of the box.

To opt into the jquery.purr error notification, just add best_in_place.purr to your javascripts, as described below. If you'd like to develop your own custom form of error notification, you can use best_in_place.purr as an example to guide you.

###Rails 3.1 and higher

It's as simple as adding:

//= require best_in_place.purr

###Rails 3.0 and lower

You'll have to load the following additional javascripts, in this order, after loading jquery and best_in_place:

jquery.purr

best_in_place.purr

Security

If the script is used with the Rails Gem no html tags will be allowed unless the sanitize option is set to true, in that case only the tags [b i u s a strong em p h1 h2 h3 h4 h5 ul li ol hr pre span img] will be allowed. If the script is used without the gem and with frameworks other than Rails, then you should make sure you are providing the csrf authenticity params as meta tags and you should always escape undesired html tags such as script, object and so forth.