Browse Source

validation notifications for postback elements

Namdak Tonpa 9 years ago
parent
commit
87adfe9781

+ 40 - 39
include/nitro.hrl

@@ -6,7 +6,8 @@
 -define(ELEMENT_BASE(Module), ?ELEMENT_BASE(Module,undefined,undefined)).
 -define(ELEMENT_BASE(Module,Tag,Delegate),
         ancestor=element, id, module=Module, delegate=Delegate, validation=[], actions, class=[], style=[], source=[], onmouseover, onkeypress, onchange, onkeyup, onkeydown, onclick,
-        data_fields=[], aria_states=[], body, role, tabindex, show_if=true, html_tag=Tag, title, accesskey, contenteditable, contextmenu, dir, draggable, dropzone, hidden, lang, spellcheck, translate, onafterprint, onbeforeprint, onbeforeunload, onblur, onerror, onfocus, onhashchange, onload, onmessage, onoffline, ononline, onpagehide, onpageshow, onpopstate, onresize, onstorage, onunload).
+        data_fields=[], aria_states=[], body, role, tabindex, show_if=true, html_tag=Tag, title, postback=[], accesskey, contenteditable, contextmenu, dir, draggable, dropzone,
+        hidden, lang, spellcheck, translate, onafterprint, onbeforeprint, onbeforeunload, onblur, onerror, onfocus, onhashchange, onload, onmessage, onoffline, ononline, onpagehide, onpageshow, onpopstate, onresize, onstorage, onunload).
 -define(ACTION_BASE(Module), ancestor=action, trigger, target, module=Module, actions, source=[]).
 -define(CTRL_BASE(Module), ?ELEMENT_BASE(Module,undefined,Module)).
 
@@ -14,7 +15,7 @@
 -record(literal, {?ELEMENT_BASE(element_literal)}).
 -record(dtl, {?ELEMENT_BASE(element_dtl), file="index", bindings=[], app=web, folder="priv/templates", ext="html", bind_script=true, js_escape=false }).
 -record(list, {?ELEMENT_BASE(element_list), numbered=false }).
--record(dropdown, {?ELEMENT_BASE(element_dropdown), options, postback, value, multiple=false, disabled=false, name}).
+-record(dropdown, {?ELEMENT_BASE(element_dropdown), options, value, multiple=false, disabled=false, name}).
 -record(radiogroup, {?ELEMENT_BASE(element_radiogroup)}).
 -record(spinner, {?ELEMENT_BASE(element_spinner), image="/nitrogen/spinner.gif"}).
 
@@ -45,47 +46,47 @@
 -record(video,       {?ELEMENT_BASE(element_video), autoplay, controls, height, loop, mediagroup, muted, poster, preload, src, width}).
 
 % HTML Form
--record(button,       {?ELEMENT_BASE(element_button), autofocus, disabled, form, formaction, formenctype, formmethod, formtarget, formnovalidate, name, type= <<"button">>, value, postback}).
+-record(button,       {?ELEMENT_BASE(element_button), autofocus, disabled, form, formaction, formenctype, formmethod, formtarget, formnovalidate, name, type= <<"button">>, value}).
 -record(datalist,       ?DEFAULT_BASE).
 -record(fieldset,       {?ELEMENT_BASE(element_fieldset), disabled, form, name, legend}).
 -record(form,       {?ELEMENT_BASE(element_form), accept_charset, action, autocomplete, enctype, method, name, novalidate, target}).
--record(keygen,       {?ELEMENT_BASE(element_keygen), autofocus, challenge, disabled, form, keytype, name, postback}).
+-record(keygen,       {?ELEMENT_BASE(element_keygen), autofocus, challenge, disabled, form, keytype, name}).
 -record(legend,       ?DEFAULT_BASE).
--record(label,       {?ELEMENT_BASE(element_label), for, form, postback}).
--record(meter,       {?ELEMENT_BASE(element_meter), high, low, max, min, optimum, value, postback}).
+-record(label,       {?ELEMENT_BASE(element_label), for, form}).
+-record(meter,       {?ELEMENT_BASE(element_meter), high, low, max, min, optimum, value}).
 -record(optgroup,       {?ELEMENT_BASE(element_select), disabled, label}).
--record(option,       {?ELEMENT_BASE(element_select), disabled, label, selected=false, value, postback}).
--record(output,       {?ELEMENT_BASE(element_output), for, form, name, postback}).
--record(progress,       {?ELEMENT_BASE(element_progress), max, value, postback}).
--record(select,       {?ELEMENT_BASE(element_select), autofocus, disabled, form, multiple, name, required, size, postback}).
--record(textarea,       {?ELEMENT_BASE(element_textarea), autofocus, cols, dirname, disabled, form, maxlength, name, placeholder, readonly, required, rows, wrap, postback, value}).
+-record(option,       {?ELEMENT_BASE(element_select), disabled, label, selected=false, value}).
+-record(output,       {?ELEMENT_BASE(element_output), for, form, name}).
+-record(progress,       {?ELEMENT_BASE(element_progress), max, value}).
+-record(select,       {?ELEMENT_BASE(element_select), autofocus, disabled, form, multiple, name, required, size}).
+-record(textarea,       {?ELEMENT_BASE(element_textarea), autofocus, cols, dirname, disabled, form, maxlength, name, placeholder, readonly, required, rows, wrap, value}).
 
 % HTML Form inputs
--record(input,       {?ELEMENT_BASE(element_input),  autofocus, disabled, form, name, value, postback, type=[], placeholder, multiple, min, max}).
--record(input_button,       {?ELEMENT_BASE(element_input_button),  autofocus, disabled, form, name, value, postback}).
--record(checkbox,           {?ELEMENT_BASE(element_checkbox),  autofocus, checked=false, disabled, form, name, required, value, postback}).
--record(color,           {?ELEMENT_BASE(element_color),  autocomplete, autofocus, disabled, form, list, name, value, postback}).
--record(date,           {?ELEMENT_BASE(element_date),  autocomplete, autofocus, disabled, form, list, max, min, name, step, readonly, required, value, postback}).
--record(calendar,       {?ELEMENT_BASE(element_calendar),  autocomplete, autofocus, disabled, form, list, maxDate, minDate, format, name, step, readonly, required, value, postback}).
--record(datetime,           {?ELEMENT_BASE(element_datetime),  autocomplete, autofocus, disabled, form, list, max, min, name, step, readonly, required, value, postback}).
--record(datetime_local,           {?ELEMENT_BASE(element_datetime_local),  autocomplete, autofocus, disabled, form, list, max, min, name, step, readonly, required, value, postback}).
--record(email,           {?ELEMENT_BASE(element_email),  autocomplete, autofocus, disabled, form, list, maxlength, multiple, name, pattern, placeholder, readonly, required, size, value, postback}).
--record(file,           {?ELEMENT_BASE(element_file),  accept, autofocus, disabled, form, multiple, name, required, postback}).
--record(hidden,           {?ELEMENT_BASE(element_hidden),  disabled, form, name, value, postback, html_name}).
--record(input_image,           {?ELEMENT_BASE(element_input_image),  alt, autofocus, disabled, form, formaction, formenctype, formmethod, formnovalue, formtarget, height, name, src, width, postback}).
--record(month,              {?ELEMENT_BASE(element_month),  alt, autocomplite, autofocus, disabled, form, list, min, max, name, readonly, required, step, value, postback}).
--record(number,              {?ELEMENT_BASE(element_number),  autocomplete, autofocus, disabled, form, list, max, min, name, placeholder, readonly, required, step, value, postback}).
--record(password,              {?ELEMENT_BASE(element_password),  autocomplete, autofocus, disabled, form, maxlength, name, pattern, placeholder, readonly, required, size, value, postback}).
--record(radio,              {?ELEMENT_BASE(element_radio),  autofocus, checked, disabled, form, name, required, value, postback, html_name}).
--record(range,              {?ELEMENT_BASE(element_range),  autocomplete, autofocus, disabled, form, list, max=100, min=0, name, step=1, value, postback}).
--record(reset,              {?ELEMENT_BASE(element_reset),  autofocus, disabled, form, name, value, postback}).
--record(search,              {?ELEMENT_BASE(element_search),  autocomplete, autofocus, dirname, disabled, form, list, maxlength, name, pattern, placeholder, readonly, required, size, value, postback}).
--record(submit,              {?ELEMENT_BASE(element_submit),  autofocus, disabled, form, formaction, formenctype, formmethod, formnovalidate, formtarget, name, value, postback, click}).
--record(tel,              {?ELEMENT_BASE(element_tel),  autocomplete, autofocus, disabled, form, list, maxlength, name, pattern, placeholder, readonly, required, size, value, postback}).
--record(textbox,              {?ELEMENT_BASE(element_textbox),  autocomplete, autofocus, dirname, disabled, form, list, maxlength, name, pattern, placeholder, readony, required, size, value, postback}).
--record(input_time,              {?ELEMENT_BASE(element_input_time),  autocomplete, autofocus, disabled, form, list, max, min, name, step, readonly, required, value, postback}).
--record(url,              {?ELEMENT_BASE(element_url),  autocomplete, autofocus, disabled, form, list, maxlength, name, pattern, placeholder, readonly, required, size, value, postback}).
--record(week,              {?ELEMENT_BASE(element_week),  autocomplete, autofocus, disabled, form, list, max, min, name, readonly, required, step, value, postback}).
+-record(input,       {?ELEMENT_BASE(element_input),  autofocus, disabled, form, name, value, type=[], placeholder, multiple, min, max}).
+-record(input_button,       {?ELEMENT_BASE(element_input_button),  autofocus, disabled, form, name, value}).
+-record(checkbox,           {?ELEMENT_BASE(element_checkbox),  autofocus, checked=false, disabled, form, name, required, value}).
+-record(color,           {?ELEMENT_BASE(element_color),  autocomplete, autofocus, disabled, form, list, name, value}).
+-record(date,           {?ELEMENT_BASE(element_date),  autocomplete, autofocus, disabled, form, list, max, min, name, step, readonly, required, value}).
+-record(calendar,       {?ELEMENT_BASE(element_calendar),  autocomplete, autofocus, disabled, form, list, maxDate, minDate, format, name, step, readonly, required, value}).
+-record(datetime,           {?ELEMENT_BASE(element_datetime),  autocomplete, autofocus, disabled, form, list, max, min, name, step, readonly, required, value}).
+-record(datetime_local,           {?ELEMENT_BASE(element_datetime_local),  autocomplete, autofocus, disabled, form, list, max, min, name, step, readonly, required, value}).
+-record(email,           {?ELEMENT_BASE(element_email),  autocomplete, autofocus, disabled, form, list, maxlength, multiple, name, pattern, placeholder, readonly, required, size, value}).
+-record(file,           {?ELEMENT_BASE(element_file),  accept, autofocus, disabled, form, multiple, name, required}).
+-record(hidden,           {?ELEMENT_BASE(element_hidden),  disabled, form, name, value, html_name}).
+-record(input_image,           {?ELEMENT_BASE(element_input_image),  alt, autofocus, disabled, form, formaction, formenctype, formmethod, formnovalue, formtarget, height, name, src, width}).
+-record(month,              {?ELEMENT_BASE(element_month),  alt, autocomplite, autofocus, disabled, form, list, min, max, name, readonly, required, step, value}).
+-record(number,              {?ELEMENT_BASE(element_number),  autocomplete, autofocus, disabled, form, list, max, min, name, placeholder, readonly, required, step, value}).
+-record(password,              {?ELEMENT_BASE(element_password),  autocomplete, autofocus, disabled, form, maxlength, name, pattern, placeholder, readonly, required, size, value}).
+-record(radio,              {?ELEMENT_BASE(element_radio),  autofocus, checked, disabled, form, name, required, value, html_name}).
+-record(range,              {?ELEMENT_BASE(element_range),  autocomplete, autofocus, disabled, form, list, max=100, min=0, name, step=1, value}).
+-record(reset,              {?ELEMENT_BASE(element_reset),  autofocus, disabled, form, name, value}).
+-record(search,              {?ELEMENT_BASE(element_search),  autocomplete, autofocus, dirname, disabled, form, list, maxlength, name, pattern, placeholder, readonly, required, size, value}).
+-record(submit,              {?ELEMENT_BASE(element_submit),  autofocus, disabled, form, formaction, formenctype, formmethod, formnovalidate, formtarget, name, value, click}).
+-record(tel,              {?ELEMENT_BASE(element_tel),  autocomplete, autofocus, disabled, form, list, maxlength, name, pattern, placeholder, readonly, required, size, value}).
+-record(textbox,              {?ELEMENT_BASE(element_textbox),  autocomplete, autofocus, dirname, disabled, form, list, maxlength, name, pattern, placeholder, readony, required, size, value}).
+-record(input_time,              {?ELEMENT_BASE(element_input_time),  autocomplete, autofocus, disabled, form, list, max, min, name, step, readonly, required, value}).
+-record(url,              {?ELEMENT_BASE(element_url),  autocomplete, autofocus, disabled, form, list, maxlength, name, pattern, placeholder, readonly, required, size, value}).
+-record(week,              {?ELEMENT_BASE(element_week),  autocomplete, autofocus, disabled, form, list, max, min, name, readonly, required, step, value}).
 
 % HTML Interactive
 -record(command,       {?ELEMENT_BASE(element_command),  checked, disabled, icon, label, radiogroup, type= <<"command">>}).
@@ -145,10 +146,10 @@
 -record(tfoot,       	?DEFAULT_BASE).
 -record(th, 			{?ELEMENT_BASE(element_th), colspan=1, headers, rowspan=1, scope}).
 -record(thead,       	?DEFAULT_BASE).
--record(tr, 			{?ELEMENT_BASE(element_tr), cells, postback}).
+-record(tr, 			{?ELEMENT_BASE(element_tr), cells}).
 
 % HTML Text-level semantics
--record(link,           {?ELEMENT_BASE(element_link),  href, hreflang, media, rel, target, type, url="javascript:void(0);", download, name, postback}).
+-record(link,           {?ELEMENT_BASE(element_link),  href, hreflang, media, rel, target, type, url="javascript:void(0);", download, name}).
 -record(abbr,       	?DEFAULT_BASE).
 -record(b,       		?DEFAULT_BASE).
 -record(bdi,       		?DEFAULT_BASE).
@@ -179,7 +180,7 @@
 -record(action,  {?ACTION_BASE(undefined)}).
 -record(wire,    {?ACTION_BASE(action_wire)}).
 -record(api,     {?ACTION_BASE(action_api), name, tag, delegate }).
--record(event,   {?ACTION_BASE(action_event), type=default, postback, delegate}).
+-record(event,   {?ACTION_BASE(action_event), type=default, postback, delegate, validation=[]}).
 -record(alert,   {?ACTION_BASE(action_alert), text}).
 -record(confirm, {?ACTION_BASE(action_confirm), text, postback, delegate}).
 -record(jq,      {?ACTION_BASE(action_jq), property, method, args=[], right, format="~s"}).

+ 2 - 2
src/actions/action_event.erl

@@ -10,7 +10,7 @@ render_action(#event{postback={bin,Value},target=Control,type=Type}) ->
     [list_to_binary([<<"qi('">>,nitro:to_binary(Control),<<"').addEventListener('">>,
         nitro:to_binary(Type),<<"',function (event){">>,PostbackBin,<<"});">>])];
 
-render_action(#event{postback=Postback,actions=_Actions,source=Source,target=Control,type=Type,delegate=Delegate}) ->
+render_action(#event{postback=Postback,actions=_Actions,source=Source,target=Control,type=Type,delegate=Delegate,validation=Validation}) ->
     Element = nitro:to_list(Control),
     Data=list_to_binary([<<"[tuple(tuple(utf8_toByteArray('">>,Element,<<"'),bin('detail')),event.detail)">>,
          [ begin {SrcType,Src2}=case is_atom(Src) of
@@ -18,7 +18,7 @@ render_action(#event{postback=Postback,actions=_Actions,source=Source,target=Con
                  false -> { <<"utf8_toByteArray">>,Src } end,
              [ <<",tuple(">>,SrcType,<<"('">>,Src2,<<"'),querySource('">>,Src2,<<"'))">> ]
              end || Src <- Source ],<<"]">>]),
-    PostbackBin = wf_event:new(Postback, Element, Delegate, event, Data, Source),
+    PostbackBin = wf_event:new(Postback, Element, Delegate, event, Data, Source, Validation),
     [list_to_binary([<<"{var x=qi('">>,Element,<<"'); x && x.addEventListener('">>,
         nitro:to_binary(Type),<<"',function (event){">>,
         PostbackBin,<<"});};">>])].

+ 1 - 1
src/elements/element_link.erl

@@ -9,7 +9,7 @@ render_element(Record) ->
         Postback ->
             ID = case Record#link.id of undefined -> nitro:temp_id(); I -> I end,
             nitro:wire(#event{ type=click,postback=Postback,target=ID,
-                            source=Record#link.source,delegate=Record#link.delegate}),
+                            source=Record#link.source,delegate=Record#link.delegate,validation=Record#link.validation}),
             ID end,
     List = [
       % global

+ 7 - 6
src/render/wf_event.erl

@@ -7,16 +7,17 @@
 -record(cx, { handlers, actions, req, module, lang, path, session, params, form, state=[] }).
 -define(CTX, (get(context))).
 
-new(bin,Data) -> <<"ws.send(enc(tuple(atom('bin'),bin('",(nitro:pickle(Data))/binary,"'))));">>.
+new(P,E,D,N,Data,Source) -> new(P,E,D,N,Data,Source,<<>>).
 
-new(undefined, _, _, _, _, _) -> <<>>;
-new(Postback, Element, Delegate, Name, Data, Source) ->
+new(bin,Data) -> <<"ws.send(enc(tuple(atom('bin'),bin('",(nitro:pickle(Data))/binary,"'))));">>.
+new(undefined, _, _, _, _, _, _) -> <<>>;
+new(Postback, Element, Delegate, Name, Data, Source, Validation) ->
     Module = nitro:coalesce([Delegate, ?CTX#cx.module]),
     Join=fun([]) -> []; ([E]) -> [$'|E]++[$'];
         ([H|T]) -> [[$'|H]++[$']] ++ [ [$,,$'|E]++[$'] || E <- T ] end,
     Event = #ev{name=Name, module=Module, msg=Postback, trigger=Element},
     erlang:list_to_binary([ <<"{ if (validateSources([">>,
         Join([ case is_atom(S) of true -> atom_to_list(S); false -> S end || S <- Source, S =/= []]),
-        <<"])) ws.send(enc(tuple(atom('">>,nitro:to_binary(application:get_env(n2o,event,pickle)),
-        <<"'),bin('">>,Element,<<"'),bin('">>,nitro:pickle(Event),<<"'),">>,Data,
-        <<")));else console.log('Validation Error'); }">> ]).
+        <<"])) { ">>,nitro:to_binary(Validation),<<" ws.send(enc(tuple(atom('">>,
+        nitro:to_binary(application:get_env(n2o,event,pickle)),<<"'),bin('">>,Element,<<"'),bin('">>,
+        nitro:pickle(Event),<<"'),">>,Data,<<"))); } else console.log('Validation Error'); }">> ]).

+ 3 - 3
src/render/wf_render_elements.erl

@@ -13,12 +13,12 @@ render_element(Element) when is_tuple(Element) ->
     Tag = case element(#element.html_tag,Element) of undefined -> nitro:to_binary(element(1, Element)); T -> T end,
     case element(#element.validation,Element) of
          [] -> skip;
-         Code ->
+         Code when element(#element.postback,Element) == [] ->
          nitro:wire(nitro:f("{var name='~s'; qi(name)"
            ".addEventListener('validation',"
               "function(e) { if (!(~s)) e.preventDefault(); });"
-              "qi(name).validation = true;}",[Id,Code]))
-            end,
+              "qi(name).validation = true;}",[Id,Code]));
+         _ -> skip end,
     case element(#element.module,Element) of
         undefined ->
 	    default_render(Tag, Element);