Step 4 - Adding simple User Input with QueryStrings

The demo from the previous step is cool because it take very little code. But it's also very limited because it's all static. We're running a static SQL statement that's returning all records. It would be nice to actually be able to specify a 'parameter' to search for, right.

Using parameters via the QueryString

Ok, let's change the code above as follows to allow us to specify a 'parameter' via the QueryString.

*** Retrieve the customer via Querystring parameter from the URL
lcCompany = Request.QueryString("Company")

*** Run a query with company as parameter
SELECT company, LastName, firstName, Phone, Entered ;
   FROM Customers ;
   WHERE UPPER(Company) = UPPER(lcCompany) ;
   ORDER BY Company ;
   INTO CURSOR TQuery      

Now try the following URLs in your browser:

http://localhost/WebDemo/CustomerList.wp?Company=A

You should now get a list back that includes only those companies that start with a 'A'. Parameters on the QueryString are passed in UrlEncoded format which is in key=value&key2=value2 format.

The QueryString is useful for 'parameterized' queries - you will utilize query string parameters primarily for embedded links that get generated by code to link to other pages. Typically you'll use IDs for linking but it's also common to use directives and simple values as I've done above.

Cleaning up the code

While we've added this query functionality let's also clean up the request a little to include a record count, and show an error message when no records are returned.

*** Retrieve the customer via Querystring parameter from the URL
lcCompany = Request.QueryString("Company")

*** Run a query with company as parameter
SELECT company, LastName, firstName, Phone, Entered ;
   FROM Customers ;
   WHERE UPPER(Company) = UPPER(lcCompany) ;
   ORDER BY Company ;
   INTO CURSOR TQuery      

*** Capture the record count
lnRecCount = _Tally

Response.Write(this.PageHeaderTemplate("Customer List"))

*** Display the dynamic record count as part of the header
TEXT TO lcHtml TEXTMERGE NOSHOW
<h3>
   <i class='fa fa-list'></i> Customer List
   <span class='badge'><<TRANSFORM(lnRecCount)>></span>
</h3>   
<hr />
ENDTEXT
Response.Write(lcHtml)

IF lnRecCount > 0
	lcHtml = HtmlDataGrid("TQuery")
ELSE
	lcHtml = "<div class='alert alert-warning'><i class='fa fa-warning'></i> No records found.</div>"	
ENDIF
Response.Write(lcHtml)   

Posting the data

For user interaction query strings are not really ideal. After all you wouldn't want to have your visitors to the Web Site key in their search parameters on querystring, right? Instead you probably want to present users with fields to input the data into. Although you can get data from HTML fields returned on the query string, in general data from HTML Forms are POSTed to the Web Server. POST data doesn't go on the querystring, but is instead sent to the server in a special HTTP buffer in an encoded format that the browser generates for you.

Using HTML forms then is a multi-step process:

  • Setting up the HTML form
  • Having the user fill out the form and submit it
  • Capturing the Form data and do something with it

Depending on the situation, this process can be handled by multiple pages or a single one. In the simple example, of providing a single Company Search box we're going to use a single Web Connection request method to both generate the form and also retrieve the value.

Let's modify the CustomerList method one more time by adding the following to the top:

FUNCTION CustomerList()
LOCAL lnRecCount, lcHtml, lcCompany

*** Retrieve the customer via Querystring OR Form var
lcCompany = Request.QueryString("Company")
IF EMPTY(lcCompany)
   lcCompany = Request.Form("txtCompany")
ENDIF

*** Run a query with company as parameter
SELECT company, FirstName, LastName, Phone, Entered ;
   FROM Customers ;
   WHERE UPPER(Company) = UPPER(lcCompany) ;
   ORDER BY Company ;
   INTO CURSOR TQuery      

lnRecCount = _Tally

Response.Write(this.PageHeaderTemplate("Customer List"))

TEXT TO lcHtml TEXTMERGE NOSHOW
<h3>
   <i class='fa fa-list'></i> Customer List
   <span class='badge'><<TRANSFORM(lnRecCount)>></span>
</h3>   
<hr />

<!-- THIS CODE SHOWS THE INPUT FORM -->
<form action="customerlist.wp" method="POST">

<div class="input-group" style='margin: 20px 0;'>
  <span class="input-group-addon">Company:</span>
  <input type="text" name="txtCompany" 
         class="form-control" 
         style="width: 200px;" 
         value="<<lcCompany>>"
         />&nbsp;
  
  <button type="submit" name="btnSearch" class="btn btn-default" type="button">
     Search...
  </button>	
</div>

</form>
ENDTEXT
Response.Write(lcHtml)

IF lnRecCount > 0
	lcHtml = HtmlDataGrid("TQUery")
ELSE
	lcHtml = "<div class='alert alert-warning'><i class='fa fa-warning'></i> No records found.</div>"	
ENDIF
Response.Write(lcHtml)

Response.Write(this.PageFooterTemplate())

RETURN

Here's what this form looks like now:

The key changes are the the code that checks for the txtCompany form variable if the query string value is empty and the block of HTML around the <form> tag. The key to the HTML block is the <form> tag itself that posts the input back to the same page. The other key piece is the <input> tag which holds the actual text input field and value. The value is captured from this input and the value attribute is set to the value the user entered into the search box, so the value is reflected back to the user.

Setting the value is important: HTML doesn't automatically retain the value you set on the last request and when the page posts back you have to tell it what value it held previously by reassigning it.

value="<<lcCompany>>"

n this case I'm writing the value back out with the TextMerge expression.


Step 5 - Drilling down into the customer list


© West Wind Technologies, 1996-2017 • Updated: 02/25/16
Comment or report problem with topic