DeliveryOrder - Doku und Typos
[kivitendo-erp.git] / SL / ClientJS.pm
index fcc2c14..335bf81 100644 (file)
@@ -9,6 +9,7 @@ use SL::JSON ();
 
 use Rose::Object::MakeMethods::Generic
 (
+  scalar                  => [ qw(controller) ],
   'scalar --get_set_init' => [ qw(_actions _flash _error) ],
 );
 
@@ -74,7 +75,8 @@ my %supported_methods = (
 
   # ## jQuery UI dialog plugin ## pattern: $(<TARGET>).dialog('<FUNCTION>')
 
-  # Closing and removing the popup
+  # Opening and closing and closing a popup
+  'dialog:open'          => 1, # kivi.popup_dialog(<TARGET>)
   'dialog:close'         => 1,
 
   # ## jQuery Form plugin ##
@@ -116,8 +118,12 @@ my %supported_methods = (
   reinit_widgets         => 0,  # kivi.reinit_widgets()
   run                    => -1, # kivi.run(<TARGET>, <ARGS>)
   run_once_for           => 3,  # kivi.run_once_for(<TARGET>, <ARGS>)
+
+  scroll_into_view       => 1,  # $(<TARGET>)[0].scrollIntoView()
 );
 
+my %trim_target_for = map { ($_ => 1) } qw(insertAfter insertBefore appendTo prependTo);
+
 sub AUTOLOAD {
   our $AUTOLOAD;
 
@@ -135,10 +141,10 @@ sub action {
   $method      =  (delete($self->{_prefix}) || '') . $method;
   my $num_args =  $supported_methods{$method};
 
-  croak "Unsupported jQuery action: $method"                                                    unless defined $num_args;
+  croak "Unsupported jQuery action: $method" unless defined $num_args;
 
   if ($num_args > 0) {
-    croak "Parameter count mismatch for $method(actual: " . scalar(@args) . " wanted: $num_args)" if scalar(@args) != $num_args;
+    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;
@@ -146,11 +152,15 @@ sub action {
   }
 
   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]);
+    # Force flattening from SL::Presenter::EscapedText.
+    $args[$idx] = "" . $args[$idx] if ref($args[$idx]) eq 'SL::Presenter::EscapedText';
   }
 
+  # Trim leading whitespaces for certain jQuery functions that operate
+  # on HTML code: $("<p>test</p>").appendTo('#some-id'). jQuery croaks
+  # on leading whitespaces, e.g. on $(" <p>test</p>").
+  $args[0] =~ s{^\s+}{} if $trim_target_for{$method};
+
   push @{ $self->_actions }, [ $method, @args ];
 
   return $self;
@@ -188,6 +198,7 @@ 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' });
 }
@@ -269,7 +280,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');
@@ -295,7 +306,7 @@ Now some Perl code:
 
     # Rendering can also be chained, e.g.
     $js->html('#selector', $html)
-       ->render($self);
+       ->render;
   }
 
 =head1 OVERVIEW
@@ -345,13 +356,16 @@ are the function parameters.
 Returns the actions gathered so far as a JSON string ready to be sent
 to the client.
 
-=item C<render $controller>
+=item C<render [$controller]>
 
 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<render>.
+
 =item C<dialog>
 
 Tells C<$self> that the next action is to be called on a jQuery UI