Skip to content
This repository has been archived by the owner on Jun 23, 2020. It is now read-only.

Commit

Permalink
#15: docs
Browse files Browse the repository at this point in the history
  • Loading branch information
adamw committed Mar 12, 2015
1 parent 3562939 commit 029b629
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
25 changes: 25 additions & 0 deletions docs/backend/formdef/typetransformations.rst
Expand Up @@ -34,3 +34,28 @@ The `Joda-Time <http://www.joda.org/joda-time>`_ DateTime transformer can look l
override def renderHint = Some(asDate())
}

.. _transform_jsonobject:

Transforming to a json object
-----------------------------

It is also possible to transform a value to a complex json object (not a plain string/number/boolean). To do that, you
need to provide an implicit ``JsonTransformer``. For example, if you have a ``Point`` class with two fields, a
transformer which serializes it to a two-field json, and deserializes from a two-field json can take the following
form::

implicit val pointJsonTransformer: JsonTransformer[Point] = new JsonTransformer[Point] {
override def typeName = "point"

override def fromJValue(jvalue: JValue) = (for {
JObject(fields) <- jvalue
JField("x", JInt(x)) <- fields
JField("y", JInt(y)) <- fields
} yield Point(x.toInt, y.toInt)).headOption

override def toJValue(value: Point) = Some(
JObject(JField("x", JInt(value.x)), JField("y", JInt(value.y))))
}

However, if the JSON representation of a field is a complex object, you will need to add support for that in the
frontend as well. See :ref:`complexjson` for more information
50 changes: 50 additions & 0 deletions docs/frontend/complexjson.rst
@@ -0,0 +1,50 @@
.. _complexjson:

Frontend: Handling fields serialized to json objects
====================================================

If a field is serialized to a JSON object (not a basic type, such as a string, number or boolean), we will need to add
custom code to display the field and read its value. To see how to (de)serialize fields to JSON objects on the backend,
see :ref:`the documentation on type transformers<transform_jsonobject>`.

For example, if the field is serialized to an object with two fields: ``x`` and ``y`` (a point), we need to provide
a method which renders two inputs instead of one, and which reads value from those two inputs and creates an object.

We can do both of these things by providing field options. If the name of the field is ``pointField``:

.. code-block:: javascript
var sf = new Supler.Form(container, {
field_options: {
pointField: {
render_options: {
renderHtmlInput: function (inputType, value, options) {
return Supler.HtmlUtil.renderTag('span', options,
Supler.HtmlUtil.renderTag('input',
{ class: 'x-coord', type: 'number', value: value.x }) +
Supler.HtmlUtil.renderTag('input',
{ class: 'y-coord', type: 'number', value: value.y })
);
}
},
read_value: function(element) {
return {
x: parseInt($('.x-coord', element).val()),
y: parseInt($('.y-coord', element).val())
}
}
}
}
});
To properly display the field, we override the ``renderHtmlInput`` method of the render options that will be used
for rendering the field. In the method, we create a container element which has all the supler-specific attributes
(passed as ``options``). These attributes will be used to identify elements from which field values can be later
read.

We are using the ``Supler.HtmlUtil.renderTag`` helper method, which simply renders a tak with the given attributes
and body. The body are two inputs: one for the ``x``, and one for the ``y`` coordinate.

Secondly, we provide a custom field-value reading method, by specifying the ``read_value`` field option. This option
takes an element, from which the value should be read (here, this will be the rendered ``span``). The return value
should be the json object, which will be then passed to the backend.
18 changes: 10 additions & 8 deletions docs/frontend/options.rst
Expand Up @@ -13,24 +13,25 @@ Here's a summary of all options that can be used when defining a Supler form.
},
field_options: {
'secretField': {
'render_hint': 'password' // [3]
render_hint: 'password' // [3]
},
'friends[].bio': {
'render_options': {
render_options: {
renderLabel: function(forId, label) { return '<div>some html</div>'; } // [4]
}
read_value: function(element) { return ... } // [5]
},
'render_hint:radio': {
}
},
after_render_function: enrichForm, // [5]
custom_data_handler: displayCustomData, // [6]
after_render_function: enrichForm, // [6]
custom_data_handler: displayCustomData, // [7]
validators: {
good_value: function(json) { return (fieldValue) => { return "error"; } }
},
render_options: new Bootstrap3RenderOptions(), // or any subset of methods from RenderOptions
field_templates: [ 'idOfElementWithTemplates1', 'idOfElementWithTemplates2' ] // [7]
field_templates: [ 'idOfElementWithTemplates1', 'idOfElementWithTemplates2' ] // [8]
});
When specifying field options and dealing with lists of subforms, options for nested fields can be defined using the
Expand All @@ -43,6 +44,7 @@ Options details:
* [2] :ref:`i18n`
* [3] :ref:`customizingrender_renderhints`
* [4] :ref:`customizingrender_fieldoptions_javascript`
* [5] :ref:`afterrender`
* [6] :ref:`customdatahandler`
* [7] :ref:`customizingrender_templates`
* [5] :ref:`complexjson`
* [6] :ref:`afterrender`
* [7] :ref:`customdatahandler`
* [8] :ref:`customizingrender_templates`
1 change: 1 addition & 0 deletions docs/index.rst
Expand Up @@ -60,4 +60,5 @@ Complete documentation
frontend/custombehavior
frontend/customdata
frontend/options
frontend/complexjson
json

0 comments on commit 029b629

Please sign in to comment.