NAME
    "DBIx::HTML::ClientDB" - Convert sql into a client-side db with keyed
    access.

Synopsis
            use DBIx::HTML::ClientDB;

            my($object) = DBIx::HTML::ClientDB -> new
            (
                    dbh          => $dbh,
                    row_headings => 'Unit code,Unit code,Campus name,Unit name',
                    sql          => 'select unit_code, unit_code, campus_name, unit_name ' .
                                    'from unit, campus where unit_campus_id = campus_id ' .
                                    'order by unit_code',
            );

            print $object -> javascript_for_client_db();
            print $object -> table();
            print $object -> javascript_for_client_init();

Description
    This module takes a db handle, an SQL statement and a
    specially-formatted row_headings parameter, and builds an array of rows
    as returned by the SQL.

    Then you ask for that array in HTML, ie as a table.

    After a call to the table() method, you can call the size() method if
    you need to check how many rows were returned by the SQL you used.

    Neither the module CGI.pm, nor any of that kidney, are used by this
    module. We simply output pure HTML.

    However, for simplicity, this document pretends you are using CGI.pm
    rather than an alternative. The sentences would become too convoluted
    otherwise.

    The output table is formatted as N rows of 2 columns:

    First column
        The first column contains the row headings you supply in the
        'row_headings' parameter. 'row_headings' is a comma-separated list
        of strings you want to appear in the first column of the table.

        There must be one string in 'row_headings' for each column mentioned
        in the SQL.

    Second column
        The second column contains the 'current record' in the database.

    Now for the rows:

    First row
        The first row contains the first prompt string in the first column.

        The first row contains a HTML popup menu in the second column.

        This menu is what you use to choose the 'current record' in the
        database.

        Since two (2) SQL columns are used to build this menu, two (2)
        strings from the row_headings parameter are consumed building the
        first row. The first of these 2 strings appears in the first column,
        as explained above. The second of these 2 strings is, much to your
        amazement, discarded!

        This way of doing things makes it easy for you to count row_heading
        strings and their corresponding SQL columns, and makes it easy for
        me to cross-check your ability to count to 2 :-).

    Other rows
        Each other row contains a field in the 'current record'. The value
        in the first column comes from the row_headings parameter, and the
        value in the second column comes from the database.

    The sum result is menu-driven access to the data returned by the SQL.
    All this is downloaded from your CGI script to the web client. Since
    changing the current menu item updates the other fields in this table
    using JavaScript, no message is sent to the web server, and hence you
    have maximum speed of access.

    The whole point of the exercise is to give you simple code for simple
    access to simple data.

    See examples/test-clientdb.cgi for an example which will make all this
    clear.

Distributions
    This module is available both as a Unix-style distro (*.tgz) and an
    ActiveState-style distro (*.ppd). The latter is shipped in a *.zip file.

    See http://savage.net.au/Perl-modules/html/installing-a-module.html for
    help on unpacking and installing each type of distro.

Usage
    You create an object of the class by calling the constructor, 'new'.

    Now call various methods to get the HTML and JavaScript.

    Lastly, display the HTML as part of a form. You don't need a submit
    button because there is no need to transmit your menu selection to the
    CGI script. It's all about convenient access to a small database. Of
    course, you can easily use this as the basis of a more complex
    record-selection system.

    Instead of the method javascript_for_client_init(), you can call the
    method javascript_for_client_on_load() to initialize a JavaScript onLoad
    event handler.

    Note: The HTML menu name and all JavaScript function and global variable
    names have been deliberately chosen so as to not clash with other
    modules of mine in the DBIx::HTML::* namespace. Hence these modules can,
    in theory, all be used to build a single web page, and indeed, can (I
    hope) all be used to build a single form. No, I didn't actually test it.

Options
    Here, in alphabetical order, are the options accepted by the
    constructor, together with their default values.

    border => 0
        This specifies whether or not the HTML table returned by the table()
        method has the border option set.

        Valid values are 0 and 1.

        This option is not mandatory.

    dbh => ''
        Pass in an open database handle.

        This option is mandatory.

    default => ''
        Pass in the string (from SQL column 2) which is to be the default
        item on the popup menu. You supply here the visible menu item, not
        the value associated with that menu item.

        If default is not given a value, the first menu item becomes the
        default.

        See the discussion of the sql option for details about the menu
        items.

        This option is not mandatory.

    form_name => 'dbix_client_form'
        The value of this parameter becomes the name of the form used in the
        JavaScript, and must be the name used by you in your call to CGI's
        start_form() or start_multipart_form() method.

        This option is not mandatory, since it has a default value.

    max_width => 0
        When the database field values displayed in the second column of the
        table are input fields, this value becomes the 'size' parameter of
        those input fields.

        A value of 0 means the data will be scanned and a value chosen which
        ensures no data is truncated in order to display the database field
        values.

        This option is not mandatory.

    menu_name => 'dbix_client_menu'
        The value of this parameter is what you would pass into a CGI object
        when you call its param() method to retrieve the user's selection.

        Hence you would do something like:

                my($name)   = 'fancy_menu';
                my($object) = DBIx::HTML::ClientDB -> new(menu_name => $name, ...);
                my($q)      = CGI -> new();
                my($id)     = $q -> param($name) || '';

        This option is not mandatory, since it has a default value.

    row_headings => 'a,b,...'
        Pass in a comma-separated list of strings to use in the first column
        of the table.

        There must be one string in 'row_headings' for each column mentioned
        in the SQL.

        Since two (2) SQL columns are used to build the menu, two (2)
        strings from the row_headings parameter are consumed building the
        first row. The first of these 2 strings appears in the first column,
        as explained above. The second of these 2 strings is, much to your
        amazement, discarded!

        This way of doing things makes it easy for you to count row_heading
        strings and their corresponding SQL columns, and makes it easy for
        me to cross-check your ability to count to 2 :-).

        This option is mandatory.

    sql => ''
        Pass in the SQL used to select the data.

        The SQL must select at least 2 columns. The first will be used as
        the value returned by a CGI object, for example, when you call its
        param() method. The second value will be used as the visible
        selection offered to the user on the menu.

        Of course, the 2 columns selected could be the same:

                $obj -> set(sql => 'select campus_name, campus_name from campus ' .
                                                'order by campus_name');

        But normally you would do this:

                $obj -> set(sql => 'select campus_id, campus_name from campus ' .
                                                'order by campus_name');

        This means that the second column is used to construct visible menu
        items, and when an item is selected by the user, the first column is
        what is returned to your CGI script.

        The question remains: After you do something like this:

                my($q)     = CGI -> new();
                my($id)    = $q -> param('dbxi_client_menu') || '';

        how do you convert the value, eg campus_id, back into the database
        fields associated with the visible menu item, eg campus_name.

        Simple: You call the param() method of the DBIx::HTML::ClientDB
        class:

                my(@field) = $object -> param($id);

        The param() method returns () if the value of $id is unknown.

        This option is mandatory.

Methods
    javascript_for_client_db()
        Returns JavaScript, including the <script>...</script> tags, which
        holds your data in a JavaScript db, and includes some JavaScript
        functions.

        Output it somewhere suitable on your page.

    javascript_for_client_init()
        Returns JavaScript, including the <script>...</script> tags, which
        holds the function call to a function which initializes the menu.
        The function itself is included in the code returned by
        javascript_for_client_db().

        Output it somewhere suitable on your page after you have output the
        string returned from javascript_for_db().

        Calling this method is optional. If you do not call it, then calling
        the method javascript_for_client_on_load() is mandatory.

    javascript_for_client_on_load()
        Returns a string to be used as a <body> tag's onLoad event handler.
        It calls the function which initializes the menu. The function
        itself is included in the code returned by javascript_for_db().

        Output it as part of the <body> tag. See examples/test-clientdb.cgi
        for an example.

        Calling this method is optional. If you do not call it, then calling
        the method javascript_for_client_init() is mandatory.

    new(%arg)
        The constructor.

        See the previous section for details of the parameters.

    param($id)
        Returns an array of database fields corresponding to the menu value
        chosen.

        Call this to convert the value returned to the CGI script when the
        user selected a menu item, into the database fields which appeared
        in the second column of the table.

        In other words, convert the first column of the SQL into the values
        of all the columns corresponding to that first column.

    size()
        Return the number of rows returned by your SQL.

        Call this after calling 'table'.

        It will tell you whether or not your menu is empty.

    table()
        Return the HTML for the table.

Sample Code
    See examples/test-clientdb.cgi for a complete program.

    You will need to run examples/bootstrap-menus.pl to load the 'test'
    database, 'campus' and 'unit' tables, with sample data.

    You'll have to patch these 2 programs vis-a-vis the db vendor, username
    and password.

    The sample data in bootstrap-menus.pl is simple, but is used by several
    modules, so don't be too keen on changing it :-).

See Also
            DBIx::HTML::LinkedMenus
            DBIx::HTML::PopupRadio
            DBIx::CSS::TreeMenu
            DBIx::CSS::TabMenu

    The latter 2 modules will be released after the current one.

Author
    "DBIx::HTML::ClientDB" was written by Ron Savage *<ron@savage.net.au>*
    in 2002.

    Home page: http://savage.net.au/index.html

Copyright
    Austrlian copyright (c) 2002, Ron Savage. All rights reserved.

            All Programs of mine are 'OSI Certified Open Source Software';
            you can redistribute them and/or modify them under the terms of
            The Artistic License, a copy of which is available at:
            http://www.opensource.org/licenses/index.html

