App-MFILE-WWW

 view release on metacpan or  search on metacpan

lib/App/MFILE/WWW.pm  view on Meta::CPAN

enters a path (e.g. http://mfile.site/some/bogus/path), this will be treated
like any other page (re)load and the path is simply ignored.

=item * if the session is expired or invalid, any incoming GET request will
cause the login dialog to be displayed.

=item * well-formed POST requests are directed to the C<process_post> routine
in L<App::MFILE::WWW::Dispatch>. In derived-distro mode, the derived distro
must provide its own dispatch module.

=item * under ordinary operation, the user will spend 99% of her time
interacting with the JavaScript code running in her browser, which will
communicate asynchronously as needed with the back-end (which must be
implemented separately) via AJAX calls.

=back


=head2 JavaScript side

The JavaScript side provides a toolkit for building web applications that

=over

=item do not require the use of a mouse; and 

=item look and feel very much like text terminal applications from the 1980s

=back

Developing a front-end application with L<App::MFILE::WWW> currently assumes
that you, the developer, will want to use RequireJS, jQuery, and QUnit.

The JavaScript code is modular. Each code module has its own file and
modules are loaded asynchronously by L<RequireJS|http://requirejs.org/>.
Also, jQuery and QUnit L<http://qunitjs.com/> are loaded automatically.

In addition to the above, L<App::MFILE::WWW> provides a number of primitives,
also referred to as "targets", that can be used to quickly slap together a web
application. The next chapter explains what these widgets are and how to use
them.



=head1 FRONT-END PRIMITIVES

The JavaScript side implements a set of primitives, or widgets, from which the
front-end application is built up. These include a menu primitive, a form
primitive for entering data, table and "browser" primitives for viewing
datasets, and a "rowselect" primitive for selecting among 

=head2 daction

The C<daction> primitive is a generalized widget that can do anything. 


=head2 dbrowser

The C<dbrowser> primitive is like C<dform>, except that it displays a set
of data objects and enables the user to "browse" the dataset using arrow keys.
Like C<dform>, the primitive includes "miniMenu" functionality through which
the user can potentially trigger actions that take the current object as input.


=head2 dcallback

The C<dcallback> primitive is useful for cases when none of the other primitives
are appropriate for displaying a given type of object, and no interactivity is
needed beyond that provided by miniMenu. The C<dcallback> primitive writes the
target title and miniMenu to the screen, along with a "dcallback" div in
between, which it populates by calling the callback function. Since the callback
function part of the target definition, it can be app-specific.


=head2 dform

The C<dform> primitive is used to implement forms consisting of read-only
fields (for viewing data), read-write fields (for entering data), or a
combination of both. A "miniMenu" can be defined, allowing the user to trigger
actions that take the current object as input.


=head2 dmenu

The C<dmenu> primitive is used to implement menus.


=head2 dnotice

The C<dnotice> primitive takes an HTML string and displays it. The same
functionality can be accomplished with a C<daction>, of course, but using the
C<dnotice> primitive ensures that the notice will have the same "look and feel"
as the other widgets.


=head2 drowselect

The C<drowselect> primitive takes an array of strings, displays them vertically
as a list, and allows the user to choose one and perform an action on it. Actions
are defined via a C<miniMenu>. The currently-selected item is displayed in
reverse-video.


=head2 dtable

The C<dtable> primitive is similar to C<dbrowser> in that it takes a set of
objects and allows the user to choose one and perform actions on it via a
C<miniMenu>. Unlike C<dbrowser>, however, it display the objects in table form.
The currently-selected object is displayed in reverse video.



=head1 JAVASCRIPT UNIT TESTS

The JavaScript side has unit tests and functional tests that can be run by
starting the application and then pointing the browser to a URL like:

    http://localhost:5001/test

The tests are implemented using QUnit. A good source of practical advise on the
use of QUnit is the QUnit Cookbook, available here:

    https://qunitjs.com/cookbook/

The QUnit API itself is documented here:

    http://api.qunitjs.com/


=head2 Adding new test cases

There are separate sets of JavaScript unit tests for each of the following
three components:

=over

=item mfile-www core

=item mfile-www demo app

=item derived application (e.g. dochazka-www)

=back

To add a new test case, go to the appropriate C<tests/> directory (in mfile-www
core, in the mfile-www demo app, or in your derived application, as
appropriate) and create a js file (use one of the other C<tests/*.js> files
as a model). Then add this file to the C<test.js> file in the parent directory.


=head1 DEVELOPMENT NOTES


=head2 UTF-8

In conformance with the JSON standard, all data passing to and from the
server are assumed to be encoded in UTF-8. Users who need to use non-ASCII
characters should check their browser's settings.


=head2 Deployment

To minimize latency, L<App::MFILE::WWW> can be deployed on the same server
as the back-end (e.g. L<App::Dochazka::REST>), but this is not required.



=head1 PACKAGE VARIABLES



( run in 0.909 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )