X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=httemplate%2Felements%2Fprogress-init.html;h=ba2e6be0ddf74813eff18d75bd9879aa74c9e353;hb=d65927fb45aa1c47d7f593db0142d14799b0fabf;hp=472a1725ff2c48d1df4f8ee3d2a617440a292f31;hpb=2b49cbe76b94c6c1561aa2bf37beba7d47591190;p=freeside.git diff --git a/httemplate/elements/progress-init.html b/httemplate/elements/progress-init.html index 472a1725f..ba2e6be0d 100644 --- a/httemplate/elements/progress-init.html +++ b/httemplate/elements/progress-init.html @@ -1,50 +1,123 @@ -<% - my( $formname, $fields, $action, $url_or_message, $key ) = @_; - $key = '' unless defined $key; - - my $url_or_message_link; - if ( ref($url_or_message) ) { #its a message or something - $url_or_message_link = - 'message='. uri_escape( $url_or_message->{'message'} ) - } else { - $url_or_message_link = "url=$url_or_message"; - } +<%doc> +Example: +In misc/something.html: + + <FORM NAME="MyForm"> + <INPUT TYPE="hidden" NAME="recordnum" VALUE="42"> + <INPUT TYPE="hidden" NAME="what_to_do" VALUE="delete"> + <% include( '/elements/progress-init.html', + 'MyForm', + [ 'recordnum', 'what_to_do' ], + $p.'misc/process_something.html', + { url => $p.'where_to_go_next.html' }, + #or { message => 'Finished!' }, + #or { url => $p.'where_to_go.html', + message => 'Finished' }, + # which displays the message, then waits for confirmation before + # redirecting to the URL. + #or { popup_url => $p.'popup_contents.html' } + # which loads that URL into the popup after completion + #or { url => $p.'where_to_go.html', + error_url => $p.'where_we_just_were.html' } + # to redirect somewhere different on error + ) %> + </FORM> + <SCRIPT TYPE="text/javascript>process();</SCRIPT> + +In misc/process_something.html: + +<%init> +my $server = FS::UI::Web::JSRPC->new('FS::something::process_whatever', $cgi); +</%init> +<% $server->process %> + +In FS/something.pm: + +sub process_whatever { #class method + my $job = shift; + my $param = thaw(base64_decode(shift)); + # param = { 'recordnum' => 42, 'what_to_do' => delete } + # make use of this as you like + do_phase1; + $job->update_statustext(20); + do_phase2; + $job->update_statustext(40); + do_phase3; + $job->update_statustext(60); + # etc. + return 'this value will be ignored'; +} + +Internal notes: + +This component creates two JS functions: process(), which starts the +submission process, and start_job(), which starts the job on the +server side. + +process() does the following: +- disable the form submit button +- for all form fields named in "fields", collect their values into an array +- declare a callback function "myCallback" +- pass the array and callback to start_job() + +start_job() is an xmlhttp standard function that turns the array of values +into a JSON string, posts it to the location given in $action, receives a +job number back, and then invokes the callback with the job number as an +argument. Normally, the post target script will use FS::UI::Web::JSRPC to insert +a queue job (with the form field values as arguments), and return its +job number. + +myCallback() opens an Overlib popup containing progress-popup.html, with +the job number, form name, and destination options (url, message, popup_url, +error_url) as URL parameters. This popup will poll the server for the status +of the job, display a progress bar, and on completion, either redirect to +'url' or 'popup_url', display 'message' in the popup window, or (on failure) +display the job statustext as an error message. If 'error_url' is specified, +the "Close" button in the popup will then redirect the user to that location. + +</%doc> +<% include('/elements/xmlhttp.html', + 'method' => 'POST', + 'url' => $action, + 'subs' => [ 'start_job' ], + 'key' => $key, + ) %> -<SCRIPT TYPE="text/javascript" SRC="../elements/jsrsClient.js"></SCRIPT> -<SCRIPT TYPE="text/javascript" SRC="../elements/overlibmws.js"></SCRIPT> -<SCRIPT TYPE="text/javascript" SRC="../elements/overlibmws_iframe.js"></SCRIPT> +<& /elements/init_overlib.html &> + <SCRIPT TYPE="text/javascript"> -function OLiframeContent(src, width, height, name) { - return ('<iframe src="'+src+'" width="'+width+'" height="'+height+'"' - +(name?' name="'+name+'" id="'+name+'"':'')+' scrolling="auto">' - +'<div>[iframe not supported]</div></iframe>'); -} -function <%=$key%>process () { +function <%$key%>process () { + + //alert('<%$key%>process for form <%$formname%>'); - document.<%=$formname%>.submit.disabled=true; + if ( document.<%$formname%>.submitButton.disabled == false ) { + document.<%$formname%>.submitButton.disabled=true; + } - overlib( 'Submitting job to server...', WIDTH, 432, HEIGHT, 136, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); + overlib( 'Submitting job to server...', WIDTH, 444, HEIGHT, 168, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); var Hash = new Array(); var x = 0; var fieldName; - for (var i = 0; i<document.<%=$formname%>.elements.length; i++) { - field = document.<%=$formname%>.elements[i]; - if ( <%= join(' || ', map { "(field.name.indexOf('$_') > -1)" } @$fields ) %> + for (var i = 0; i<document.<%$formname%>.elements.length; i++) { + field = document.<%$formname%>.elements[i]; + if ( <% join(' || ', map { "(field.name.indexOf('$_') > -1)" } @$fields ) %> ) { if ( field.type == 'select-multiple' ) { + //alert('select-multiple ' + field.name); for (var j=0; j < field.options.length; j++) { if ( field.options[j].selected ) { + //alert(field.name + ' => ' + field.options[j].value); Hash[x++] = field.name; Hash[x++] = field.options[j].value; } } } else if ( ( field.type != 'radio' && field.type != 'checkbox' ) || ( ( field.type == 'radio' || field.type == 'checkbox' ) - && document.<%=$formname%>.elements[i].checked + && document.<%$formname%>.elements[i].checked ) ) { @@ -54,15 +127,49 @@ function <%=$key%>process () { } } - jsrsPOST = true; - jsrsExecute( '<%= $action %>', <%=$key%>myCallback, 'start_job', Hash ); + // jsrsPOST = true; + // jsrsExecute( '<% $action %>', <%$key%>myCallback, 'start_job', Hash ); + + //alert('start_job( ' + Hash + ', <%$key%>myCallback )' ); + //alert('start_job()' ); + <%$key%>start_job( Hash, <%$key%>myCallback ); } -function <%=$key%>myCallback( jobnum ) { +function <%$key%>myCallback( jobnum ) { - overlib( OLiframeContent('<%=$p%>elements/progress-popup.html?jobnum=' + jobnum + ';<%=$url_or_message_link%>;formname=<%=$formname%>' , 432, 136, 'progress_popup'), CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); + var url = <% $progress_url->as_string |js_string %>; + url = url.replace('_JOBNUM_', jobnum); + overlib( OLiframeContent(url, 444, 168, '<% $popup_name %>'), CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); } </SCRIPT> + +<%init> + +my( $formname, $fields, $action, $url_or_message, $key ) = @_; +$key = '' unless defined $key; + +my %dest_info; +if ( ref($url_or_message) ) { #its a message or something + %dest_info = map { $_ => $url_or_message->{$_} } + grep { $url_or_message->{$_} } + qw( message url popup_url error_url ); +} else { + # it can also just be a url + %dest_info = ( 'url' => $url_or_message ); +} + +my $progress_url = URI->new($fsurl.'misc/progress-popup.html'); +$progress_url->query_form( + 'jobnum' => '_JOBNUM_', + 'formname' => $formname, + %dest_info, +); + +#stupid safari is caching the "location" of popup iframs, and submitting them +#instead of displaying them. this should prevent that. +my $popup_name = 'popup-'.random_id(); + +</%init>