In this step, you will create the user interface for collecting requests. Users specify the desired reagent, a desired quantity, and some user contact information, submitting requests with a form like the following:

Folders and Permissions

First create a separate folder where your target users are granted "insert" permissions. Creating a separate folder allows you to grant these expanded permissions to all site users only for the scope needed and not to more sensitive information. Further, insertion of data into the lists can then be carefully controlled and granted only through admin-designed forms.

  • Log in to your server (with Admin or Developer permissions) and navigate to the project you want to work in.
  • Create a new folder to work in:
    • Go to Admin > Folder > Management > click Create Subfolder.
    • Name it "Reagent Request Tutorial" (confirm it is of type Collaboration).
    • Click Next.
    • On the User/Permissions page, click Finish and Configure Permissions.
  • Uncheck Inherit permissions from parent.
  • Next to Submitter, select All Site Users.
  • Click Save and Finish.

Import Lists

The reagent request application will use two lists. One records the available reagents, the other records the incoming requests. Below you import the lists in one pass, using a "list archive". (We've pre-populated these lists to simulate a system in actual use.)

  • Download this list archive: ReagentTutorial.lists.zip
  • Go to Admin > Manage Lists.
  • Click Import List Archive.
  • Click Browse or Choose File and select the list archive you just downloaded.
  • Click Import List Archive.

Create the Request Page

Requests submitted via this page will be inserted into the Reagent Requests list.

  • Click the Start Page tab to return to the main folder page.
  • In the Wiki web part, click Create a new wiki page.
  • Give it the name "reagentRequest" and the title "Reagent Request Form".
  • Click the Source tab.
  • Scroll down to the Code section of this page.
  • Copy and paste the HTML/JavaScript code block into the Source tab.
  • Click Save and Close.

The page reagentRequest now displays the submission form.

See a live example.

Notes on the source code

The following example code uses LABKEY.Query.selectRows and LABKEY.Query.insertRows to handle traffic with the server. For example code that uses Ext components, see LABKEY.ext.Store.

To view the source code, click the pencil icon, or view similar source in the interactive example. Search for the items in orange text to observe any or all of the following:

  • Initialization. The init() function, triggered by Ext.onReady, pre-populates the web form with several pieces of information about the user.
  • User Info. User information is provided by LABKEY.Security.currentUser API. Note that the user is allowed to edit some of the user information obtained through this API (their email address and name), but not their ID.
  • Dropdown. The dropdown options are extracted from the Reagent list. The LABKEY.Query.selectRows API is used to populate the dropdown with the contents of the Reagents list.
  • Data Submission. To insert requests into the Reagent Requests list, we use LABKEY.Query.insertRows. The form is validated before being submitted.
  • Asynchronous APIs. The success in LABKEY.Query.insertRows is used to move the user on to the next page only after all data has been submitted. The success function executes only after rows have been successfully inserted, which helps you deal with the asynchronous processing of HTTP requests.
  • Default onFailure function. In most cases, it is not necessary to explicitly include an onFailure function for APIs such as LABKEY.Query.insertRows. A default failure function is provided automatically; create one yourself if you wish a particular mode of failure other than the simple, default notification message.

Confirmation page dependency. Note that this source code requires that a page named "confirmation" exists before you can make a request. Continue to the next step: Step 2: Confirmation Page to create this page.

Code

<div align="right" style="float: right;">
<input value='View Source' type='button' onclick='gotoSource()'><br/>
<input value='Edit Source' type='button' onclick='editSource()'>
</div>

<form name="ReagentReqForm">
<table cellspacing="0" cellpadding="5" border="0">
<tr>
<td colspan="2">Please use the form below to order a reagent.
All starred fields are required.</td>
</tr>
<tr>
<td colspan="2"><div id="errorTxt" style="display:none;color:red"></div></td>
</tr>
<tr>
<td valign="top" width="100"><strong>Name:*</strong></td>
<td valign="top"><input type="text" name="DisplayName" size="30"></td>
</tr>
<tr>
<td valign="top" width="100"><strong>E-mail:*</strong></td>
<td valign="top"><input type="text" name="Email" size="30"></td>
</tr>
<tr>
<td valign="top" width="100"><strong>UserID:*</strong></td>
<td valign="top"><input type="text" name="UserID" readonly="readonly" size="30"></td>
</tr>
<tr>
<td valign="top" width="100"><strong>Reagent:*</strong></td>
<td valign="top">
<div>
<select id="Reagent" name="Reagent">
<option>Loading...</option>
</select>
</div>
</td>
</tr>
<tr>
<td valign="top" width="100"><strong>Quantity:*</strong></td>
<td valign="top"><select id="Quantity" name="Quantity">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select></td>
</tr>

<tr>
<td valign="top" width="100"><strong>Comments:</strong></td>
<td valign="top"><textarea cols="23" rows="5" name="Comments"></textarea></td>
</tr>
<tr>
<td valign="top" colspan="2">
<div align="center">
<input value='Submit' type='button' onclick='submitRequest()'>
</td>
</tr>
</table>
</form>
<script type="text/javascript">

// Ensure that page dependencies are loaded
LABKEY.requiresExt3ClientAPI(true, function() {
Ext.onReady(init);
});

// Navigation functions. Demonstrates simple uses for LABKEY.ActionURL.
function gotoSource() {
window.location = LABKEY.ActionURL.buildURL("wiki", "source", LABKEY.ActionURL.getContainer(), {name: 'reagentRequest'});
}

function editSource() {
window.location = LABKEY.ActionURL.buildURL("wiki", "edit", LABKEY.ActionURL.getContainer(), {name: 'reagentRequest'});
}

// Initialize the form by populating the Reagent drop-down list and
// entering data associated with the current user.
function init() {
LABKEY.Query.selectRows({
schemaName: 'lists',
queryName: 'Reagents',
success: populateReagents
});

document.getElementById("Reagent").selectedIndex = 0;

// Set the form values
var reagentForm = document.getElementsByName("ReagentReqForm")[0];
reagentForm.DisplayName.value = LABKEY.Security.currentUser.displayName;
reagentForm.Email.value = LABKEY.Security.currentUser.email;
reagentForm.UserID.value = LABKEY.Security.currentUser.id;
}

// Populate the Reagent drop-down menu with the results of
// the call to LABKEY.Query.selectRows.
function populateReagents(data) {
var el = document.getElementById("Reagent");
el.options[0].text = "<Select Reagent>";
for (var i = 0; i < data.rows.length; i++) {
var opt = document.createElement("option");
opt.text = data.rows[i].Reagent;
opt.value = data.rows[i].Reagent;
el.options[el.options.length] = opt;
}
}

// Enter form data into the reagent request list after validating data
// and determining the current date.
function submitRequest() {
// Make sure the form contains valid data
if (!checkForm()) {
return;
}

// Insert form data into the list.
LABKEY.Query.insertRows({
schemaName: 'lists',
queryName: 'Reagent Requests',
rowDataArray: [{
"Name": document.ReagentReqForm.DisplayName.value,
"Email": document.ReagentReqForm.Email.value,
"UserID": document.ReagentReqForm.UserID.value,
"Reagent": document.ReagentReqForm.Reagent.value,
"Quantity": parseInt(document.ReagentReqForm.Quantity.value),
"Date": new Date(),
"Comments": document.ReagentReqForm.Comments.value,
"Fulfilled": 'false'
}],
success: function(data) {
// The set of URL parameters.
var params = {
"name": 'confirmation', // The destination wiki page. The name of this parameter is not arbitrary.
"userid": LABKEY.Security.currentUser.id // The name of this parameter is arbitrary.
};

// This changes the page after building the URL. Note that the wiki page destination name is set in params.
var wikiURL = LABKEY.ActionURL.buildURL("wiki", "page", LABKEY.ActionURL.getContainer(), params);
window.location = wikiURL;
}
});
}

// Check to make sure that the form contains valid data. If not,
// display an error message above the form listing the fields that need to be populated.
function checkForm() {
var result = true;
var ob = document.ReagentReqForm.DisplayName;
var err = document.getElementById("errorTxt");
err.innerHTML = '';
if (ob.value == '') {
err.innerHTML += "Name is required.";
result = false;
}
ob = document.ReagentReqForm.Email;
if (ob.value == '') {
if(err.innerHTML != '')
err.innerHTML += "<br>";
err.innerHTML += "Email is required.";
result = false;
}
ob = document.ReagentReqForm.Reagent;
if (ob.value == '') {
if(err.innerHTML != '<Select Reagent>')
err.innerHTML += "<br>";
err.innerHTML += "Reagent is required.";
result = false;
}
if(!result)
document.getElementById("errorTxt").style.display = "block";
return result;
}

init();

</script>

Start Over | Next Step


previousnext
 
expand allcollapse all