X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FClientJS.pm;h=7eb092c4733c98c23ecc0779cbc4020aca76702f;hb=3ac83c6134a876990a2b5e26075e4304b3ce1cae;hp=99598afc6323d726331f7341fa073d2b5b5d7837;hpb=128f310047ce6d3dc7a42fa2384a1fe9bf88a36d;p=kivitendo-erp.git diff --git a/SL/ClientJS.pm b/SL/ClientJS.pm index 99598afc6..7eb092c47 100644 --- a/SL/ClientJS.pm +++ b/SL/ClientJS.pm @@ -9,10 +9,13 @@ use SL::JSON (); use Rose::Object::MakeMethods::Generic ( - 'scalar --get_set_init' => [ qw(_actions) ], + 'scalar --get_set_init' => [ qw(_actions _flash _error) ], ); my %supported_methods = ( + # ## Non-jQuery methods ## + flash => 2, # kivi.display_flash(, ) + # ## jQuery basics ## # Basic effects @@ -55,6 +58,11 @@ my %supported_methods = ( removeProp => 2, val => 2, + # Class attribute + addClass => 2, + removeClass => 2, + toggleClass => 2, + # Data storage data => 3, removeData => 2, @@ -62,6 +70,11 @@ my %supported_methods = ( # Form Events focus => 1, + # ## jqModal plugin ## + + # Closing and removing the popup + jqmClose => 1, + # ## jstree plugin ## pattern: $.jstree._reference($()).() # Operations on the whole tree @@ -78,6 +91,7 @@ my %supported_methods = ( 'jstree:reopen' => 1, # Modifying nodes + 'jstree:create_node' => 4, 'jstree:rename_node' => 3, 'jstree:delete_node' => 2, 'jstree:move_node' => 5, @@ -86,6 +100,11 @@ my %supported_methods = ( 'jstree:select_node' => 2, # $.jstree._reference($()).(, true) 'jstree:deselect_node' => 2, 'jstree:deselect_all' => 1, + + # ## other stuff ## + redirect_to => 1, # window.location.href = + + reinit_widgets => 0, # kivi.reinit_widgets() ); sub AUTOLOAD { @@ -119,12 +138,28 @@ sub action { return $self; } +sub action_if { + my ($self, $condition, @args) = @_; + + return $condition ? $self->action(@args) : $self; +} + sub init__actions { return []; } +sub init__flash { + return {}; +} + +sub init__error { + return ''; +} + sub to_json { my ($self) = @_; + + return SL::JSON::to_json({ error => $self->_error }) if $self->_error; return SL::JSON::to_json({ eval_actions => $self->_actions }); } @@ -135,6 +170,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' }); } @@ -144,6 +180,29 @@ sub jstree { return $self; } +sub flash { + my ($self, $type, @messages) = @_; + + my $message = join ' ', grep { $_ } @messages; + + if (!$self->_flash->{$type}) { + $self->_flash->{$type} = [ 'flash', $type, $message ]; + push @{ $self->_actions }, $self->_flash->{$type}; + } else { + $self->_flash->{$type}->[-1] .= ' ' . $message; + } + + return $self; +} + +sub error { + my ($self, @messages) = @_; + + $self->_error(join ' ', grep { $_ } ($self->_error, @messages)); + + return $self; +} + 1; __END__ @@ -161,12 +220,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: @@ -222,7 +281,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. @@ -301,6 +360,68 @@ Instead of: The first variation is obviously better suited for chaining. +=over 4 + +=item C + +Call the function with the name C<$method> on C<$self> with arguments +C<@args>. Returns the return value of the actual function +called. Useful for chaining (see above). + +=item C + +Call the function with the name C<$method> on C<$self> with arguments +C<@args> if C<$condition> is trueish. Does nothing otherwise. + +Returns the return value of the actual function called if +C<$condition> is trueish and C<$self> otherwise. Useful for chaining +(see above). + +This function is equivalent to the following: + + if ($condition) { + $obj->$method(@args); + } + +But it is easier to integrate into a method call chain, e.g.: + + $js->html('#content', $html) + ->action_if($item->is_flagged, 'toggleClass', '#marker', 'flagged') + ->render($self); + +=back + +=head2 ADDITIONAL FUNCTIONS + +=over 4 + +=item C + +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 flashes of all types will be cleared after each +successful ClientJS call that did not end with C<$js-Eerror(...)>. + +=item C + +Causes L (and therefore L) to output a JSON object +that only contains an C field set to this C<$message>. The +client will then show the message in the 'error' flash. + +The messages of multiple calls of C on the same C<$self> will +be merged. + +=item C + +Redirects the browser window to the new URL by setting the JavaScript +property C. Note that +L is AJAX aware and uses this +function if the current request is an AJAX request as determined by +L. + +=back + =head2 JQUERY FUNCTIONS The following jQuery functions are supported: