Using jQuery UI in CGI C++ Web application

In this demonstration we will illustrate how to integrate jQuery into a cgicc C++ web application. We will also show how to use cgicc forms and cookies to manage user session. The example that follows also illustrates using, jQuery's Tab view, Dialog, Accordion panel and button widgets.

The application described here was tested in Debian on Apache2. This application can be found here http://demo.kahimyang.info/cgi-cpp/cpp/index.cgi. See the "related" article near the bottom of this page for help in setting up Apache2 virtual host in Debian Linux for use with cgi. It is also an introduction to cgicc.

To enable a page to use jQuery and jQuery UI, the add the following snippet to the head section of your page.

<head>
    <title>Sample</title>
    <link rel="stylesheet" 
        href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
    <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
    <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
    <link rel="stylesheet" href="/resources/demos/style.css" />
    <script>
    $(function() {
        $("#tabs").tabs();
    });
    </script>

All files referenced in the above code (line 4) can be downloaded to your own server and change those lines reflecting the location of the download files. Line 4 is the UI base/default theme. Change this theme to the desired theme only make sure you have downloaded or pointed to that theme css file as in line 4. Line 9 above is the tab view handler. It will look for a <div /> in the page with an id of tabs (#tabs). To use a <div /> using its class use .tabs (or any other name desired) instead. The dot (.) that preceeds the name signifies that the name is a class name.

jQuery, UI, and themes and its documentation can be found here http://jqueryui.com/download/. See the documentation for additional options for creating widgets.

Documentation for cgicc can be found here http://www.gnu.org/software/cgicc/doc/index.html.

Below is our cgicc page enabled with jQuery UI with start theme. Lines beginning in line 41 corresponds to line starting at line 4 above. Lines from 55 corresponds to line 9 above.

Line 77 show how a tab view is defined. Notice the id attribute tabs, this corresponds to line 53 in the handler code.

The same principle applies to other jQuery UI widgets. You define a handler code and a selector which is either an id (preceeded with a #) or a class (preceeded with a dot (.) in the head section, and then create a div in the body with that id or class.


#include <iostream>
#include <string>

#include "cgicc/CgiDefs.h"
#include "cgicc/Cgicc.h"
#include "cgicc/HTTPHTMLHeader.h"
#include "cgicc/HTMLClasses.h"

#include <glog/logging.h>

//#include <stdio.h>
//#include <stdlib.h>

using namespace std;
using namespace cgicc;

int main(int argc, char **argv) {

    google::InitGoogleLogging("app-index");

    Cgicc cgi;
    const_cookie_iterator cookies;
    const CgiEnvironment& env = cgi.getEnvironment();

    string logged = "new";
    // Check if user is currently logged
    for (cookies = env.getCookieList().begin();
            cookies != env.getCookieList().end(); ++cookies) {
        string c = cookies->getName();
        if (c == "Logged") {
            logged = cookies->getValue();
            break;
        }
    }

    cout << HTTPHTMLHeader();

    // Includes for jQuery and Jquery UI
    cout << html().set("xmlns", "http://www.w3.org/1999/xhtml");
    cout << head() << title("Test");
    cout << cgicc::link().set("rel", "stylesheet").
            set("href", "./jquery/themes/start/jquery-ui.css");
    cout << script().set("type", "text/javascript").
            set("src", "./jquery/jquery-1.8.3.js");
    cout << script();
    cout << script().set("type", "text/javascript").
            set("src", "./jquery/jquery-ui.js");
    cout << script();

    // Tab view widget
    cout << script();
    cout << "$(function() {";
    cout << "$(\"#tabs\").tabs();";
    cout << "});";
    cout << script();

    // Dialog widget
    cout << script();
    cout << "$(function() {" ;
    cout << "$(\"#loginDialog\").dialog({autoOpen:false,modal:true});";
    cout << "});";
    cout << script();

    // Button
    cout << script();
    cout << "$(function() {";
    cout << "$(\".buttons\").button({icons:{primary:"ui-icon-check"}});" ;
    cout << "});" ;
    cout << script();
    cout << head(); // end head section

    // Body
    cout << body().set("style", "font-size:12px;");
    cout << h2() << "CGICC and jQuery Demonstration" << h2();

    // Tab view
    cout << "
"; cout << ul(); cout << li(); cout << a().set("href", "#welcome"); cout << "Welcome"; cout << a(); cout << li(); cout << li(); cout << a().set("href", "#products"); cout << "Products"; cout << a(); cout << li(); cout << ul(); // First tab cout << cgicc::div().set("id", "welcome"); cout << p(); cout << "Welcome!"; cout << p(); // Login button, hide if user is already logged if (logged == "new" || logged == "false") { cout << p(); cout << a().set("href", "#").set("class", "buttons"). set("onclick", "$('#loginDialog').dialog('open');return false;"); cout << "Login" << a(); cout << p(); } cout << cgicc::div(); // end first tab // Second tab cout << cgicc::div().set("id", "products"); cout << p(); cout << "Products"; cout << p(); cout << cgicc::div(); // end second tab cout << "
"; // end tab view // Dialog cout << "<div id=\"loginDialog\" title=\"Login\">"; // form cout << form().set("action", "login.cgi"). set("method", "post"); cout << cgicc::div().set("style", "display:block"); cout << "Enter credentials" << cgicc::div() << br(); cout << fieldset(); cout << label().set("for", "userid") << "User ID" << label(); cout << input().set("type", "text"). set("style", "display:block"). set("name", "userid"). set("class", "ui-widget-content ui-corner-all"). set("id", "userid"); cout << label().set("for", "password") << "Password" << label(); cout << input().set("type", "password"). set("name", "password"). set("id", "password"). set("style", "display:block"). set("class", "ui-widget-content ui-corner-all"); cout << fieldset(); cout << br(); // Submit button cout << input().set("type", "submit"). set("value", "Submit"). set("class", "buttons"); cout << form(); // end form cout << "</div>"; // end dialog cout << body(); cout << html() << endl; return 0; }

In line 143 above, we created a submit type button (inside our dialog widget) that submits our form (line 121) to login.cgi, the page below. Our dialog is lunched by a button in line 100. The visibility of this button is controlled as to whether the user is logged in or not by a cookie retrieved in line 21 above.

#include <iostream>
#include <string>
#include <vector>
#include <iterator>	

#include "cgicc/CgiDefs.h"
#include "cgicc/Cgicc.h"
#include "cgicc/HTTPHTMLHeader.h"
#include "cgicc/HTMLClasses.h"

#include <glog/logging.h>

//#include <stdio.h>
//#include <stdlib.h>

using namespace std;
using namespace cgicc;

void writeOK() {
    // Set cookie.  Max-age is 60 seconds, after that
    // time our cookie is deleted.  You may want to add
    // more cookies depending on your requirements.  In
    // the example below, our cookie name is Logged.

    cout << "Set-Cookie:Logged=true;Max-age=60;\r\n";
    cout << "Content-type:text/html\r\n\r\n";

    cout << html().set("xmlns", "http://www.w3.org/1999/xhtml") << endl;
    cout << head().set("title", "Members Area");

    // jQuery and Jquery UI includes
    cout << head() << title("Test");
    cout << cgicc::link().set("rel", "stylesheet").
            set("href", "./jquery/themes/start/jquery-ui.css");
    cout << script().set("type", "text/javascript").
            set("src", "./jquery/jquery-1.8.3.js");
    cout << script();
    cout << script().set("type", "text/javascript").
            set("src", "./jquery/jquery-ui.js");
    cout << script();

    // Accordion
    cout << script();
    cout << "$(function() {";
    cout << "$("#accordion").accordion();";
    cout << "});";
    cout << script();

    // Button
    cout << script();
    cout << "$(function() {";
    cout << "$(\".buttons\").button({icons:{primary:"ui-icon-home"}});";
    cout << "});";
    cout << script();

    cout << head();
    cout << body();
    cout << h2() << "Members area" ;
    cout << h2();

    // Accordion 
    cout << "<div id="accordion" style="font-size:12px;">";
    cout << h3() << "My account" << h3() ;
    cout << cgicc::div();
    cout << p();
    cout << "My account";
    cout << p();
    cout << cgicc::div();
    cout << h3() << "Recent purchases" << h3();
    cout << cgicc::div();
    cout << p();
    cout << "My recent purchases";
    cout << p();
    cout << cgicc::div();

    cout << h3() << "Wish list" << h3();
    cout << cgicc::div();
    cout << p();
    cout << "My wish list";
    cout << p();
    cout << cgicc::div();

    cout << "</div>"; // end accordion

    // Home button
    cout << p();
    cout << a().set("href", "index.cgi").set("class", "buttons");
    cout << "Home" << a();
    cout << p();

    cout << body();
    cout << html() << endl;
}

// Write nothing but JavaScript redirection 
// to home page
void writeError() {

    // Send cookie to the browser.  Max-age=0 deletes
    // our cookie.
    cout << "Set-Cookie:Logged=false;Max-age=0;\r\n";
    cout << "Content-type:text/html\r\n\r\n;";

    cout << html().set("xmlns", "http://www.w3.org/1999/xhtml");
    cout << head().set("title", "Failed login");
    cout << script();
    cout << "function redirect () {";
    cout << "window.location.replace('index.cgi');";
    cout << "}";
    cout << script();
    cout << head();
    cout << body().set("onload", "redirect()");
    cout << body() ;
    cout << html() << endl;
}

int main(int argc, char **argv) {

    google::InitGoogleLogging("app-login");

    try {
        // Get form data submitted.  This is the most simple
        // form of getting form data
        Cgicc cgi;
        string userid = cgi("userid");
        string password = cgi("password");

        // Validate data.  May use database records for
        // validation
        if (userid == "userid0" && password == "password0") {
            // Success
            writeOK();
            return 0;
        } else {
            // Invalid user
            writeError();
        }
    } catch (exception& e) {
        // An error occurred
        LOG(ERROR) << e.what() << endl;
        writeError();
    }

    return 0;
}

Our login.cgi page above, demonstrates how to set a cookie and retrieve data submitted from a form (see line 125 and 126). For other methods of retrieving form data please see the cgicc documentation. Our cookie are set in line 25 and 26 upon successful login and deleted in line 101 and 102 if error occurred or login failed.

Please note that cookies must be set before the "Content-type" line of a request.

In the form example above userid and password are userid0 and password0 repectively.

That's it Good Luck.

If you like the article, please share.
(Site URL pattern has changed as a result social actions counter was reset.)



Comment icon   Comments (Newest first)