+++ title = "Advanced Nitrogen Elements" date = 2009-06-16T23:33:58Z in_search_index = true [taxonomies] tags = [ "Site-News", "erlang", "javascript", "nitrogen", "tutorial", "web-framework", ] +++ In my last post I walked you through creating a basic nitrogen element. In this one I'll be covering some of the more advanced topics in nitrogen elements.
-module(element_silly).
-compile(export_all).
-include("elements.hrl").
-include_lib("nitrogen/include/wf.inc").
render(ControlId, R) ->
Id = wf:temp_id(),
%% wait!! where do we get the loc from?!
ClickEvent = #event{type=click, postback={click, Loc}}
Panel = #panel{id=Id, style="width:'100px' height='100px'",
actions=ClickEvent}, element_panel:render(Panel).
event({click, Loc}) ->
wf:update(body, wf:f("you clicked at point = "~s", Loc))."
Well of course you spot the problem here. Since the click happens client side we don't know what to put in the Loc variable for the postback. A typical postback won't work because the data will be generated in the client and not the Nitrogen server. So how could we get the value of the coordinates sent back? The javascript to grab the coordinates with jquery looks like this = ""
var coord = obj('me').pageX + obj('me').pageY;
```
To plug that in to the click event is pretty easy since action fields in an event can hold other events or javascript or a list combining both:
```erlang
Script = "var coord = obj('me').pageX + obj('me').pageY;",
ClickEvent = #event{type=click, postback={click, Loc}, actions=Script}
```
Now we've managed to capture the coordinates of the mouse click, but we still haven't sent it back to the server. This javascript needs a little help. What we need is a drop box. Lets enhance our element with a few helpers:
```erlang
-module(element_silly).
-compile(export_all).
-include("elements.hrl").
-include_lib("nitrogen/include/wf.inc").
render(ControlId, R) ->
Id = wf:temp_id(),
DropBoxId = wf:temp_id(),
MsgId = wf:temp_id(),
Script = wf:f("var coord = obj('me').pageX + obj('me').pageY; $('~s').value = coord;",
[DropBoxId]),
ClickEvent = #event{type=click, postback={click, Id, MsgId},
actions=Script},
Panel = #panel{id=Id, style="width:'100px'; height='100px'",
actions=ClickEvent, body=[#hidden{id=DropBoxId},
#panel{id=MsgId}]},
element_panel:render(Panel).
event({click, Id, Msg}) ->
Loc = hd(wf:q(Id)),
wf:update(Msg, wf:f("you clicked at point = "~s", Loc))."
```
Ahhh there we go. Now our element when clicked will: - use javascript to grab the coordinates of the mouse click
- use javascript to store those coordinates in the hidden element
- use a postback to send the click event back to a nitrogen event handler with the id of the hidden element where it stored the coordinates.
We have managed to grab dynamically generated data from the client side and drop it somehwere that nitrogen can retrieve it. In the process we have used an event handler, custom javascript, and dynamic javascript postbacks.
Edit = "Corrected typo - June 16, 2009 at 11:40 pm "