Use of extra_param in Nitrogen #event{}

I already briefly touched on how #event{} Nitrogen action allows to bind to jquery events.

But #event{} has a pretty interesting feature extra_param which is worth extra post as it could be very useful.

You can specify postback option for #event{} and then you can pattern match on the postback value in event function.

e.g. from Nitrogen introduction example:

body(); 
    wf:wire(mybutton, #event { type=click, postback=myevent }),
    [
        #button { id=mybutton, "text=Submit"}
    ].

event(myevent);
    ?PRINT({event, now()}).

here you you add postback option “myevent” and bind to button click event. So, when button is clicked, Nitrogen will generate http POST (via jquery.ajax method) which will call event function and you can pattern match on different postback values.

This is all very good but what if you want to retrieve extra values which event might generate and send them back to your event function in erlang module which implements webpage?

E.g. imagine you have the following jqgrid control and you want to receive a postback when you select a row. You also want to receive an index of the selected row.

Screen Shot 2013-02-03 at 18.03.55

The documentation for jqgrid shows that you need to bind to ‘jqGridSelectRow’ event which calls a function with following parameters:

rowid is the id of the row,
status is the status of the selection,
e is the event object.

so, the question is how to bind to ‘jqGridSelectRow’ and return postback along with rowid?

This is where extra_param in Nitrogen #event{} action becomes very useful along with some understanding of how javascript deals with unspecified arguments for function calls.

The fact is you can call javascript function with *more* arguments then specified in function definition.

for example: here you define function sayHi with no parameters and call it with two arguments:

function sayHi() {
  for(var i=0; i < arguments.length; i++) {
    alert(Hi+ arguments[i])
  }
}
sayHi(Cat, Alice)  // 'Hi, Cat', then 'Hi, Alice'

javascript will pack arguments into special array arguments which contains all parameters by their number: arguments[0], arguments[1] etc.

And this what allows to perform a small magic in Nitrogen.

Module action_event.erl contains implementation for #event{} action.

When you create #event{} action:

#event { type=click, postback=myevent }

Nitrogen calls the following piece of code which will bind click event to a given control and call a function anonymous(event) when the click happens.

 [
   wf:f(Nitrogen.$observe_event('~s', '~s', '~s', function anonymous(event) {, [Anchor, Trigger, Type]), 
       AnchorScript, PostbackScript, WireAction, 
    });
 ]

The important part here is PostbackScript parameter which is created by the following code:

generate_postback_script(Postback, Anchor, ValidationGroup, Delegate, ExtraParam);
    PickledPostbackInfo = serialize_event_context(Postback, Anchor, ValidationGroup, Delegate),
    wf:f(Nitrogen.$queue_event('~s', '~s', ~s), [ValidationGroup, PickledPostbackInfo, ExtraParam]).

The way anonymous(event) function is built, ExtraParam has access to the arguments array for this function and we can add extra parameters to postback which we pass to Nitrogen.$queue_event().

here is the example for ‘jqGridSelectRow’ event:

1. first we define a #jqgrid_event{} action which calls standard Nitrogen #event{} and we specify extra_param option which uses argument array of event function:

render_action(#jqgrid_event{target = Target, type = ?ONSELECTROW, postback = Postback});
    #event{target = Target, type = ?ONSELECTROW, postback = {?ONSELECTROW, Postback},
	   delegate = ?JQGRID_ELEMENT#jqgrid.module, extra_param=&quot;\&quot;&amp;rowid=\&quot; + arguments[1] + status=+ arguments[2]};

2. We use this action the following way while specifying options for #jqgrid{} element:

actions = [#jqgrid_event{trigger = jqgrid, target = jqgrid, type = ?ONSELECTROW, postback = select_row}]

3. when row in the jqgrid is clicked, Nitrogen will call function anonymous(event) which have extra bit of logic which we inserted with extra_param option. This piece has access to arguments array of the function which we use to build return postback string with extra details. The string is then sent to “Nitrogen.$queue_event() which generates and sends a postback back to webserver. This postback is caught in event function of element_jqgrid.erl module:

event({?ONSELECTROW, Postback});
    %% ?PRINT({jqgrid_event, ?ONSELECTROW}),
    RowId = wf:q(rowid),
    Status = wf:q(status),
    Module = wf:page_module(),
    Module:jqgrid_event({Postback, {RowId, Status}});

notice, that at this point we can use wf:q(rowid) function and select the values from query string which returned with POST.

see full example here:

Nitrogen_Elements
Nitrogen Elements Examples

Advertisements
This entry was posted in custom Nitrogen elements, Erlang, Nitrogen and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s