File Coverage

blib/lib/HTML/GUI/screen.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package HTML::GUI::screen;
2              
3 6     6   25377 use warnings;
  6         15  
  6         220  
4 6     6   59 use strict;
  6         10  
  6         287  
5              
6             =head1 NAME
7              
8             HTML::GUI::screen - Create and control a whole screen for web application
9              
10             =head1 VERSION
11              
12             Version 0.01
13              
14             =cut
15              
16             our $VERSION = '0.01';
17              
18 6     6   10326 use HTML::Template;
  6         104829  
  6         181  
19 6     6   4793 use HTML::GUI::container;
  0            
  0            
20             use HTML::GUI::hidden;
21             use HTML::GUI::log::eventList;
22             use UNIVERSAL qw(isa);
23             our @ISA = qw(HTML::GUI::container);
24             use JSON;
25             use Log::Log4perl qw(:easy);
26              
27              
28              
29             =head1 SCREEN
30              
31             Manage a screen : it loads its definition with a YAML file and create all the widgets it contains.
32             It can generate javascript code to check constraints on the web page.
33             It can test if constraints of each widget are OK.
34             It can generate the HTML of each widget for use with HTML::Template.
35              
36              
37             =cut
38              
39             # array of string : list of all public properties specific to a screen
40             my @publicPropList = qw/ path actionUrl nextScreen nextScreenParams
41             nextScreenType nextScreenValues session hsession
42             counter lastCounter parentScreenDesc loadNextScreen
43             dialogCallBack openCallBack/;
44              
45              
46             =head1 PUBLIC METHODS
47              
48             =pod
49              
50             =head3 new
51              
52             create a new screen
53              
54             =cut
55              
56             sub new
57             {
58             my($class,$params,$path) = @_;
59              
60             my $this = $class->SUPER::new($params);
61             return undef unless defined $this;
62              
63             $this->{type} = "screen";
64             $this->{dialogCallBackFunc} = undef;
65             $this->{openCallBackFunc} = undef;
66             #default path to a screen is '/' (root directory)
67             $this->setProp({ 'path'=> defined $path ? $path : '/',
68             'nextScreen' => '',
69             'nextScreenParams' => {},
70             'nextScreenValues' => {},
71             'parentScreenDesc' => $params->{parentScreenDesc} || '',
72             'session' => {},
73             'hsession' => {},
74             'loadNextScreen' => 0,
75             'dialogCallBack' => $params->{dialogCallBack} || '',
76             'openCallBack' => $params->{openCallBack} || '',
77             });
78             if (!$this->getProp('actionUrl')){
79             #default form action
80             $this->setProp({'actionUrl'=>'/'})
81             }
82              
83             bless($this, $class);
84             }
85              
86              
87             =pod
88              
89             =head3 setProp
90              
91             Description :
92             specialized version of widget::setProp for managing
93             functions associated with the screen
94              
95             =cut
96             sub setProp
97             {
98             my($self,
99             $params, # hash ref : defines params value
100             ) = @_;
101              
102             if (exists $params->{dialogCallBack}){
103             $self->{dialogCallBackFunc} = $self->getFunctionFromName($params->{dialogCallBack});
104             }
105             if (exists $params->{openCallBack}){
106             $self->{openCallBackFunc} = $self->getFunctionFromName($params->{openCallBack});
107             }
108             $self->SUPER::setProp($params);
109             }
110              
111             =pod
112              
113             =head3 getJscript
114              
115             Parameters :
116              
117             Return :
118             string
119              
120             Description :
121             Return the javascript code to enforce the constraints of the widgets (describe each constraint for each widget); this code must be inserted in the header of the HTML page.
122              
123             =cut
124              
125             sub getJscript
126             {
127             my($self ) = @_;
128             #UML_MODELER_BEGIN_PERSONAL_CODE_getJscript
129             #UML_MODELER_END_PERSONAL_CODE_getJscript
130             }
131              
132             =head3 getDescriptionDataFromParams
133              
134             Description:
135             Retrieve from the http form data the data describing the current screen
136              
137             Parameters :
138             params : the hash containing the params retrieve from the HTTP form submit
139              
140             Return :
141             a hash ref containing the description data (screen name...)
142              
143             =cut
144              
145             sub getDescriptionDataFromParams
146             {
147             my ($self,$params)=@_;
148              
149             my $descDataString = exists $params->{'GHW:screenDescription'} ?
150             $params->{'GHW:screenDescription'} : '{}';
151              
152             return JSON::decode_json($descDataString);
153             }
154              
155             =head3 getDescriptionFieldsHtml
156              
157             Return :
158             a string containing the html of the hidden fields containing usefull
159             data for describing the screen (for example, the name of the screen)
160             To generate a valid Html document, we insert the the hidden field into
161             an invisible div.
162              
163             =cut
164              
165             sub getDescriptionFieldsHtml
166             {
167             my ($self)=@_;
168              
169             #we create a JSON string that contain all the usefull data we need for this screen
170             my $descDataString = JSON::encode_json({screenName => $self->getProp('path'),
171             counter => $self->getProp('counter')||'0'});
172              
173             my $descField = HTML::GUI::hidden->new({id => 'GHW:screenDescription',
174             value => $descDataString });
175             if (!$descField){
176             return '';
177             }else{
178             return $self->getHtmlTag("div",{style=>'display:none'},
179             $descField->getHtml());
180             }
181             }
182              
183             =head3 getHtml
184              
185             Return :
186             a string containing the html of the webpage for the screen.
187              
188             =cut
189              
190             sub getHtml
191             {
192             my($self ) = @_;
193             my $filename = $self->getPath()."templates/main.html";
194             my $template = HTML::Template->new(filename => $filename);
195             my $eventList = HTML::GUI::log::eventList::getCurrentEventList();
196             my $screenHtml = $eventList->getHtml()
197             .$self->SUPER::getHtml()
198             .$self->getDescriptionFieldsHtml();
199             $template->param( screen => $self->getHtmlTag('form',
200             {action=> $self->getProp('actionUrl'),
201             method=>'post'},
202             $screenHtml),
203             css_path => [{url =>"/static/css/base.css"}] );
204              
205             return $template->output;
206              
207             }
208              
209             =pod
210              
211             =head3 validate
212             Description :
213             Validate all the fields of a screen and store the result of
214             the validation
215              
216             Return :
217             return 1 if no field of the screen break no constraint
218             return 0 if one or more field break constraint
219              
220             =cut
221              
222             sub validate
223             {
224             my($self) = @_;
225             my $eventList = HTML::GUI::log::eventList::getCurrentEventList();
226             $eventList->forget();
227             return $self->SUPER::validate();
228             }
229              
230             =pod
231              
232             =head3 getPubPropHash
233              
234             Returns :
235             propHash : hash : a hash containing the value '1' pour each public propertie
236              
237             =cut
238              
239             my $pubPropHash = undef;
240             sub getPubPropHash{
241             my($self ) = @_;
242              
243             return $pubPropHash if (defined $pubPropHash);
244             foreach my $propName(@publicPropList){
245             $pubPropHash->{$propName} = 1;
246             }
247             return $pubPropHash;
248             }
249              
250             =pod
251              
252             =head3 executeAction
253              
254             Parameters :
255             - $actionFunction : the function to execute
256             - $session : a hash ref to the session
257              
258             Description :
259             Execute the function $actionFunction with the values of the screen
260              
261             Returns :
262            
263            
264              
265             =cut
266             sub executeAction{
267             my($self,$actionFunction) = @_;
268              
269              
270             if (defined $actionFunction){
271             &$actionFunction($self);
272             }
273             return $self;
274             }
275              
276              
277              
278             =pod
279              
280             =head3 processHttpRequest
281              
282             Parameters :
283             - $params : hash ref containing the POST data
284              
285             Description :
286             - do all the stuff when a user press a buton
287              
288             Returns :
289             - the screen to display to the user ; it can be a new one if needed
290            
291              
292             =cut
293             sub processHttpRequest{
294             my($self,$params) = @_;
295              
296             $self->setValueFromParams($params);
297              
298             my $btnFired = $self->getFiredBtn($params);
299             if ($btnFired){
300             my $nextScreenName = $btnFired->getProp('nextScreen');
301             if ($nextScreenName){
302             $self->setNextScreen($nextScreenName,undef,undef);
303             }
304            
305             if ($btnFired->getProp('btnAction')){
306             #We want to process data => we first validate it
307             if ($self->validate()){
308             #Data are OK for the GUI => call the controller
309             #defined by the action button
310             my $actionFunction = $btnFired->getProp('btnActionFunc');
311             if ($actionFunction){
312             $self->executeAction($actionFunction);
313             }
314            
315             }
316             }
317             }
318             return $self;
319             }
320              
321             =pod
322              
323             =head3 executeCallBackHandler
324              
325             Description
326             - execute the handler whose name is $handlerName on
327             the $newScreen object if the handle is defined.
328             When the handler is called, it is called with $params as parameters
329              
330             =cut
331             sub executeCallBackHandler{
332             my($self,$newScreen,$handlerName,$params) = @_;
333              
334             if ($newScreen->{$handlerName}){
335             #activate the callback if it's defined
336             $newScreen->{$handlerName}($newScreen,$params);
337             }
338             }
339              
340             =pod
341              
342             =head3 getNextScreen
343              
344             Description :
345             - determine what is the next screen to display to the user and populate it with the messages and user data
346              
347             Returns :
348             - the screen to display to the user ; it can be a new one if needed
349            
350              
351             =cut
352             sub getNextScreen{
353             my($self) = @_;
354              
355             my $newScreen = undef;
356             my $nextScreenPath = $self->getProp('nextScreen');
357             my $nextScreenValues = $self->getProp('nextScreenValues');
358              
359             if ( ! $self->getProp('loadNextScreen') ){
360             #we want to stay on the same screen
361             return $self;
362             }
363             $DB::single = 1;
364             if ($self->getProp('nextScreenType') eq 'closeDialog'){
365             $newScreen = HTML::GUI::widget->instantiateFromYAML( $self->getProp('parentScreenDesc'));
366             $self->executeCallBackHandler($newScreen,'dialogCallBackFunc',$self->getProp('nextScreenParams'));
367             }else{
368             $newScreen = HTML::GUI::widget->instantiateFromFile($nextScreenPath);
369             $self->executeCallBackHandler($newScreen,'openCallBackFunc',$self->getProp('nextScreenParams'));
370             }
371             if (!$newScreen){
372             $self->error("Sorry, a technical problem occured : impossible to load the next screen. Please report this issue to the support.");
373             return $self;
374             }
375             $newScreen->setProp({counter => $self->getProp('counter')});
376             if ($nextScreenValues){
377             $newScreen->setValue($nextScreenValues);
378             }
379             if ($self->getProp('nextScreenType') eq 'openDialog'){
380             $newScreen->setProp({parentScreenDesc=>$self->serializeToYAML()});
381             }
382              
383             return $newScreen;
384             }
385              
386             =pod
387              
388             =head3 setNextScreen
389              
390             Parameters :
391             - $path : the path of the next screen
392             - $params : hash ref containing the optional params to call the next screen (for example imagine the next screen is customer_info and the param is {customer_id => 254412}
393             - $values : you can specify all the values you want to feed your screen (in the way you get the values from getValueHash() )
394              
395             Description :
396             - determine what is the next screen to display to the user and populate it with the messages and user data
397              
398             Returns :
399             - the screen to display to the user ; it can be a new one if needed
400            
401              
402             =cut
403             sub setNextScreen{
404             my($self,$path,$params,$values,$screenType) = @_;
405              
406             $screenType ||= 'screen';
407             $self->setProp({nextScreen => $path,
408             nextScreenType => $screenType,
409             nextScreenParams => $params || {},
410             nextScreenValues => $values || {},
411             loadNextScreen => 1,
412             });
413             }
414              
415              
416             =pod
417              
418             =head3 openDialog
419            
420             Description :
421             - define the next dialog to show to the end user. The difference between a dialog and a screen is that a dialog can be closed (like a popup window).
422              
423             Parameters :
424             - $path : the path of the next screen
425             - $params : hash ref containing the optional params to call the next screen (for example imagine the next screen is customer_info and the param is {customer_id => 254412}
426             - $values : you can specify all the values you want to feed your screen (in the way you get the values from getValueHash() )
427             =cut
428              
429             sub openDialog(){
430             my($self,$path,$params,$values) = @_;
431              
432             $self->setNextScreen($path,$params,$values,'openDialog');
433             }
434              
435             =pod
436              
437             =head3 closeDialog
438            
439             Description :
440             - close the current dialog. MUST only be called on an dialog screen.
441              
442             Parameters :
443             - $params : hash ref containing the optional params that will be used as parameters for the dialogCallBack function.
444              
445             =cut
446             sub closeDialog(){
447             my($self,$params) = @_;
448            
449             $self->setNextScreen(undef,$params,undef,'closeDialog');
450              
451             }
452              
453             =pod
454              
455             =head3 error
456              
457             Description :
458             - Specialization of the error function for all generic messages for the end user
459              
460             parameters :
461             - $message : the message to display to the end user
462              
463             Returns :
464             - nothing
465              
466             =cut
467             sub error($){
468             my ($self,$message) = @_;
469             $self->SUPER::error({
470             visibility => 'pub',
471             'error-type' => 'business',
472             'message' => $message,
473             });
474             }
475              
476             #array of properties that must be serialized
477             my @GHW_publicPropList = qw/parentScreenDesc dialogCallBack/;
478              
479             =pod
480              
481             =head3 getDefinitionData
482            
483             This method is the specialisation of the widget.pm method, refer to the widget.pm manual for more information.
484              
485             =cut
486              
487             sub getDefinitionData($)
488             {
489             my ($self) = @_;
490              
491             my $publicProperties = $self->SUPER::getDefinitionData();
492            
493             return $self->SUPER::getDefinitionData($publicProperties,
494             undef,\@GHW_publicPropList);
495             }
496             =head1 AUTHOR
497              
498             Jean-Christian Hassler, C<< >>
499              
500             =head1 BUGS
501              
502             Please report any bugs or feature requests to
503             C, or through the web interface at
504             L.
505             I will be notified, and then you'll automatically be notified of progress on
506             your bug as I make changes.
507              
508             =head1 SUPPORT
509              
510             You can find documentation for this module with the perldoc command.
511              
512             perldoc HTML::GUI::widget
513              
514             You can also look for information at:
515              
516             =over 4
517              
518             =item * AnnoCPAN: Annotated CPAN documentation
519              
520             L
521              
522             =item * CPAN Ratings
523              
524             L
525              
526             =item * RT: CPAN's request tracker
527              
528             L
529              
530             =item * Search CPAN
531              
532             L
533              
534             =back
535              
536             =head1 ACKNOWLEDGEMENTS
537              
538             =head1 COPYRIGHT & LICENSE
539              
540             Copyright 2007 Jean-Christian Hassler, all rights reserved.
541              
542             This program is free software; you can redistribute it and/or modify it
543             under the same terms as Perl itself.
544              
545             =cut
546              
547             1; # End of HTML::GUI::screen