Authoring Components
Component GUI model
Bundling UI functionality in client-side components is a pretty obvious idea. The reference implementation of the component library uses just trivial stateless function maps, with the simple inheritance.
jasty.Button = jasty.extend(jasty.Control, { init: function(self, opts) { self.text(opts.text); self.click(function() { jasty.raiseEvent(self, opts.onClick, {srcId: self.attr("id"), data: opts.data}); return false; }); }, text: function(self, value) { self.text(value); } });
Method init
is reserved for component initialization. I would generally recommend to put
the whole rendering code for the component into this method. So that the only thing, rendered
on the server is the outer tag with nothing but an id specified. The remaining initialization
occurs in the init
-method.
<button id="someId"></button> <script> jasty.Button.init($("#someId"), { text: "initial text", onClick: "buttonClicked"}) </script>
Behavioural methods may substantially depend on the DOM-representation of the component. That's why it's reasonable to keep everything in one place - in the component code - only having a single DOM-tag to be rendered by the server.
To facilitate calling methods on complex selectors, as well as to provide a common interface to various component writing styles, dispatching plugin may be used:
$("#someId").jasty("Button", "text", ["some text"])
This jQuery-plugin resolves the component and calls the specified method sequentially for every selected element, applying parameters from the array in the 3rd parameter.
For the components designed in a different way, alternative dispatching plugins might be necessary. But the calling interface should be kept the same:
$(<selector>).<dispatcher>(<component>, <method>, <parameters array>)
Sticking to the common interface for call dispatchers allows for easy code generation by the server-side component proxies.
Server-side proxy components
Proxy components are used to enable interaction with the client components from the server-side code.
public class Button extends Component { @InitProperty private String text; @InitProperty private String onClick; public void setText(String text) { this.text = text; invoke("text", text); } @Override public String getHtmlTag() { return "button"; } }
By calling invoke
method, component method (setText
) generates javascript code,
which is then included in the AJAX-response and executed in the browser.
For example, these calls
Button btn = new Button(); btn.setId("someId"); btn.setText("new text");
produce following script:
$("#someId").jasty("Button", "text", ["new text"])
Emitting executable javascript is the only method of AJAX-response in the framework, and it perfectly covers all needs.
The proxy components are actively used in the event handlers of the Forms.