Gyroscope / Auto-complete Utilities
Gyroscope offers a convenient, standard interface for context-sensitive
lookups.
For example, in a form that books house viewing appointments,
there's a field for entering the property address.
<input id="property" onfocus="lookup_property(this);"
onkeyup="_lookup_property(this);">
Then in JavaScript:
_lookup_property=function(d){
if (d.timer) clearTimeout(d.timer);
d.timer=setTimeout(function(){
lookup_property(d);
},100);
}
The above code should look familiar. When we were building inline lookup
for the property list we used the same timeout flag to throttle requests.
Now the lookup function itself:
lookup_property=function(d){
listlookup(d, 'Property Search',
'lk_pr&key='+encodeHTML(d.value));
}
The function listlookup is defined in autocomplete.js. It sends the following
request to the server:
...?cmd=lk_pr&key=...
We can handle the request by intercepting the lk_pr message:
case 'lk_pr':
include 'icl/lookupproperty.inc.php';
lookupproperty();
break;
Then in
icl/lookupproperty.inc.php:
<?php
function lookupproperty(){
$key=GETSTR('key');
global $db;
$query="select * from properties
where addr like '%$key%' order by addr";
$rs=sql_query($query,$db);
?>
<div class="section">
<?
while ($myrow=sql_fetch_array($rs)){
$prid=$myrow['prid'];
$addr=$myrow['addr'];
?>
<div style="listitem">
<a onclick="picklookup('<?echo $addr?>',
<?echo $prid;?>);"><?echo $addr;?></a>
</div>
<?
}//while
?>
</div>
<?
}
The picklookup function is also defined in autocomplete.js. The function
works with listlookup and populates the auto-complete-enabled input field
with the first parameter. In addition, it attaches the record ID to the input
field.
Imagine we click on the lookup result for Property #5, "123 Test St.". The
input field now shows "123 Test St.", and we can use its ID directly:
...
var prid=gid('property').value2;
if (!prid){
alert('Please pick a property from the list!');
return;
}
...
Identity Resolution
In the above code example, the identity of the lookup is enforced.
We perform the search based on the address of a property. It is the ID of the property that we're submitting to the form handler.
It is possible that the user alters the search string without clicking on a new search result. The form submission will use the previously looked-up ID; and this could be confusing.
Starting v3.8.4, ID'ed lookups can have a visual cue as well as protection of the input field:
The identity locking feature can be invoked by adding a "val2" container:
<input id="test" onfocus=... >
<span id="test_val2"></span>
The new
picklookup function and its variants will automatically lock the input field and display the unlock button.
The lookup field can be
pre-populated and
pre-locked:
<input id="test" value="some_display_value" disabled onfocus=... >
<span id="test_val2"> <?cancelpickup('test');?></span>
Inline Lookup
Autocomplete in Gyroscope is typically displayed on the left panel. Starting 3.8.4, the look up can be displayed inline:
The inline lookup is invoked similar to identity locking. Instead of manually create the containers, use this helper function:
<input id="test" onfocus=... >
<? makelookup('test'); ?>
The
makelookup function is defined in myservices.php. It takes a second optional parameter
$fullscale.
When this parameter is set to true, the lookup view will have no clipping. This is useful for displaying calendars inline.
By default, inline lookup is only triggered in a mobile device when viewing in portrait mode. The left lookup panel is used
to better utilise the screen space.
Although not recommended, it is possible to force an inline autocomplete even in a desktop or landscape view.
The
listlookup function in
autocomplete.js takes a new parameter that explicitly sets the "mini" flag.
A hardcoded "mini" has to be forwarded by all subsequent function calls. Otherwise the lookup will show on the left panel:
<input id="startdate"
onfocus="pickdate(this,null,1);"
onkeyup="_pickdate(this,1);" >
<? makelookup('startdate',1); ?>
Using the Date, Time and Date/Time Pickers
Starting v5.6, the function signature for the date picker has changed to make the code more maintainable.
function pickdate(d, opts, def){...}
The previous mini lookup example is written as the following:
<input id="startdate"
onfocus="pickdate(this,{mini:1});"
onkeyup="_pickdate(this,{mini:1});" >
<? makelookup('startdate',1); ?>
The
pickdatetime function works the same way, with added options to specify the start and end hours in the time selector:
<input id="startdatetime"
onfocus="pickdatetime(this,{start:9,end:17});"
onkeyup="_pickdatetime(this,{start:9,end:17});" >
<? makelookup('startdatetime',1); ?>
Note the start and end times are in 24-hour format.
The
picktime function skips the calendar and displays the time line directly. There is no
_picktime function for the
onkeyup event.
Although the three lookup functions are invoked identically, their input values require different handling.
pickdate populates the input field with a yyyy-mm-dd string, which is validated by the
valdate function and converted to a UNIX timestamp by using the
date2stamp function.
pickdatetime and
picktime populates the "value2" attribute of the input field with a UNIX timestamp. The visible input value is for display only.
It is up to the server side logic to extract the hour and minute information from
picktime. The recommended storage format is 24-hour stamp. For example, 5:45pm is coded as 1745.