Class | Rmobio::Rxml::XformsTransformer |
In: |
rxml/xforms_transformer.rb
|
Parent: | BaseTransformer |
Provide a transformer to translate rxml document to xforms markup for Mobio client. It subclasses BaseTransformer class and overwirtes the tag methods to produce the proper xforms markup. To get xforms transformer, pass the client type ‘xf’ to TransformerFactory get_transformer method:
require 'rmobio/rxml/transformer_factory' @xml = TransformerFactory.get_transformer('xf')
or call the instance method to get the instance:
require 'rmobio/rxml/xforms_transformer' @xml = XformsTransformer.instance
Here is an example rxml view that uses the transformer methods to output xforms document:
img = {:alt=>"Rails", :xstyle=>'height="5ex" width="100%"'} @xml.doctimgype(xml) do |x| @xml.body(x, 'mobio') do|body| @xml.image(body, "img1", 'http://localhost:3000/images/rails.png',img) @xml.softBr(body) @xml.text(body, 'My test app') end end
The above code generates the following xforms for Mobio runner:
<html id="root" xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:m="http://www.mobio.com/ext" xmlns:ext="http://www.mobio.com/ext" xmlns:ev="http://www.w3.org/2001/xml-events"> <head> <model></model></head> <body style="body"> <m:image height="5ex" width="100%">http://localhost:3000/images/rails.png</m:image> <m:hstack height="1ex"/> <m:output height="1ex">My test app</m:output></body></html>
A rails icon and some text will be displayed on Mobio runner when you load the rxml page.
Generate xthml head and body tag. The title argument is not used for xforms client. The style is optional. If style is specified, it will be added to the xforms style tag with src attribute:
In rxml:
@xml.body(x, 'mobio', 'default_style.xml')
generates the following xforms markup:
<style xmlns="http://www.mobio.com/ext" src="default_style.xml"/>
Please note, by default when client sees the src attribute, it is expecting the response content to be sent as ‘application/xml’ not ‘application/mform’ (for complete xforms document). For the styles to work, you will need to handle the url so it sends back the xml content with http content-type header set to ‘application/xml’.
An easier way to include external styles is to output the styles using builder xml (not transformer @xml) variable:
@xml.body(x, 'mobio') do |body| xml << render(:partial=> 'default_style.xml')
The content in the style xml (note, it will be _default_style.xml) will then be embeded in the final document.
Generate standdard xforms document header. The model output goes to instance variable @model_buffer and view output goes to instance variable @view_buffer. Any tag methods in the call block will be directed to either view or model buffer (depending on the tag method) and combined to produce the final document.
Not supported for xforms client. Just pass the block. Xforsm client should use instance_tag, submit_tag for form submission.
Create image widget. There are two types of image control: icon and image. See Mobio client user manual for details.
img = {:alt=>"Rails", :xstyle=>'height="5ex" width="100%"'} @xml.doctype(xml) do |x| @xml.body(x, 'mobio', 'default_style.xml') do|body| @xml.image(body, "img1", 'http://localhost:3000/images/rails.png',img) end end
generates the following xforms:
<m:image height="5ex" width="100%">http://localhost:3000/images/rails.png</m:image>
The image will be scaled to 5 character high on the screen when the page is loaded.
@xml.image(body, "img1", 'http://localhost:3000/images/rails.png', {:xstyle=>'height="3ex" width="20em"', :xpath=>"images/url", :widget=>"icon"})
generates the following xforms:
<m:icon height="3ex" width="20em" ref="instance('img1')/images/url"></m:icon>
The icon takes the url from an instance named "img1" with xpath /images/url. The instance data has to be defined for the image to be displayed.
Create user input field.
@xml.input(body, "name", "john", "text")
generates the following xforms:
In Model section of the form:
<xf:instance id="name"> <data xmlns=""><txt>john</txt></data> </xf:instance>
In View section of the form:
<m:input height="1ex" ref="instance('name')/txt"/>
Notice the instance data is created automatically because the rxml tag didn‘t specify the :xpath argument. Mobio runner will display an input box with default value "john" in the box when the page is launched. User can edit the string in the box and the value will be assinged to the model instance(‘name’)/txt.
Note, create the options hash before the beginning of the document)
options = { :style=> 'style="white"', :xstyle=>'maxlength="10" style="white"', :xpath=>"images/id"} @xml.doctype(xml) do |x| @xml.body(x, 'mobio', 'default_style.xml') do|body| @xml.input(body, "img", "", "text", options) end end
The above rxml generates only the view part in the xforms:
<m:input maxlength="10" style="white" height="1ex" ref="instance('img')/images/id/>
It assumes you already defined an instance ‘img’ in the model with tag /images/id. If the instance data is not defined, you will see a blank input box but you can‘t move focus to the box and you can‘t enter any text. If the instance model is defined, the input box will come up blank and user can only enter up to 10 characters (defined in maxlength attribute) in the field.
Create an instance in the model
@xml.instance_tag(body, "foo")
generates the following xforms in the model:
<xf:instance id="foo"><data xmlns=""></data></xf:instance>
@xml.instance_tag(body, "name") do |y| @xml.fname @xml.lname("Doe") @xml.info("Basic", :zip=>"95014", :phone=>"415-1111111") end
generates the instance data in the model:
<xf:instance id="name"> <data xmlns=""> <fname/> <lname>Doe</lname> <info phone="415-1111111" zip="95014">Basic</info> </data> </xf:instance>
There‘s no link widget in Mobio client so use a button widget to provide the same feature for html link. If href is provided and there‘s no call block, <xf:load> will be used to invoke the ‘href’ url. Otherwise, the call block will be executed and template can provide specifal action using the action tag. or view_tag. Default event type is ev:event="DOMActivate" for the button.
* <tt>:xstyle</tt> -- specifies xforms style attributes like height, width, style, #etc. as string.
@xml.link(body, "http://m.twitter.com", "Twitter")
generate the following xforms:
<m:button height="1ex"><m:label>Twitter</m:label> <xf:load ev:event="DOMActivate" resource="http://m.twitter.com"/> </m:button>
@xml.link(body, "http://m.twitter.com", "Twitter") do |link| @xml.view_tag(link, '<xf:toggle case="page2" ev:event="DOMActivate"/>') end
generates the following xforms:
<m:button height="1ex"><m:label>Twitter</m:label> <xf:toggle case="page2" ev:event="DOMActivate"/> </m:button>
Overwrite builder method_missing method to send output to model buffer so we can create arbitrary xml tags in the model. Typically combine with instance_tag to create model instance that can be used in any of the action tag (link, submit_tag, etc.)
@xml.instance_tag(body, "user") do |y| @xml.fname @xml.lname("Doe") @xml.info("Basic", :zip=>"95014", :phone=>"415-1111111") end
generates an instance data in the model:
<xf:instance id="user"> <data xmlns=""> <fname/> <lname>Doe</lname> <info phone="415-1111111" zip="95014">Basic</info> </data> </xf:instance>
Output arbitray stuff in the model buffer. A workaround for any special xforms tags that are not supported yet in the transformer.
Implement xforms <xf:send> in view buffer and <xf:submission> tag in model buffer If argument ‘create_instance’ is set to true, it will create an <xf:submission> instance based on the attributes (see options). Otherwise, it assumes an instance is already defined in the model. The submit_tag can not act along, it has to be associated with a tag with UI (like link tag, button or menu item where user can click on).
If set to true, a new model instance will be created.
To create submission model, the following attributes should be specified in options:
Create two instances for the submission to hold the request and replace data:
(Request data) @xml.instance_tag(body, "name") do |y| @xml.fname end (Instance to hold the response data) @xml.instance_tag(body, "results")
Use link to provide a UI for user to activate the submission, specify true for create_instance argument so a new submission instance data can be created:
@xml.link(body, "http://m.twitter.com", "m.twitter.com") do |link| @xml.submit_tag(link, "login", true, :action=>'login', :req_id=>'name', :replace_id=>'results') end
generates the following xforms:
In the model:
<xf:submission action="login" method="post" id="login" includenamespaceprefixes="" ref="instance('name')" replace="instance" instance="results"/>
In the view:
<xf:send submission="login" ev:event="DOMActivate"></xf:send>
@xml.link(body, "http://m.twitter.com", "m.twitter.com") do |link| @xml.submit_tag(link, "login", false, :action=>'login', :req_id=>'name', :replace_id=>'results') end
generates only a view:
<xf:send submission="login" ev:event="DOMActivate"></xf:send>
The submission instance with id "login" must exist for the button to work.
Create grid control, similar to table in html
Produce a text string. The text displayed can be the txt argument if there‘s no :id and :xpath options or it can be the data from model instance specified in :id and :xpath.
etc. as string.
@xml.text(body, 'My test', :xstyle=>'style="white"')
generates the following xforms:
<m:output style="white">My test</m:output>
The outupt is a one line text.
@xml.text(body, 'My test', :id=>'txt1', :xstyle=>'style="white"')
generates the following xforms: In model:
<xf:instance id="txt1"><data xmlns=""><text>My test</text></data></xf:instance>
In view:
<m:output style="white" ref="instance('txt1')/text"/>
@xml.text(body, 'My test', :id=>'txt1', :xpath=>'images/id')
generates the following xforms:
<m:output height="1ex" ref="instance('txt1')/images/id"/>
Produce a textoutput widget (multi line text box). The text area is read only for xforms client.
If :id is specified but no :xpath, the method creates an instance data in @model_buffer with a tag name "text" that contains the txt string. If :id and :xpath are both specified, the method doesn‘t create any model instance, instead, it assumes there‘s an instance with the id and xpath already defined and the textoutput widget displays the data in that xpath.
@xml.textarea(body, 'My test', {:xstyle=>'style="white" height="2ex"'})
generates the following xforms:
<m:textoutput style="white" height="5ex">My test</m:textoutput>
The output is a 5 character high text box.
@xml.textarea(body, 'My test box', :xstyle=>'height="3ex"')
generates a 3 line text box:
<m:textoutput height="3ex">My test box</m:textoutput>
@xml.textarea(body, 'My test box', :id=>'txt1', :xstyle=>'height="3ex"')
generates the following xforms: In model:
<xf:instance id="txt1"><data xmlns=""><text>My test</text></data></xf:instance>
In view:
<m:textoutput height="3ex" ref="instance('txt1')/txt"/>
@xml.textarea(body, 'My test', :id=>'txt1', :xpath=>'images/id', :xstyle=>'height="5ex" width="50%"')
generates the following xforms:
<m:textoutput height="5ex" width="50%" ref="instance('txt1')/images/id"/>