X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FClientJS.pm;h=c12b9ea24b72686518a28b12e45f16871073e10c;hb=c51601f019f963dcdc875469514aa40802b5c574;hp=d58905e75986cb90178a56a7f3a6a30d3164dc0e;hpb=2738c03e1340255baade2fd357aafbbfd1347d5e;p=kivitendo-erp.git diff --git a/SL/ClientJS.pm b/SL/ClientJS.pm index d58905e75..c12b9ea24 100644 --- a/SL/ClientJS.pm +++ b/SL/ClientJS.pm @@ -9,13 +9,11 @@ use SL::JSON (); use Rose::Object::MakeMethods::Generic ( + scalar => [ qw(controller) ], 'scalar --get_set_init' => [ qw(_actions _flash _error) ], ); my %supported_methods = ( - # ## Non-jQuery methods ## - flash => 2, # display_flash(, ) - # ## jQuery basics ## # Basic effects @@ -68,7 +66,21 @@ my %supported_methods = ( removeData => 2, # Form Events - focus => 1, + focus => 1, # kivi.set_focus() + + # Generic Event Handling ## pattern: $().(, kivi.get_function_by_name()) + on => 3, + off => 3, + one => 3, + + # ## jQuery UI dialog plugin ## pattern: $().dialog('') + + # Opening and closing and closing a popup + 'dialog:open' => 1, # kivi.popup_dialog() + 'dialog:close' => 1, + + # ## jQuery Form plugin ## + 'ajaxForm' => 1, # pattern: $().ajaxForm({ success: eval_json_result }) # ## jstree plugin ## pattern: $.jstree._reference($()).() @@ -96,8 +108,18 @@ my %supported_methods = ( 'jstree:deselect_node' => 2, 'jstree:deselect_all' => 1, + # ## ckeditor stuff ## + 'focus_ckeditor' => 1, # kivi.focus_ckeditor_when_ready() + # ## other stuff ## redirect_to => 1, # window.location.href = + + flash => 2, # kivi.display_flash(, ) + reinit_widgets => 0, # kivi.reinit_widgets() + run => -1, # kivi.run(, ) + run_once_for => 3, # kivi.run_once_for(, ) + + scroll_into_view => 1, # $()[0].scrollIntoView() ); sub AUTOLOAD { @@ -118,12 +140,18 @@ sub action { my $num_args = $supported_methods{$method}; croak "Unsupported jQuery action: $method" unless defined $num_args; - croak "Parameter count mismatch for $method(actual: " . scalar(@args) . " wanted: $num_args)" if scalar(@args) != $num_args; - if ($num_args) { - # Force flattening from SL::Presenter::EscapedText: "" . $... - $args[0] = "" . $args[0]; - $args[0] =~ s/^\s+//; + if ($num_args > 0) { + croak "Parameter count mismatch for $method(actual: " . scalar(@args) . " wanted: $num_args)" if scalar(@args) != $num_args; + } else { + $num_args *= -1; + croak "Parameter count mismatch for $method(actual: " . scalar(@args) . " wanted at least: $num_args)" if scalar(@args) < $num_args; + $num_args = scalar @args; + } + + foreach my $idx (0..$num_args - 1) { + # Force flattening from SL::Presenter::EscapedText and trim leading whitespace for scalars + $args[$idx] = "" . $args[$idx] if ref($args[$idx]) eq 'SL::Presenter::EscapedText'; } push @{ $self->_actions }, [ $method, @args ]; @@ -163,6 +191,8 @@ sub to_array { sub render { my ($self, $controller) = @_; + $controller ||= $self->controller; + $self->reinit_widgets if $::request->presenter->need_reinit_widgets; return $controller->render(\$self->to_json, { type => 'json' }); } @@ -172,6 +202,18 @@ sub jstree { return $self; } +sub dialog { + my ($self) = @_; + $self->{_prefix} = 'dialog:'; + return $self; +} + +sub ckeditor { + my ($self) = @_; + $self->{_prefix} = 'ckeditor:'; + return $self; +} + sub flash { my ($self, $type, @messages) = @_; @@ -212,12 +254,12 @@ with jQuery First some JavaScript code: // In the client generate an AJAX request whose 'success' handler - // calls "eval_json_response(data)": + // calls "eval_json_result(data)": var data = { action: "SomeController/the_action", id: $('#some_input_field').val() }; - $.post("controller.pl", data, eval_json_response); + $.post("controller.pl", data, eval_json_result); Now some Perl code: @@ -231,7 +273,7 @@ Now some Perl code: my ($self) = @_; # Create a new client-side JS object and do stuff with it! - my $js = SL::ClientJS->new; + my $js = SL::ClientJS->new(controller => $self); # Show some element on the page: $js->show('#usually_hidden'); @@ -249,12 +291,15 @@ Now some Perl code: $js->jstree->rename_node('#tb-' . $text_block->id, $text_block->title) ->jstree->select_node('#tb-' . $text_block->id); + # Close a popup opened by kivi.popup_dialog(): + $js->dialog->close('#jqueryui_popup_dialog'); + # Finally render the JSON response: $self->render($js); # Rendering can also be chained, e.g. $js->html('#selector', $html) - ->render($self); + ->render; } =head1 OVERVIEW @@ -273,7 +318,7 @@ There are three things that need to be done for this to work: =item 1. The "client_js.js" has to be loaded before the AJAX request is started. -=item 2. The client code needs to call C with the result returned from the server. +=item 2. The client code needs to call C with the result returned from the server. =item 3. The server must use this module. @@ -304,13 +349,24 @@ are the function parameters. Returns the actions gathered so far as a JSON string ready to be sent to the client. -=item C +=item C Renders C<$self> via the controller. Useful for chaining. Equivalent to the following: $controller->render(\$self->to_json, { type => 'json' }); +The controller instance to use can be set during object creation (see +synopsis) or as an argument to C. + +=item C + +Tells C<$self> that the next action is to be called on a jQuery UI +dialog instance, e.g. one opened by C. For +example: + + $js->dialog->close('#jqueryui_popup_dialog'); + =item C Tells C<$self> that the next action is to be called on a jstree @@ -392,8 +448,8 @@ But it is easier to integrate into a method call chain, e.g.: Display a C<$message> in the flash of type C<$type>. Multiple calls of C on the same C<$self> will be merged by type. -On the client side the flash of this type will be cleared before the -message is shown. +On the client side the flashes of all types will be cleared after each +successful ClientJS call that did not end with C<$js-Eerror(...)>. =item C @@ -414,6 +470,26 @@ L. =back +=head2 KIVITENDO FUNCTIONS + +The following functions from the C namespace are supported: + +=over 4 + +=item Displaying stuff + +C (don't call directly, use L instead) + +=item Running functions + +C, C + +=item Widgets + +C + +=back + =head2 JQUERY FUNCTIONS The following jQuery functions are supported: @@ -448,6 +524,10 @@ C, C C, C, C, C, C +=item Class attributes + +C, C, C + =item Data storage C, C @@ -456,15 +536,56 @@ C, C C +=item Generic Event Handlers + +C, C, C + +These attach/detach event listeners to specific selectors. The first +argument is the selector, the second the name of the events and the +third argument is the name of the handler function. That function must +already exist when the handler is added. + =back -=head2 JSTREE JQUERY PLUGIN +=head2 JQUERY POPUP DIALOG PLUGIN + +Supported functions of the C plugin to jQuery. They are +invoked by first calling C in the ClientJS instance and then +the function itself: + + $js->dialog->close(...); + +=over 4 -The following functions of the C plugin to jQuery are +=item Closing and removing the popup + +C + +=back + +=head2 AJAXFORM JQUERY PLUGIN + +The following functions of the C plugin to jQuery are supported: =over 4 +=item All functions by the generic accessor function: + +C + +=back + +=head2 JSTREE JQUERY PLUGIN + +Supported functions of the C plugin to jQuery. They are +invoked by first calling C in the ClientJS instance and then +the function itself: + + $js->jstree->open_node(...); + +=over 4 + =item Operations on the whole tree C, C @@ -495,7 +616,10 @@ C accordingly. The steps are: =item 1. Add lines in this file to the C<%supported_methods> hash. The key is the function name and the value is the number of expected -parameters. +parameters. The value can be negative to indicate that the function +takes at least the absolute of this value as parameters and optionally +more. In such a case the CARGSE> format expands to an actual +array (and the individual elements if the value is positive>. =item 2. Run C. It will generate C automatically.