+<%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 recirects to the URL and displays the message as a status
+ #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>