Kosmetik: Kopieroperationen zusammenfassen.
[kivitendo-erp.git] / SL / ClientJS.pm
index d58905e..ada199e 100644 (file)
@@ -14,7 +14,7 @@ use Rose::Object::MakeMethods::Generic
 
 my %supported_methods = (
   # ## Non-jQuery methods ##
-  flash        => 2,            # display_flash(<TARGET>, <ARGS>)
+  flash        => 2,            # kivi.display_flash(<TARGET>, <ARGS>)
 
   # ## jQuery basics ##
 
@@ -70,6 +70,16 @@ my %supported_methods = (
   # Form Events
   focus        => 1,
 
+  # Generic Event Handling ## pattern: $(<TARGET>).<FUNCTION>(<ARG1>, kivi.get_function_by_name(<ARG2>))
+  on           => 3,
+  off          => 3,
+  one          => 3,
+
+  # ## jQuery UI dialog plugin ## pattern: $(<TARGET>).dialog('<FUNCTION>')
+
+  # Closing and removing the popup
+  'dialog:close'         => 1,
+
   # ## jstree plugin ## pattern: $.jstree._reference($(<TARGET>)).<FUNCTION>(<ARGS>)
 
   # Operations on the whole tree
@@ -98,6 +108,8 @@ my %supported_methods = (
 
   # ## other stuff ##
   redirect_to            => 1,  # window.location.href = <TARGET>
+
+  reinit_widgets         => 0,  # kivi.reinit_widgets()
 );
 
 sub AUTOLOAD {
@@ -120,10 +132,10 @@ sub action {
   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+//;
+  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';
+    $args[$idx] =~ s/^\s+//         if !ref($args[$idx]);
   }
 
   push @{ $self->_actions }, [ $method, @args ];
@@ -163,6 +175,7 @@ sub to_array {
 
 sub render {
   my ($self, $controller) = @_;
+  $self->reinit_widgets if $::request->presenter->need_reinit_widgets;
   return $controller->render(\$self->to_json, { type => 'json' });
 }
 
@@ -172,6 +185,12 @@ sub jstree {
   return $self;
 }
 
+sub dialog {
+  my ($self) = @_;
+  $self->{_prefix} = 'dialog:';
+  return $self;
+}
+
 sub flash {
   my ($self, $type, @messages) = @_;
 
@@ -212,12 +231,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:
 
@@ -249,6 +268,9 @@ 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);
 
@@ -273,7 +295,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<eval_json_response()> with the result returned from the server.
+=item 2. The client code needs to call C<kivi.eval_json_result()> with the result returned from the server.
 
 =item 3. The server must use this module.
 
@@ -311,6 +333,14 @@ to the following:
 
   $controller->render(\$self->to_json, { type => 'json' });
 
+=item C<dialog>
+
+Tells C<$self> that the next action is to be called on a jQuery UI
+dialog instance, e.g. one opened by C<kivi.popup_dialog()>. For
+example:
+
+  $js->dialog->close('#jqueryui_popup_dialog');
+
 =item C<jstree>
 
 Tells C<$self> that the next action is to be called on a jstree
@@ -392,8 +422,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<flash> 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-E<gt>error(...)>.
 
 =item C<error $message>
 
@@ -456,6 +486,15 @@ C<data>, C<removeData>
 
 C<focus>
 
+=item Generic Event Handlers
+
+C<on>, C<off>, C<one>
+
+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