Tutorial 21: How to Use Session Variables

This tutorial explains how to benefit from session variables in Formspider. You will discover how to define, store and destroy session variables.

In this tutorial you will create a basic application containing two screens. First one is a login screen containing “Username” and “Password” fields and a “Sign In” button. Second one is a sample setting screen where the user can change his current password. You will discover how to store the username and password values provided by the user in session variables, how to retrieve their values and how to destroy them when necessary.

Why you need session variables?

Formspider is a stateless framework, meaning that it’s configured to work in stateless connection structure. But it’s often needed to store some session specific information (like username, shopping items…) during user session’s lifetime. Formspider solves this demand by allowing you to create and store session level variables.

Defining and Storing a Session Variable

Open Formspider IDE and click “New Application” under the “File” menu. The “New Application” dialog will show up. Enter “sessionVaribles” as the name of the application and “HR” as its Datasource Schema name.  If you are using Formspider Online, you do not need to enter database schema name since your account is already configured to use your online database. Leave other fields empty and click “OK”. This creates the “sessionVaribles” application with a default mainframe (called “mainFrame”) and a default panel (called “mainPanel”).

You will create a panel which will contain “Username” and “Password” fields and “Sign In” button of your login screen. To achieve this, Expand the “Containers” accordion Panel, select the “Panels” node in the navigation tree and click the “+” button to create a new Simple Panel. Alternatively, you may right click the “Panels” node and select the “New” menu item from the pop-up menu. The “New Panel” dialog will show up. Enter “loginPanel” as the name of the panel. Click “OK” to create and open the panel in the editor.


Creating “loginPanel”

Add a textField labeled “Username”, a passwordField labeled “Password” and a “Sing In” button in your “loginPanel”.

<panel>
  <tableLayout cellSpacing="10">
    <!-- ******************************************** -->
    <!-- Dummy row to adjust column widths -->
    <row height="0">
      <!-- This column has a static 120 px width -->
      <cell width="120"/>
      <!-- This one is dynamic and it will expand to the free space of the row -->
      <cell/>
    </row>
    <row height="30">
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" font-size="16" label="Login to Formspider"/>
      </cell>
    </row>
    <row height="10"/>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="Username:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <textField name="username" domain="DefaultVarchar2"/>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="Password:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <passwordField name="password" domain="DefaultVarchar2"/>
      </cell>
    </row>
    <row height="20">
      <cell/>
      <cell hAlign="Left" vAlign="Full">
        <button label="Sign In"/>
      </cell>
    </row>
  </tableLayout>
</panel>

Next you will add the “loginPanel” into “mainPanel” for displaying it when the application is run. To accomplish this, double-click and open the “mainPanel” in the editor and include “loginPanel” in the “mainPanel”;

<panel>
  <borderLayout>
    <cell docking="Center" name="mainPanelCenter">
      <include panelName="loginPanel"/>
    </cell>
  </borderLayout>
</panel>

When “Sign In” button is pressed you will define two session variables keeping values entered in “Username” and “Password” fields. To accomplish this you have to create a Formspider action which will be fired when “Sign In” button is pressed.

In your datasource schema, create a package called “session_pkg” and open your newly created “session_pkg” package in your favorite PL/SQL Editor. Add a procedure named “signIn” and ensure that the procedure is exposed in the package specification. This procedure uses api_component.getValueTX API to retrieve the values entered in “Username” and “Password” fields. If both of these values are not null it calls api_session.add API to define two session variables named “username” and “password” and set their values. Please notice that api_session.add API fulfill two functionality, first it defines the session variable if it’s not defined before and secondly sets its value. So in future if you want to update value of a specific session variable you will use again api_session.add API.

procedure signIn is
  v_userName_tx varchar2(4000);
  v_password_tx varchar2(4000);
begin
  v_userName_tx := api_component.getvaluetx('loginPanel.username');
  v_password_tx := api_component.getvaluetx('loginPanel.password');
  if v_userName_tx is not null and v_password_tx is not null then
    -- define session varaibles and set their values
    api_session.add('username', v_userName_tx);
    api_session.add('password', v_password_tx);
  else
    api_application.showpopupmessage('Failed: Username or Password cannot be null');
  end if;
end;

In Formspider IDE expand the “Actions” accordion, select the “Actions” node, click the “+” button to create a new action. Alternatively you may right click the “Actions” node and select “New” from the pop-up menu. The “New Action” dialog will show up. Enter “signIn” as the action name and “session_pkg.signIn ” as the procedure. Click “OK” to save your action.


Creating “signIn” action

Open the “loginPanel” in the editor. Add a buttonPress event to the “Sign In” button triggering the “signIn” action, the panel XML should look like;

<panel>
  <tableLayout cellSpacing="10">
    <!-- ******************************************** -->
    <!-- Dummy row to adjust column widths -->
    <row height="0">
      <!-- This column has a static 120 px width -->
      <cell width="120"/>
      <!-- This one is dynamic and it will expand to the free space of the row -->
      <cell/>
    </row>
    <row height="30">
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" font-size="16" label="Login to Formspider"/>
      </cell>
    </row>
    <row height="10"/>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="Username:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <textField name="username" domain="DefaultVarchar2"/>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="Password:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <passwordField name="password" domain="DefaultVarchar2"/>
      </cell>
    </row>
    <row height="20">
      <cell/>
      <cell hAlign="Left" vAlign="Full">
        <button label="Sign In">
          <events>
            <buttonPress action="signIn"/>
          </events>
        </button>
      </cell>
    </row>
  </tableLayout>
</panel>

Run your application and enter some values in “Username” and “Password” fields. When “Sign In” button is pressed the value entered in these fields will be stored in session variables.


Defining session variables

In the following step you will learn how to retrieve value from a session variable.

Retrieving Value From a Session Variable

The second screen of your application is a simple setting panel allowing users to change their passwords. Create a new panel and enter “settingPanel” as the name of the panel. You will add two passwordFields where the users can enter their old and new passwords and a “Submit” button confirming password change. Your panel XML will look like;

<panel>
  <tableLayout cellSpacing="10">
    <!-- ******************************************** -->
    <!-- Dummy row to adjust column widths -->
    <row height="0">
      <!-- This column has a static 120 px width -->
      <cell width="120"/>
      <!-- This one is dynamic and it will expand to the free space of the row -->
      <cell/>
    </row>
    <row height="30">
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" font-size="16" label="Change Password"/>
      </cell>
    </row>
    <row height="10"/>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="Old Password:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <passwordField name="oldPassword" tabIndex="10"/>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="New Password:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <passwordField name="newPassword" tabIndex="20"/>
      </cell>
    </row>
    <row height="20">
      <cell/>
      <cell hAlign="Left" vAlign="Full">
        <button label="Submit"/>
      </cell>
    </row>
  </tableLayout>
</panel>

As part of the application flow implementation, when “Sign In” button of “loginPanel” is pressed, the user should be navigated to “settingPanel”. To achieve this open and edit “signIn” procedure as the following;

procedure signIn is
  v_userName_tx varchar2(4000);
  v_password_tx varchar2(4000);
begin
  v_userName_tx := api_component.getvaluetx('loginPanel.username');
  v_password_tx := api_component.getvaluetx('loginPanel.password');
  if v_userName_tx is not null and v_password_tx is not null then
    -- define session varaibles and set their values
    api_session.add('username', v_userName_tx);
    api_session.add('password', v_password_tx);
    -- navigate to "settingPanel"
    api_component.setvalue('settingPanel.oldPassword', in_value_tx => null);
    api_component.setvalue('settingPanel.newPassword', in_value_tx => null);
    api_panel.addpanel('mainPanel','mainPanelCenter', 'settingPanel');
  else
    api_application.showpopupmessage('Failed: Username or Password cannot be null');
  end if;
end;

When “Submit” button is pressed you have to compare the value entered in “Old Password” field with the current password of the user. You will retrieve value of current password from the “password” session variable using api_session.getValueTX API. If the “Old Password” value is correct you will update “password” session variable using api_session.add API as mentioned before.

Open “session_pkg” package and create a procedure named “setPassword” which will be used when “Submit” button is pressed.

procedure setPassword is
  v_newPassword_tx varchar2(4000);
begin
  v_newPassword_tx := api_component.getvaluetx('settingPanel.newPassword');
  if api_session.getvaluetx('password') = api_component.getvaluetx('settingPanel.oldPassword') then
    if v_newPassword_tx is not null then
      api_session.add('password', v_newPassword_tx);
      api_application.showpopupmessage('Succeed: New password is set for user "' || api_session.getvaluetx('username') ||'"');
    else
      api_application.showpopupmessage('Failed: New Password cannot be null');
    end if;
  else
    api_application.showpopupmessage('Failed: Old Password does not match with the current password for user "' || api_session.getvaluetx('username') ||'"');
  end if;
end;

Create a new action, enter “setPassword” as the action name and “session_pkg.setPassword” as the procedure. Click “OK” to save your action. Then add a buttonPress event to “Submit” button triggering “setPassword” action.

<panel>
  <tableLayout cellSpacing="10">
    <!-- ******************************************** -->
    <!-- Dummy row to adjust column widths -->
    <row height="0">
      <!-- This column has a static 120 px width -->
      <cell width="120"/>
      <!-- This one is dynamic and it will expand to the free space of the row -->
      <cell/>
    </row>
    <row height="30">
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" font-size="16" label="Change Password"/>
      </cell>
    </row>
    <row height="10"/>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="Old Password:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <passwordField name="oldPassword" tabIndex="10"/>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="New Password:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <passwordField name="newPassword" tabIndex="20"/>
      </cell>
    </row>
    <row height="20">
      <cell/>
      <cell hAlign="Left" vAlign="Full">
        <button label="Submit">
          <events>
            <buttonPress action="setPassword"/>
          </events>
        </button>
      </cell>
    </row>
  </tableLayout>
</panel>

Run your application again. Notice that when “Submit” button is pressed the password comparison made successfully.


Validation made when “Submit” button is pressed

As the final step you will discover how destroy a session variable.

Destroying Session Variables

You will need to clear and destroy all session variables when the user logged out from the application. In this final step we will add a “Logout” hyperLink to the top-right of the “settingPanel”. When this link is clicked all session variables will be destroyed and the user will navigate back to login screen.

Open “session_pkg” package and create a procedure named “logout” which will be used when “Logout” hyperLink is clicked. You will use api_session.removeAll API to destroy all session variables defined in the current session. Notice destroying a single session variable is also possible, to achieve this you can use api_session.remove API.

procedure logout is
begin
  -- destroy all session variables
  api_session.removeAll;
  api_component.setvalue('loginPanel.username', in_value_tx => null);
  api_component.setvalue('loginPanel.password', in_value_tx => null);
  api_panel.addpanel('mainPanel','mainPanelCenter', 'loginPanel');
end;

Create a new action, enter “logout” as the action name and “session_pkg.logout” as the procedure. Click “OK” to save your action. Open your “settingPanel” in the editor, add a “Logout” hyperLink at the top-right of the screen and add a click event to this hyperLink triggering “logout” action. Your panel XML will look like;

<panel>
  <tableLayout cellSpacing="10">
    <!-- ******************************************** -->
    <!-- Dummy row to adjust column widths -->
    <row height="0">
      <!-- This column has a static 120 px width -->
      <cell width="120"/>
      <!-- This one is dynamic and it will expand to the free space of the row -->
      <cell/>
    </row>
    <row height="20">
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <hyperLink font-color="Blue" font-style="Underlined" text-align="Right" label="Logout">
          <events>
            <click action="logout"/>
          </events>
        </hyperLink>
      </cell>
    </row>
    <row height="30">
      <cell columnSpan="2" hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" font-size="16" label="Change Password"/>
      </cell>
    </row>
    <row height="10"/>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="Old Password:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <passwordField name="oldPassword" tabIndex="10"/>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Full" vAlign="Full">
        <textLabel font-style="Bold" label="New Password:   " text-align="Right"/>
      </cell>
      <cell hAlign="Full" vAlign="Full">
        <passwordField name="newPassword" tabIndex="20"/>
      </cell>
    </row>
    <row height="20">
      <cell/>
      <cell hAlign="Left" vAlign="Full">
        <button label="Submit">
          <events>
            <buttonPress action="setPassword"/>
          </events>
        </button>
      </cell>
    </row>
  </tableLayout>
</panel>

Run the application again and click “Logout” hypeLink. When this hyperLink is clicked all session variables are destroyed and the user is navigated back to login screen.