Web Development (CGI Library)

In this chapter we will learn about developing Web applications using a CGI Library written in the Ring language.

Configure the Apache web server

We can use Ring with any web server that support CGI. In this section we will learn about using Ring with the Apache HTTP Server.

You can download Apache from : http://httpd.apache.org/

Or you can get it included with other projects like

XAMPP : https://www.apachefriends.org/download.html

Install then open the file:

xampp\apache\conf\httpd.conf

search for

<Directory />

Then after it add

Options FollowSymLinks +ExecCGI

So we have

<Directory />
Options FollowSymLinks +ExecCGI

Search for the next line and be sure that it’s not commented

LoadModule cgi_module modules/mod_cgi.so

Search for : AddHandler cgi-script

Then add ”.ring” to the supported cgi extensions

Example

AddHandler cgi-script .cgi .ring

Example

AddHandler cgi-script .cgi .pl .asp .ring

Run/Start the server

Create your web applications in a directory supported by the web server.

Example:

Apache2.2\htdocs\mywebapplicationfolder

Example:

xampp\htdocs\mywebapplicationfolder

Inside the source code file (*.ring), Add this line

#!c:\ring\bin\ring.exe -cgi

Note

Change the previous line based on the path to ring.exe in your machine

Ring CGI Hello World Program

The next program is the Hello World program

#!c:\ring\bin\ring.exe -cgi

See "content-type : text/html" +nl+nl+
    "Hello World!" + nl

Hello World Program using the Web Library

We can use the web library to write CGI Web applications quickly

Example (1) :

#!c:\ring\bin\ring.exe -cgi

Load "weblib.ring"

Import System.Web

New Page
{
        Text("Hello World!")
}

Example (2) :

#!c:\ring\bin\ring.exe -cgi

Load "weblib.ring"

Import System.Web

WebPage()
{
        Text("Hello World!")
}

Tip

the difference between ex. 1 and ex. 2 is using WebPage() function to return the page object instead of creating the object using new statement.

Web Library Features

The next features are provided by the Web library to quickly create web applications.

  • Generate HTML pages using functions
  • Generate HTML pages using objects
  • HTTP Get
  • HTTP Post
  • Files Upload
  • URL Encode
  • Templates
  • CRUD MVC Sample
  • Users Logic & Registration Sample

HTTP Get Example

The Page User Interface

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web
New Page
{
  Title = "Test HTTP Get"
  divstart([ :style = StyleSizeFull() ] )
  boxstart()
        text( "Test HTTP GET" )
        newline()
  boxend()
  divstart([ :style = Styledivcenter("600px","550px") +
                      StyleGradient(21) ])
  divstart([:style = stylefloatleft() + stylesize("100px","100%") +
                     stylecolor("black") + stylegradient(58)])
  formstart("ex5.ring")
        tablestart([ :style = stylesize("65%","90%") +
                              stylemarginleft("35%") +
                              stylemargintop("30%") ])
          rowstart([])
                cellstart([])
                  text ( "Name : "  )
                cellend()
                cellstart([])
                  cTextboxStyle = StyleMarginLeft("5%") +
                                  StyleWidth("250px") +
                                  StyleColor("black") +
                                  StyleBackColor("white")
                  textbox([ :name = "Name", :style = cTextboxStyle ] )
                cellend()
          rowend()
          rowstart([])
                cellstart([])
                  text ( "Address : " )
                cellend()
                cellstart([])
                  textbox([ :name = "Address", :style = cTextboxStyle] )
                cellend()
          rowend()
          rowstart([])
                cellstart([])
                  text ( "Phone : " )
                cellend()
                cellstart([])
                  textbox([ :name = "Phone", :style = cTextboxStyle ])
                cellend()
          rowend()
          rowstart([])
                cellstart([])
                  text ( "Age : "  )
                cellend()
                cellstart([])
                  textbox([ :name = "Age", :style = cTextboxStyle ])
                cellend()
          rowend()
          rowstart([])
                cellstart([])
                  text ( "City: " )
                cellend()
                cellstart([])
                  listbox([ :name = "City", :items = ["Cairo","Riyadh","Jeddah"],
                         :style = stylemarginleft("5%") + stylewidth("400px") ] )
                cellend()
          rowend()
          rowstart([])
                cellstart([])
                  text ( "Country : " )
                cellend()
                cellstart([])
                  combobox([ :name = "Country",
                         :items = ["Egypt","Saudi Arabia","USA"],
                         :style = stylemarginleft("5%") +
                                  stylewidth("400px")+
                                  stylecolor("black")+
                                  stylebackcolor("white")+
                                  stylefontsize("14px") ])
                cellend()
          rowend()
          rowstart([])
                cellstart([])
                  text ( "Note : " )
                cellend()
                cellstart([])
                  editbox([ :name = "Notes",
                        :style = stylemarginleft("5%") +
                                 stylesize("400px","100px")+
                                 stylecolor("black")+
                                 stylebackcolor("white") ,
                        :value = "write comments here..." ] )
                cellend()
          rowend()
          rowstart([])
                cellstart([])
                cellend()
                cellstart([])
                  submit([ :value = "Send" , :Style = stylemarginleft("5%") ])
                cellend()
          rowend()
        tableend()
  formend()
  divend()
  divend()
  divend()
}

Screen Shot:

HTTP Get

The Response

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web
New Page
{
 divstart([ :style = styledivcenter("800px","500px") ])
  boxstart()
        text ( "HTTP GET Response" )  newline()
  boxend()
  divstart([ :style = stylefloatleft()+stylewidth("10%")+
                      stylecolor("black")+stylegradient(58) ])
        newline()
        text ( "Name : "   )
        newline() newline()
        text ( "Address : "  )
        newline() newline()
        text ( "Phone : "   )
        newline() newline()
        text ( "Age : "   )
        newline() newline()
        text ( "City : "   )
        newline() newline()
        text ( "Country : "   )
        newline() newline()
        text ( "Note : "   )
        newline() newline()
  divend()
  divstart([ :style = stylefloatleft()+stylewidth("90%")+
                      stylecolor("black")+stylegradient(47) ])
        divstart([ :style = stylefloatleft() + stylewidth("1%") ])
          newline()
        divend()
        divstart([ :style = stylefloatleft() + stylewidth("95%") ])
          newline()
          text ( aPageVars["Name"] )
          newline() newline()
          text ( aPageVars["Address"] )
          newline() newline()
          text ( aPageVars["Phone"] )
          newline() newline()
          text (  aPageVars["Age"] )
          newline() newline()
          text ( aPageVars["City"] )
          newline() newline()
          text (aPageVars["Country"] )
          newline() newline()
          text ( aPageVars["Notes"] )
          newline() newline()
        divend()
  divend()
 divend()
}

Screen Shot:

HTTP Get

HTTP POST Example

The Page User Interface

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web
New Page
{
        boxstart()
                text( "Post Test")
                newline()
        boxend()
        divstart([ :style=StyleFloatLeft()+StyleWidth("100px") ])
                newline()
                text( "Number1 : " )    newline() newline()
                text( "Number2 : " )    newline() newline()
        divend()
        formpost("ex7.ring")
                divstart([ :style = styleFloatLeft()+StyleWidth("200px") ])
                        newline()
                        textbox([ :name = "Number1" ])  newline() newline()
                        textbox([ :name = "Number2" ])  newline() newline()
                        submit([ :value = "Send" ] )
                divend()
        formend()
}

Screen Shot:

HTTP Post

The Response

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web
New Page
{
        boxstart()
                text( "Post Result" )
                newline()
        boxend()
        divstart([ :style = styleFloatLeft()+styleWidth("200px") ])
                newline()
                text( "Number1 : " + aPageVars["Number1"] )
                newline() newline()
                text( "Number2 : " + aPageVars["Number2"] )
                newline() newline()
                text( "Sum : " + (0 + aPageVars["Number1"] + aPageVars["Number2"] ) )
                newline()
        divend()
}

Screen Shot:

HTTP Post

Upload Files

The Page User Interface

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web
New page
{
        boxstart()
                text( "Upload File" )
                newline()
        boxend()
        for x = 1 to 3 newline() next
        formupload("ex9.ring")
                text( "Customer Name : " )
                textbox([ :name = "custname" ])
                newline() newline()
                divstart([ :style = styleFloatLeft() + styleWidth("90px") ])
                        uploadfile("file")  newline() newline()
                        uploadfile("file2") newline() newline()
                        submit([ :value = "Send" ])
                divend()
        formend()
}

Screen Shot:

Upload File

The Response

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

cUploadPath = "C:/Apache2.2/htdocs/ringapp/upload/"
cUploadFolder = "/ringapp/upload/"

New page
{
        boxstart()
                text( "Upload Result" )
                newline()
        boxend()
        newline()
        divstart([ :style=  styleFloatLeft() + styleWidth("100px") ])
                text( "Name : " + aPageVars["custname"] )
                newline()
        divend()
        if aPageVars["file"] != char(13)
                getuploadedfile(self,"file")
        ok
        if aPageVars["file2"] != char(13)
                getuploadedfile(self,"file2")
        ok
}

Func getuploadedfile oObj,cFile
        # here we use object.property
        # instead of object { } to avoid executing braceend method
        cFileName = cUploadPath + oObj.getfilename(aPageVars,cFile)
        write(cFileName,aPageVars[cFile])
        system("chmod a+x "+cFileName)
        oObj.newline()
        oObj.text( "File "+cFileName+ " Uploaded ..." )
        oObj.newline()
        imageURL = cUploadFolder+oObj.getfilename(aPageVars,cFile)
        oObj.link([ :url = imageURL, :title = "Download" ])
        oObj.newline()
        oObj.image( [ :url = imageURL , :alt = :image  ] )
        oObj.newline()

Screen Shot:

Upload File

Cookies

The Page User Interface

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

New page
{
        boxstart()
                text( "Cookie Test" )
                newline()
        boxend()
        newline()
        link([ :url = "ex11.ring", :title = "Use Cookies" ])
        cookie("custname","Mahmoud Fayed")
        cookie("custage",28)
}

Screen Shot:

Cookies

The Response

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

New Page
{
        boxstart()
                text( "Cookies Values" )
                newline()
        boxend()
        link([ :url = "ex10.ring", :title = "back" ])
        newline()
        divstart([:style="float:left;width:200px"])
                text( "Name : " + aPageVars["custname"] )
                newline()
                text( "Age : " + aPageVars["custage"] )
                newline()
        divend()
}

Screen Shot:

Cookies

URL Encode

The Page User Interface

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

New Page
{
        boxstart()
                text( "URLEncode" )
                newline()
        boxend()
        link([ :url = "ex5.ring?Name="+URLEncode("-*{Mahmoud}*-")+
                      "&Address=Egypt&Phone=123456&Age=28&Notes=Programmer",
                      :title = "Test URL Encode" ])
}

Screen Shot:

URL Encode

Screen Shot:

URL Encode

Templates

Using Templates we can write Ring code inside HTML files

Syntax:

<%= Ring Expression %>
<%  Ring Statements %>

The HTML Code

<h1>Listing Numbers</h1>
<table>
  <tr>
    <th> <%= myheader.cColumn1 %> </th>
    <th> <%= myheader.cColumn2 %> </th>
    <th></th>
    <th></th>
    <th></th>
  </tr>
<% for x in aNumbers %>
  <tr>
    <td> <%= x.nValue  %> </td>
    <td> <%= x.nSquare %> </td>
  </tr>
<% next %>
</table>

The Ring Code

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

New NumbersController { start() }

Class NumbersController

        MyHeader aNumbers

        Func Start

                MyHeader = New Header
                {
                        cColumn1 = "Number" cColumn2 = "Square"
                }

                aNumbers = list(20)

                for x = 1 to len(aNumbers)
                        aNumbers[x] = new number
                        {
                                nValue  = x   nSquare = x*x
                        }
                next

                cTemp = Template("mynumbers.html",self)

                New Page
                {
                        boxstart()
                                text( "Test Templates" )
                                newline()
                        boxend()
                        html(cTemp)
                }

Class Header cColumn1 cColumn2
Class Number nValue   nSquare

Screen Shot:

Templates

HTML Special Characters

The text() function display HTML special characters.

If you want to write html code, use the html() function.

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

New Page
{
        boxstart()
                text("HTML Special Characters")
                newline()
        boxend()
        text('
                <html>
                        <body>
                                <p> "hello world" </p>
                        </body>
                </html>
        ')
}

Screen Shot:

HTML Special Characters

Hash Functions

The Page User Interface

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

New Page
{
        boxstart()
                text( "Hash Test")
                newline()
        boxend()
        divstart([ :style = StyleFloatLeft() + StyleWidth("100px") ])
                newline()
                text( "Value : " )
                newline() newline()
        divend()
        formpost("ex16.ring")
                divstart([ :style = StyleFloatLeft() + StyleWidth("300px") ])
                        newline()
                        textbox([ :name = "Value" ])
                        newline() newline()
                        submit([ :value = "Send" ])
                divend()
        formend()
}

Screen Shot:

Hash Functions

The Response

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

New Page
{
        boxstart()
                text( "Hash Result" )
                newline()
        boxend()
        divstart([ :style = styleFloatLeft() + styleWidth("100%") ])
                newline()
                text( "Value : "  + aPageVars["Value"] )
                newline()
                text( "MD5 : "    + MD5(aPageVars["Value"]) )
                newline()
                text( "SHA1 : "   + SHA1(aPageVars["Value"]) )
                newline()
                text( "SHA256 : " + SHA256(aPageVars["Value"]) )
                newline()
                text( "SHA224 : " + SHA224(aPageVars["Value"]) )
                newline()
                text( "SHA384 : " + SHA384(aPageVars["Value"]) )
                newline()
                text( "SHA512 : " + SHA512(aPageVars["Value"]) )
                newline()
        divend()
}

Screen Shot:

Hash Functions

Random Image

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

cUploadPath = "C:/Apache2.2/htdocs/ringapp/upload/"

New Page
{
        boxstart()
                text( "Random Test")
                newline()
        boxend()
        divstart([ :style = styleFloatLeft() + styleWidth("400px") ])
                newline()
                aList = dir(cUploadPath)
                if len(aList) > 0
                        nIndex = random(len(aList))
                        if nindex = 0 nIndex = 1 ok
                        cItem = "upload/" + aList[nIndex][1]
                        newline()
                        image( [ :url = cItem , :alt = :image  ] )
                else
                        text("No images!") newline()
                ok
        divend()
}

Screen Shot:

Random Image

HTML Lists

The next example print a list contains numbers from 1 to 10

Then print a list from Ring List.

Finally we have a list of buttons and when we press on a button we get a message contains the clicked button number.

To start the list we uses the ulstart() function.

To end the list we uses the ulend() function.

We uses listart() and liend() to determine the list item.

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

Func Main
        New Page
        {
                ulstart([])
                        for x = 1 to 10
                                listart([])
                                        text(x)
                                liend()
                        next
                ulend()
                list2ul(["one","two","three","four","five"])
                ulstart([])
                        for x = 1 to 10
                                listart([])
                                        cFuncName = "btn"+x+"()"
                                        button([ :onclick = cFuncName , :value = x])
                                        script(scriptfuncalert(cFuncName,string(x)))
                                liend()
                        next
                ulend()
        }

Screen Shot:

HTML Lists

HTML Tables

In this example we will learn how to generate HTML tables using the tablestart(), tableend(), rowstart(), rowend() ,headerstart(), headerend(), cellstart() and cellend() functions.

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

Func Main
        New Page
        {
                divstart([ :style = styledivcenter("400px","500px") ] )
                        style(styletable() + styletablerows("t01"))
                        tablestart([ :id = :t01 , :style = stylewidth("100%") ])
                                rowstart([])
                                        headerstart([]) text("Number") headerend()
                                        headerstart([]) text("square") headerend()
                                rowend()
                                for x = 1 to 10
                                        rowstart([])
                                                cellstart([]) text(x)   cellend()
                                                cellstart([]) text(x*x) cellend()
                                        rowend()
                                next
                        tableend()
                divend()
        }

Screen Shot:

HTML Tables

Gradient

In this example we will learn how to use the StyleGradient() function.

The function takes the style number as input (range from 1 to 60).

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

Func Main
        New Page
        {
                boxstart()
                        text("StyleGradient() Function")
                boxend()
                for x = 1 to 60
                        divstart([ :id = x , :align = "center" ,
                                   :style = stylefloatleft() +
                                            stylesize(string(100/60*6)+"%","50px") +
                                            stylegradient(x) ])
                                h3(x)
                        divend()
                next
        }

Screen Shot:

Gradient

Generating Pages using Objects

Instead of using functions/methods to generate HTML pages, we can use an object for each element in the page.

This choice means more beautiful code but slower.

The fastest method is to print HTML code directly, then using functions then using templates then using objects (slower).

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

Func Main

  WebPage()
  {
        Title = "Using objects to create the Web Page content"
        h1 { text("welcome") }
        link
        {
          Title = "Google"
          Link  = "http://www.google.com"
        }
        div
        {
          id = "div1"
          style = stylegradient(30) + stylesize("50%","50%")
          text("Outer Div")
          div
          {
                id = "div2"
                color = "white"
                backgroundcolor = "green"
                width = "50%"
                height = "50%"
                marginleft = "5%"
                margintop = "5%"
                text("Inner Div")
          }
        }
        div
        {
          id = "div3"
          color = "black"
          backgroundcolor = "silver"
          width = "100%"
          height = "100%"
          text("Form")
          form
          {
                method = "POST"
                Action = "helloworld.ring"
                Table
                {
                  style = stylewidth("100%") + stylegradient(24)
                  TR
                  {
                        TD { WIDTH="10%" text("Name : " )  }
                        TD { Input { type = "text" } }
                  }
                  TR
                  {
                        TD { WIDTH="10%" text("Email : " ) }
                        TD { Input { type = "text" } }
                  }
                  TR
                  {
                        TD { WIDTH="10%" text("Password : " ) }
                        TD { Input { type = "password" } }
                  }
                  TR
                  {

                        TD { WIDTH="10%" text("Notes") }
                        TD { TextArea { width="100%" rows = 10  cols = 10
                                        text("type text here...") } }
                  }
                  TR
                  {
                        TD { WIDTH="10%" text("Gender") }
                        TD {
                          select
                           {
                                 width = "100%"
                                 option { text("Male") }
                                 option { text("Female") }
                           }
                        }
                  }
                  TR
                  {
                        TD {   WIDTH="10%" text("Role") }
                        TD
                        {
                          select
                          {
                                 multiple = "multiple"
                                 width    = "100%"
                                 option { text("student") }
                                 option { text("admin") }
                           }
                        }
                  }
                }
                Input { type = "submit" value = "send" }
                Image { src="upload/profile1.jpg" alt="profile"}
                Input { type = "checkbox" value = "Old Member"} text("old member")
                Input { type = "range" min=1 max=100}
                Input { type = "number" min=1 max=100}
                Input { type = "radio" color="black" name="one"
                        value = "one"} text("one")
          }
        }
        div
        {
          color = "white"
          backgroundcolor = "blue"
          width = "100%"
          UL
          {
                LI { TEXT("ONE") }
                LI { TEXT("TWO") }
                LI { TEXT("THREE") }
          }
        }
        div
        {
          audio
          {
                src = "horse.ogg"
                type = "audio/ogg"
          }

          video
          {
                 width = 320
                 height = 240
                 src = "movie.mp4"
                 type = "video/mp4"
          }

          Input
          {
                type = "color"
                value = "#ff0000"
                onchange = "clickColor(0, -1, -1, 5)"
          }
        }
  }

Screen Shot:

Using Objects Using Objects - part 2

Using Bootstrap Library using Functions

The next example uses the Bootstrap JavaScript Library when generating the HTML page.

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

Func Main
  new BootstrapPage {
        divstart([ :class = "container" ])
           divstart([ :class = "jumbotron"  ])
                h1("Bootstrap Page")
          divend()
          divstart([ :class = :row ])
                divstart([ :class = "col-sm-4" ])
                  h3("Welcome to the Ring programming language")
                  p([ :text = "Using a scripting language is very fun!" ])
                divend()
                divstart([ :class = "col-sm-4" ])
                  h3("Welcome to the Ring programming language")
                  p([ :text = "using a scripting language is very fun!" ])
                divend()
                divstart([ :class = "col-sm-4" ])
                  h3("Welcome to the Ring programming language")
                  p([ :text = "using a scripting language is very fun!" ])
                divend()
          divend()
        divend()
  }

Screen Shot:

Bootstrap

Using Bootstrap Library using Objects

The next example uses the Bootstrap JavaScript Library when generating the HTML page.

Instead of using functions to generate the HTML elements, we will use objects.

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Import System.Web

Func Main
  BootStrapWebPage()
  {
        div
        {
          classname = :container
          div
          {
                classname = :jumbotron
                H1 {   text("Bootstrap Page")   }
          }
          div
          {
                classname = :row
                for x = 1 to 3
                  div
                  {
                        classname = "col-sm-4"
                        H3 { html("Welcome to the Ring programming language") }
                        P  { html("Using a scripting language is very fun!") }
                  }
                next
          }
          div
          {
                classname = :row
                div
                {
                  classname = "col-sm-4"
                  Button
                  {
                        classname = "btn btn-info btn-lg"
                        datatoggle= "modal"
                        datatarget = "#myModal"
                        text("Open Large Modal")
                  }
                }
                div
                {
                  classname = "col-sm-4"
                  Button {  classname = "btn btn-default btn-lg" text("default") }
                  Button {  classname = "btn btn-primary btn-md" text("primary") }
                  Button {  classname = "btn btn-sucess btn-sm"  text("sucess") }
                  Button {  classname = "btn btn-info btn-xs"    text("info") }
                  Button {  classname = "btn btn-warning"        text("warning") }
                  Button {  classname = "btn btn-danger"         text("danger") }
                  Button {  classname = "btn btn-link"           text("link") }
                }
                div
                {
                  classname = "col-sm-4"
                  Button {  classname = "btn btn-default btn-block" text("default") }
                  Button {  classname = "btn btn-primary btn-block" text("primary") }
                  Button {  classname = "btn btn-sucess btn-block"  text("sucess") }
                  Button {  classname = "btn btn-info btn-block"    text("info") }
                  Button {  classname = "btn btn-warning btn-block" text("warning") }
                  Button {  classname = "btn btn-danger btn-block"  text("danger") }
                  Button {  classname = "btn btn-link btn-block"    text("link") }
                }
                div
                {
                  classname = "col-sm-4"
                  div { classname = "btn-group"
                        button {  classname="btn btn-primary" text("one") }
                        button {  classname="btn btn-primary" text("two") }
                        button {  classname="btn btn-primary" text("three") }
                  }
                }
                div
                {
                  classname = "col-sm-4"
                  div { classname = "btn-group btn-group-lg"
                        button {  classname="btn btn-primary" text("one") }
                        button {  classname="btn btn-primary" text("two") }
                        button {  classname="btn btn-primary" text("three") }
                  }
                }
                div
                {
                  classname = "col-sm-4"
                  div {
                        classname = "btn-group-vertical btn-group-lg"
                        button {  classname="btn btn-primary" text("one") }
                        button {  classname="btn btn-primary" text("two") }
                        button {  classname="btn btn-primary" text("three") }
                  }
                }
          }
          div { classname="modal fade" id="myModal" role="dialog"
                div { classname = "modal-dialog modal-lg"
                  div { classname="modal-content"
                        div { classname="modal-header"
                          button {  classname="close" datadismiss="modal"
                                html("&times")
                          }
                          h4 {  classname="modal-title"
                                text("Modal Header")
                          }
                        }
                        div { classname = "modal-body"
                          p { text("This is a large model.") }
                        }
                        div { classname="modal-footer"
                          button { classname = "btn btn-default" datadismiss="modal"
                                text("close")
                          }
                        }
                  }
                }
          }
        }
  }

Screen Shot:

Bootstrap Page using Objects

CRUD Example using MVC

The next example uses the weblib.ring & datalib.ring.

The datalib.ring contains classes for creating database applications using MVC pattern.

In this example we create an object from the SalaryController class then call the Routing method.

We define the website variable to contains the basic url of the page.

When we create the SalaryModel class from the ModelBase class, the salary table will be opened and the columns data will be defined as attributes in the model class.

The SalaryView class create an object from the SalaryLanguageEnglish class to be used for translation.

The method AddFuncScript is used to call the form for adding/modifying record data.

The method FormViewContent is used to determine the controls in the form when we add or modify a record.

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Load "datalib.ring"
Import System.Web

website = "ex24.ring"

New SalaryController { Routing() }

Class SalaryModel from ModelBase

Class SalaryController From ControllerBase

Class SalaryView From ViewBase

  oLanguage = new SalaryLanguageEnglish

  Func AddFuncScript oPage,oController
        return   oPage.scriptfuncajax("myadd",oController.cMainURL+
                 oController.cOperation+"=add","mysubpage")

  Func FormViewContent oController,oTranslation,oPage
        return [
                        [ oTranslation.aColumnsTitles[2], "textbox", "name",
                          oController.oModel.Name, oPage.stylewidth("100%")    ],
                        [ oTranslation.aColumnsTitles[3], "textbox", "salary",
                          oController.oModel.Salary, oPage.stylewidth("50%") ]
                   ]

Class SalaryLanguageEnglish
  cTitle = "Salary Table"
  cBack = "back"
  aColumnsTitles = ["ID","Name","Salary"]
  cOptions = "Options"
  cSearch = "Search"
  comboitems = ["Select Option...","Edit","Delete"]
  cAddRecord = "Add Record"
  cEditRecord = "Edit Record"
  cRecordDeleted = "Record Deleted!"
  aMovePages = ["First","Prev","Next","Last"]
  cPage = "Page"
  cOf = "of"
  cRecordsCount = "Records Count"
  cSave = "Save"
  temp = new page
  cTextAlign = temp.StyleTextRight()
  cNoRecords = "No records!"

Screen Shot:

Salary Table Salary Table - Search

Users registration and Login

We have the users classes (Model, View & Controller) to deal with the users data like username & email.

The next code is stored in ex25_users.ring

Class UsersModel from ModelBase
  cSearchColumn = "username"

Class UsersController From ControllerBase
  aColumnsNames = ["id","username","email"]

  Func UpdateRecord
        oModel.id = aPageVars[cRecID]
        oModel.updatecolumn("username", aPageVars[:username] )
        oModel.updatecolumn("email", aPageVars[:email] )
        oView.UpdateView(self)

Class UsersView from ViewBase

  oLanguage = new UsersLanguageEnglish

  Func AddFuncScript oPage,oController
        return   oPage.scriptfunc("myadd",oPage.scriptredirection("ex26.ring"))

  Func FormViewContent oController,oTranslation,oPage
        return [
                        [oTranslation.aColumnsTitles[2],"textbox","username",
                        oController.oModel.UserName,oPage.stylewidth("100%")],
                        [oTranslation.aColumnsTitles[3],"textbox","email",
                        oController.oModel.Email,oPage.stylewidth("50%")]
                   ]

Class UsersLanguageEnglish
  cTitle = "Users Table"
  cBack = "back"
  aColumnsTitles = ["ID","User Name","Email"]
  cOptions = "Options"
  cSearch = "Search"
  comboitems = ["Select Option...","Edit","Delete"]
  cAddRecord = "Add Record"
  cEditRecord = "Edit Record"
  cRecordDeleted = "Record Deleted!"
  aMovePages = ["First","Prev","Next","Last"]
  cPage = "Page"
  cOf = "of"
  cRecordsCount = "Records Count"
  cSave = "Save"
  temp = new page
  cTextAlign = temp.StyleTextRight()
  cNoRecords = "No records!"

In the file ex25.ring we load ex25_users.ring then create an object from UsersController class.

Using the created object, we call the routing method.

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Load "datalib.ring"
Load "ex25_users.ring"

Import System.Web
website = "ex25.ring"
New UsersController { Routing() }

Screen Shot:

Users Table

See the next code for the registration page

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Load "datalib.ring"
Import System.Web

website = "ex26.ring"

new page {
  boxstart()
        text( "Register")
        newline()
  boxend()
  divstart([:style = stylegradient(6) + stylesize("100%","95%") ])
  link([ :url = website, :title = "back" , :style = stylecolor("white")])
  newline()
  divstart([ :style= styledivcenter("500","160") + stylegradient(52) ])
  formpost("ex27.ring")
        tablestart([ :Style =    stylemarginleft("2%") + stylemargintop("2%") +
                                 stylewidth("90%") ])
          rowstart([])
                cellstart([:style = stylewidth("20%") + styleheight(30)])
                  text("User Name")
                cellend()
                cellstart([ :style = stylewidth("80%")  ])
                  textbox([:name = "username", :style = stylewidth("100%")])
                cellend()
          rowend()
          rowstart([])
                cellstart([ :Style = styleheight(30)])
                  text("Password")
                cellend()
                cellstart([])
                  textbox([:name = "password" , :type = "password"])
                cellend()
          rowend()
          rowstart([])
                cellstart([ :style = styleheight(30)])
                  text("Email")
                cellend()
                cellstart([])
                  textbox([:name = "email" , :style = stylewidth("100%")])
                cellend()
          rowend()
          rowstart([])
                cellstart([ :style = styleheight(30)])
                cellend()
                cellstart([ :style = styleheight(30)])
                  submit([:value = "Register"  ])
                cellend()
          rowend()
        tableend()
  formend()
  divend()
  divend()
}

Screen Shot:

Registration Page

The Registration response

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Load "datalib.ring"
Load "ex25_users.ring"

Import System.Web

oUser = new UsersModel
oUser.Connect()
if oUser.findwith("username",aPageVars["username"])
        new page {
                text("The user name is already registered")
        }
        return
ok
if oUser.findwith("email",aPageVars["email"])
        new page {
                text("This email is already registered")
        }
        return
ok

aPageVars["salt"] = str2hex(RandBytes(32))
aPageVars["pwhash"] = sha256(aPagevars["password"]+aPageVars["salt"])
aPageVars["sessionid"] = str2hex(randbytes(32))
oUser.Insert()
new page {
        cookie("sessionid",aPageVars["sessionid"])
        text("New User Created!")
        newline()
        text("User Name : " + aPageVars["username"])
        newline()
}
oUser.Disconnect()

See the next code for the Login page

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Load "datalib.ring"

Import System.Web

website = "ex28.ring"

new page {
  boxstart()
        text( "Login")
        newline()
  boxend()
  divstart([:style = stylegradient(6) + stylesize("100%","95%") ])
  link([ :url = website, :title = "back" , :style = stylecolor("white")])
  newline()
  divstart([ :style= styledivcenter("500","130") + stylegradient(52) ])
  formpost("ex29.ring")
        tablestart([ :Style =   stylemarginleft("2%") + stylemargintop("2%") +
                                stylewidth("90%") ])
          rowstart([])
                cellstart([:style = stylewidth("20%") + styleheight(30)])
                  text("User Name")
                cellend()
                cellstart([ :style = stylewidth("80%") ])
                  textbox([:name = "username", :style = stylewidth("100%")])
                cellend()
          rowend()
          rowstart([])
                cellstart([ :style = styleheight(30)])
                  text("Password")
                cellend()
                cellstart([])
                  textbox([:name = "password" , :type = "password"])
                cellend()
          rowend()
          rowstart([])
                cellstart([ :style = styleheight(30) ])
                cellend()
                cellstart([])
                  submit([:value = "Login"  ])
                cellend()
          rowend()
        tableend()
  formend()
  divend()
  divend()
}

Screen Shot:

Login Page

The response page

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Load "datalib.ring"
Load "ex25_users.ring"

Import System.Web

oUser = new UsersModel
oUser.Connect()
lResult = oUser.FindWith("username",aPageVars["username"])
new page {
        if lResult
                if sha256(aPagevars["password"]+oUser.Salt) = oUser.pwhash
                        text ("Correct Password!")
                        aPageVars["sessionid"] = str2hex(randbytes(32))
                        oUser.UpdateColumn("sessionid",aPageVars["sessionid"])
                        cookie("sessionid",aPageVars["sessionid"])
                else
                        text ("Bad password!")
                ok
        else
                text("Bad User Name!")
        ok
}
oUser.Disconnect()

The next code for checking if the user needs to login or not

#!c:\ring\bin\ring.exe -cgi
Load "weblib.ring"
Load "datalib.ring"
Load "ex25_users.ring"

Import System.Web

oUser = new UsersModel
oUser.Connect()
lResult = oUser.FindWith("sessionid",aPageVars["sessionid"])
new page {
        if lResult
                text("User Name : " + oUser.username )
        else
                text("Please Login First!")
        ok
}
oUser.Disconnect()

Database, ModelBase & ControllerBase classes

In this section we will see some code from datalib.ring

The next code presents the Database, ModelBase & ControllerBase classes

Import System.Web

Class Database

  cServer = "localhost"
  cUserName = "root"
  cPassword = "root"
  cDatabase = "mahdb"

  Func Connect

        con = mysql_init()
        mysql_connect(con, cServer, cUserName, cPassWord,cDatabase)

  Func Disconnect

        mysql_close(con)

  Func Query cQuery

        mysql_query(con,cQuery)

  Func QueryResult

        return mysql_result(con)

  Func QueryResultWithColumns
        # return columns names + query result
        return mysql_result2(con)

  Func QueryValue
        aResult = mysql_result(con)
        if islist(aResult) and len(aResult) >= 1
          aResult = aResult[1]
          if len(aResult) >= 1
                return aResult[1]
          ok
        ok
        return 0

  Func EscapeString x
        if isstring(x)
          return MySQL_Escape_String(con,x)
        else
          return MySQL_Escape_String(con,string(x))
        ok

  Private
        con = NULL

Class ModelBase from Database

  cTableName = ""
  cSearchColumn = "name"
  aColumns = []
  aQueryResult = []
  ID = 0

  # set table name from class name
  classname = lower(classname(self))
  if right(classname,5) = :model
        cTablename = left(classname,len(classname)-5)
  ok

  Func Insert

        cValues = ""
        for x in aColumns
          cValues += "'" + EscapeString(aPageVars[x]) + "',"
        Next
        cValues = left(cValues,len(cValues)-1)  # remove last comma
        cColumns = ""
        for x in aColumns
          cColumns += x + ","
        next
        cColumns = left(cColumns,len(cColumns)-1)
        query("insert into " + cTableName + "("+cColumns+") values (" +
                 cValues + ")" )

  Func Update nID

        cStr = ""
        for x in aColumns
          cStr += x + " = '" + EscapeString(aPageVars[x]) + "' , "
        # the space after comma is necessary
        Next
        cStr = left(cStr,len(cStr)-2)
        query("update " + cTableName + " set " + cStr + " where id = " + nID )

  Func UpdateColumn cColumn,cValue
        query("update " + cTableName + " set " + cColumn + " = '" +
        EscapeString(cValue) + "' where id = " + self.ID )


  Func Count cValue

        query("SELECT count(*) FROM " + cTableName +
                 " where "+cSearchColumn+" like '" + EscapeString(cValue) + "%'")
        return queryValue()

  Func Read nStart,nRecordsPerPage

        query("SELECT * FROM "+ cTableName+" limit " + EscapeString(nStart) + "," +
        EscapeString(nRecordsPerPage) )
        aQueryResult = queryResult()

  Func Search cValue,nStart,nRecordsPerPage

        query("SELECT * FROM "+ cTableName+" where "+cSearchColumn+" like '" +
        EscapeString(cValue) + "%'" +
          " limit " + EscapeString(nStart) + "," + EscapeString(nRecordsPerPage) )
        aQueryResult = queryResult()

  Func Find nID

        query("select * from " + cTableName + " where id = " + EscapeString(nID) )
        aResult = queryResult()[1]
        # move the result from the array to the object attributes
        ID = nID
        cCode = ""
        for x = 2 to len(aResult)
          cCode += aColumns[x-1] + " = hex2str('" + str2hex(aResult[x]) + "')" + nl
        next
        eval(cCode)

  Func FindWith cColumn,cValue

        query("select * from " + cTableName + " where "+cColumn+" = '" +
        EscapeString(cValue) + "'" )
        aResult = queryResult()
        if len(aResult) > 0
          aResult = aResult[1]
        else
          return 0
        ok
        # move the result from the array to the object attributes
        ID = aResult[1]
        cCode = ""
        for x = 2 to len(aResult)
          cCode += aColumns[x-1] + " = hex2str('" + str2hex(aResult[x]) + "')" + nl
        next
        eval(cCode)
        return 1

  Func Delete ID

        query("delete from " + cTableName + " where id = " + EscapeString(ID) )

  Func Clear

        cCode = ""
        for x in aColumns
          cCode += x + ' = ""' + nl
        next
        eval(cCode)

  Func LoadModel

        # create the columns array
        query("SELECT * FROM "+ cTableName + " limit 0,1")
        aQueryResult = QueryResultWithColumns()[1]
        for x = 2 to len(aQueryResult)
          aColumns + lower(trim(aQueryResult[x]))
        next

        # create attribute for each column
        for x in aColumns
          addattribute(self,x)
        next

  Func Connect

        Super.Connect()
        if nLoadModel = 0
          nLoadModel = 1
          LoadModel()
        ok

  private

        nLoadModel = 0


Class ControllerBase

  nRecordsPerPage = 5
  nRecordsCount = 0
  nPagesCount = 0
  nActivePage = 0

  # Dynamic creation of oView = new tablenameView and oModel = new tablename.Model
  classname = lower(classname(self))
  if right(classname,10)  = :controller
        tablename = left(classname,len(classname)-10)
        cCode = "oView = new " + tablename+"View" + nl
        cCode += "oModel = new " + tablename+"Model" + nl
        eval(cCode)
        oModel.connect()
  ok

  cSearchName = "searchname"
  cPart = "part"
  cPageError = "The page number is not correct"
  cLast = "last"
  cOperation = "operation"
  cRecID = "recid"

  aColumnsNames = ["id"]
  for t in oModel.aColumns
        aColumnsNames + t
  next

  cMainURL = website + "?"

  func Routing

        switch      aPageVars[cOperation]
        on NULL     showtable()
        on :add     addrecord()
        on :save    saverecord()
        on :delete  deleterecord()
        on :edit    editrecord()
        on :update  updaterecord()
        off

  func ShowTable

        nRecordsCount = oModel.Count( aPageVars[cSearchName] )

        nPagesCount = ceil(nRecordsCount / nRecordsPerPage)

        if aPageVars[cPart] = cLast
          aPageVars[cPart] = string(nPagesCount)
        ok

        nActivePage = number(aPageVars[cPart])
        if nActivePage = 0 nActivePage = 1 ok

        if ( nActivePage > nPagesCount ) and nRecordsCount > 0
          ErrorMsg(cPageError)
          return
        ok

        nStart = (nActivePage-1)*nRecordsPerPage

        if aPageVars[cSearchName] = NULL
          oModel.Read( nStart,nRecordsPerPage )
        else
          oModel.Search( aPageVars[cSearchName],nStart,nRecordsPerPage )
        ok

        oView.GridView(self)

  func AddRecord

        oModel.clear()
        oView.FormViewAdd(Self,:save,false) # false mean don't include record id

  func SaveRecord

        oModel.Insert()
        oView.SaveView(self)

  func EditRecord

        oModel.Find( aPageVars[cRecID] )
        oView.FormViewEdit(Self,:update,true) # true mean include record id

  func UpdateRecord

        oModel.update( aPageVars[cRecID] )
        oView.UpdateView(self)

  func DeleteRecord

        oModel.Delete( aPageVars[cRecID] )
        oView.DeleteView()

  func braceend

        oModel.Disconnect()

WebLib API

In this section we will see the web library functions, classes and methods.

Function Parameters Description
LoadVars None Save the request parameters and cookies to aPageVars List
WebPage None Create new object from the WebPage Class
BootStrapWebPage None Create new object from the BootStrapWebPage Class
HTMLSpecialChars cString Encode Special characters to HTML equivalent
Template cFile,oObject Execute Ring Code in cFile after accessing oObject using {}
Alert cMessage Generate HTML Web Page that display cMessage using JavaScript Alert()
HTML2PDF cString Generate and Display PDF File from HTML String (cString)

The Package System.Web contains the next classes

Class Name Description
Application Contains methods for Encoding, Decoding, Cookies & More.
Page Contains methods to generate HTML pages.
ScriptFunctions Contains methods to generate some JavaScript Functions.
StyleFunctions Contains methods to generate CSS.
PageBuffer Generate HTML Page in memory (don’t print the output).
HTML2PDF Generate PDF File from HTML code.
BootStrapPage Using BootStrap Library.
WebPage Generate page using objects for each element.
BootStrapWebPage Generate page using objects, using BootStrap Library.
ObjsBase Parent Class for page objects.
NewObjectsFunctions Methods to create new objects in the page or element.
H1 Wraps HTML H1.
H2 Wraps HTML H2.
H3 Wraps HTML H3.
H4 Wraps HTML H4.
H5 Wraps HTML H5.
H6 Wraps HTML H6.
P Wraps HTML P.
Link Wraps HTML link.
NewLine Wraps HTML NewLine.
Div Wraps HTML Div.
Form Wraps HTML Form.
Input Wraps HTML Input.
TextArea Wraps HTML TextArea.
Select Wraps HTML Select.
Option Wraps HTML Option.
Image Wraps HTML Image.
UL Wraps HTML UL.
LI Wraps HTML LI.
Table Wraps HTML Table.
TR Wraps HTML TR.
TD Wraps HTML TD.
TH Wraps HTML TH.
Audio Wraps HTML Audio.
Video Wraps HTML Video.
Nav Wraps HTML Nav.
Span Wraps HTML Span.
Button Wraps HTML Button.

Application Class

Method Parameters Description
DecodeString cString Decode request parameters
Decode cString Decode multipart/form-data
GetFileName aArray,cVar Get File Name in aArray using cVar
SetCookie name,value,expires,path,domain,secure Set Cookie
Cookie name,value Set Cookie using name and value only
GetCookies None Get Cookies
URLEncode cString URL Encode
ScriptLibs None Add JavaScript Libraries like BootStrap
Print None Print Page Content
Style cStyle Add cStyle to page CSS content
StartHTML None Add HTTP Header to page content

The method DecodeString is used to get HTTP request parameters.

The methods Decode and GetFileName are used for uploading files.

The methods SetCookie, Cookie & GetCookies are used for adding and reading cookies.

The methods StartHTML, ScriptsLibs, Style & Print are used for page structure and JS/CSS support.

The method URLEncode is used to encode a URL to be used in HTML pages.

Page Class

Method Parameters Description
text x add HTMLSpecialChars(x) to page content (accept strings and numbers)
html cString add html code to page content
h1 x add x to page content between <h1> and </h1>
h2 x add x to page content between <h2> and </h2>
h3 x add x to page content between <h3> and </h3>
h4 x add x to page content between <h4> and </h4>
h5 x add x to page content between <h5> and </h5>
h6 x add x to page content between <h6> and </h6>
p aPara HTML <p> </p>, uses aPara List as Hash to get attributes
NewLine None add <br /> to page content
AddAttributes aPara Convert aPara list as hash to HTML element attributes
Link aPara HTML <a href> and </a>, uses aPara List as Hash to get attributes
Image aPara HTML <img>, uses aPara List as Hash to get attributes
Button aPara HTML <input type=”button”>, uses aPara List as Hash to get attributes
ButtonLink aPara HTML <input type=”button”>, uses link attribute to navigate to link
Textbox aPara HTML <input type=”text”>, uses aPara List as Hash to get attributes
Editbox aPara HTML <textarea> and </textarea>, uses aPara to get attributes
Combobox aPara HTML <select>, uses items attribute as list for <option>
Listbox aPara HTML <select multiple=’multiple’>, uses items attribute for <option>
ulstart aPara HTML <ul>
ulend aPara HTML </ul>
listart aPara HTML <li>
liend aPara HTML </li>
List2UL aList Generate HTML <ul> including items from Ring List items
DivStart aPara HTML <div>, uses aPara List as Hash to get attributes
NavStart aPara HTML <nav>, uses aPara List as Hash to get attributes
SpanStart aPara HTML <span>, uses aPara List as Hash to get attributes
BoxStart None Generate Div with black background to be used as page header
DivEnd None HTML </div>
NavEnd None HTML </nav>
SpanEnd None HTML </span>
BoxEnd None HTML </div>, the same as divend()
FormStart cAction HTML <form>, with cAction as the action attribute or an empty value
FormPost cAction HTML <form method=”post”> , with cAction as the action attribute
FormEnd None HTML </form>
Submit aPara HTML <input type=”submit”>
Hidden cName,cValue HTML <input type=”hidden”>
FormUpload x HTML Form, method=”post” enctype=”multipart/form-data” and x = action
UploadFile x HTML <input type=”file”> and name = x
Video aPara HTML <video>
Audio aPara HTML <audio>
GetColor aPara Select Color
Radio aPara HTML <input type=”radio”>
Checkbox aPara HTML <input type=”checkbox”>
Spinner aPara HTML <input type=”number”>
Slider aPara HTML <input type=”range”>
TableStart aPara HTML <table>
TableEnd None HTML </table>
RowStart aPara HTML <tr>
RowEnd None HTML </tr>
CellStart aPara HTML <td>
CellEnd None HTML </td>
HeaderStart aPara HTML <th>
HeaderEnd None HTML </th>

aPara in the page methods is a list contains attributes and values. Using aPara we can set values for the next attributes

classname id name align style dir value onclick oncontextmenu ondblclick
onmousedown onmouseenter onmouseleave onmousemove onmouseover onmouseout
onmouseup onkeydown onkeypress onkeyup onabort onbeforeunload onerror
onhashchange onload onpageshow onpagehide onresize onscroll onunload
onblur onchange onfocus onfocusin onfocusout oninput oninvalid onreset
onsearch onselect onsubmit ondrag ondragend ondragenter ondragleave
ondragover ondragstart ondrop oncopy oncut onpaste onafterprint
onbeforeprint oncanplay oncanplaythrough ondurationchange onemptied
onended onloadeddata onloadedmetadata onloadstart onpause onplay
onplaying onprogress onratechange onseeked onseeking onstalled onsuspend
ontimeupdate onvolumechange onwaiting animationend animationiteration
animationstart transitionend onmessage onopen onmousewheel ononline
onoffline onpostate onshow onstorage ontoggle onwheel ontouchcancel
ontouchend ontouchmove ontouchstart color opacity background backgroundattachment
backgroundcolor backgroundimage backgroundposition backgroundrepeat backgroundclip
backgroundorigin backgroundsize border borderbottom borderbottomcolor
borderbottomleftradius borderbottomrightradius borderbottomstyle borderbottomwidth
bordercolor borderimage borderimageoutset borderimagerepeat borderimageslice
borderimagesource borderimagewidth borderleft borderleftcolor borderleftstyle
borderleftwidth borderradius borderright  borderrightcolor borderrightstyle
borderrightwidth borderstyle bordertop bordertopcolor bordertopleftradius
bordertoprightradius bordertopstyle bordertopwidth borderwidth boxdecorationbreak
boxshadow bottom clear clip display float height left margin marginbottom marginleft
marginright margintop maxheight maxwidth minheight minwidth overflow overflowx
overflowy padding paddingbottom paddingleft paddingright paddingtop position
right top visibility width verticalalign zindex aligncontent alignitems alignself
flex flexbasis flexdirection flexflow flexgrow flexshrink flexwrap justifycontent
order hangingpunctuation hyphens letterspacing linebreak lineheight overflowwrap
tabsize textalign textalignlast textcombineupright textindent textjustify
texttransform whitespace wordbreak wordspacing wordwrap textdecoration
textdecorationcolor textdecorationline textdecorationstyle textshadow
textunderlineposition @fontface @fontfeaturevalues font fontfamily fontfeaturesettings
fontkerning fontlanguageoverride fontsize fontsizeadjust fontstretch fontstyle
fontsynthesis fontvariant fontvariantalternates fontvariantcaps fontvarianteastasian
fontvariantligatures fontvariantnumeric fontvariantposition fontweight direction
textorientation unicodebidi writingmode bordercollapse borderspacing captionside
emptycells tablelayout counterincrement counterreset liststyle liststyleimage
liststyleposition liststyletype @keyframes animation animationdelay animationdirection
animationduration animationfillmode animationiterationcount animationname
animationplaystate animationtimingfunction backfacevisibility perspective
perspectiveorigin transform transformorigin transformstyle transition
transitionproperty transitionduration transitiontimingfunction transitiondelay
boxsizing content cursor imemode navdown navindex navleft navright navup
outline outlinecolor outlineoffset outlinestyle outlinewidth resize textoverflow
breakafter breakbefore breakinside columncount columnfill columngap columnrule
columnrulecolor columnrulestyle columnrulewidth columnspan columnwidth columns
widows orphans pagebreakafter pagebreakbefore pagebreakinside marks quotes
filter imageorientation imagerendering imageresolution objectfit objectposition
mask masktype mark markafter markbefore phonemes rest restafter restbefore
voicebalance voiceduration voicepitch voicepitchrange voicerate voicestress
voicevolume marqueedirection marqueeplaycount marqueespeed marqueestyle datatoggle
dataride datatarget dataslideto dataslide datadismiss dataplacement datacontent
datatrigger dataspy dataoffset dataoffsettop

ScriptFunctions Class

This class contains methods for adding JavaScript code to the generated web page.

The class methods are merged to the Page class, so we can use the next methods with page objects directly.

Method Parameters Description
Script cCode Add cCode string between <script> and </script>
ScriptRedirection cURL set window.location to cURL
ScriptFunc cFuncName,cCode Define function cFuncName that contains cCode
ScriptFuncAlert cFuncName,cMsg Define function cFuncName that uses alert() to print cMsg
ScriptFuncAjax cFuncName,cLink,cDiv Define function cFuncName that load cLink in cDiv
ScriptFuncClean cFuncName,cDiv Define function cFuncName that clear the cDiv
ScriptFuncSelect cF,aL,cD,cR,cGR,cFC,nTO,cL1,cL2 Used to Edit/Delete Grid Record
ScriptScrollFixed cDiv,nSize Set cDiv as Fixed Div with Size = nSize

StyleFunctions Class

This class contains methods for adding CSS to the generated web page.

Like ScriptFunctions Class, The StyleFunctions class methods are merged to the Page class, so we can use the next methods with page objects directly.

Method Parameters Description
StyleFloatLeft None Return float: left ;
StyleFloatRight None Return float: right ;
StyleSizeFull None Return width: 100% ; height: 100% ;
Stylecolor x Return ” color: ” + x + ” ; “
Stylebackcolor x Return ” background-color: ” + x + ” ;”
StyleTextCenter None Return “text-align: center ;”
StyleTextRight None Return “text-align: right ;”
StyleTextLeft None Return “text-align: left ;”
StyleSize x,y Return ” width: ” + x + ” ; height: ” + y + ” ;”
StyleWidth x Return ” width: ” + x + ” ;”
StyleHeight x Return ” height: ” + x + ” ;”
StyleTop x Return ” top: ” + x + ” ;”
StyleLeft x Return ” Left: ” + x + ” ;”
StylePos x,y Return ” top: ” + x + ” ;” + ” Left: ” + y + ” ;”
StyleHorizontalCenter None Return ” margin-right:auto ; margin-left:auto; “
StyleMarginTop x Return ” margin-top: ” + x + ” ;”
StyleMarginRight x Return ” margin-right: ” + x + ” ;”
StyleMarginLeft x Return ” margin-left: ” + x + ” ;”
StyleDivCenter nWidth,nHeight Create Div in the center of the page
StyleAbsolute None Return ” position:absolute ;”
StyleFixed None Return ” position:fixed ;”
StyleZIndex x Return ” z-index: ” + x + ” ;”
StyleFontSize x Return ” font-size: ” + x + ” ;”
StyleGradient x Generate Gradient (x values from 1 to 60)
StyleTable None Set table properties
StyleTableRows id Set different color to even and odd rows in the table
StyleTableNoBorder None Return ” border-style: none;”