| << Previous | Suneido > Contents > Cookbook | Next >> |
by Claudio Mascioni
Category: User Interface
Problem
You have to add controls as ChooseListControl, RadioButtonsControl, ButtonControl, to an AccessControl to increase choice of operator. A TimeStamp autogenerated Key.
Ingredients
- ChooseListControl to select a table to open, and to select the index order
IMPORTANT: In this example, the tables must have all the same structure because changing the table is not handled by AccessControl
- RadioButtonsControl to select an ascending or descendig sort order
Recipe
"layout()" is used to pass the parameter "query" to the AccessControl.
Controller
{
Title: "find item"
New()
{
super(.layout())
.sortIndex = 'NOINDEX'
.sortOrder = ''
}
layout()
{
In the variable "query" is stored the table name to open the first time when opening the Access window. The first time the table does not have a sort order.
query = .FirstTime()
return Object('RecordControl'
Object('Vert'
Object('Horz'
Object('Static' 'selected table: ')
Object('ChooseList' name: 'Chlt', listField: 'cm_tables', selectFirst:)
Object('Skip' 5)
Object('Static' 'ordered by: ')
Object('ChooseList' name: 'Chls', listField: 'cm_index', selectFirst:)
Object('Skip' 5)
Object('Static' 'sort order: ')
Object('RadioButtons' "ascending", "descending", name: 'RB1', horz:)
Object('Skip' 20)
Object('Button' 'press', command:'Pressed')
)
Object('Access' query title: '')
)
)
}
FirstTime()
{
.SetCurrTable('tables')
return Suneido.cm_temp_currentTable
}
With Record_NewValue(field,value) we trap when is manually selected a table name, an index, or a sort order from a Control. This code filter that only changed fields with name 'Chlt', 'Chls' and 'RB1' can use the routine. In a program that does not use RecordControl, this action is trapped from NewValue(value,source). Using Record_NewValue(source,value) "source" is RecordControl().
Record_NewValue(field,value)
{
if ((field isnt 'Chlt') and (field isnt 'Chls') and (field isnt 'RB1'))
return
// check if .Data is not initialized the first time
try
if (.Data is false)
return
catch
return
.SetCurrTable(.Data.GetField('Chlt'))
.sortIndex = .Data.GetField('Chls').Replace('/' ',')
if (field is 'RB1')
{
if (value is 'ascending')
.sortOrder = ''
else
.sortOrder = 'reverse '
}
.qry = Suneido.cm_temp_currentTable
if (.sortIndex isnt 'NOINDEX')
.qry $= ' sort ' $ .sortOrder $ .sortIndex
.Data.Vert.Access.ChangeQuery(.qry)
}
The Suneido global object is used to store the current table value because this value will be used from Rule_cm_index to return a list of available index for the selected table.
SetCurrTable(tablename)
{
Suneido.cm_temp_currentTable = tablename
}
To trap the Button "press" action. Used only for an example.
On_Pressed()
{
Alert('Do something', 'Do something', flags: MB.ICONINFORMATION)
}
To trap the close window action of the operator and give him an alert:
Ok_to_CloseWindow?()
{
if (not OkCancel("sure to exit?"))
return false
else
return true // destroy the window
}
}
To trap the close window action to delete "cm_temp_currentTable" from the Suneido global object before exiting the program:
Destroy()
{
Suneido.Delete('cm_temp_currentTable')
super.Destroy()
}
This "Rule" return a list of tables. This list is used to populate a ChooseListControl to can select a table to open. This list tables must have all the same structure(and different data) In this example it return only the Suneido table "tables".
Rule_cm_tables
function ()
{
return "tables"
// example return "table_x, table_y, table_z" all with the same structure
}
This "Rule" return a list of all keys and indexes that have the selected table. This list is used to populate a ChooseListControl to can select and index to order the records displayed in the AccessControl window. The Replace(',' '/') is used in case of index composed with more than one field. The "NOINDEX" indicate that there is not a sort order.
Rule_cm_index
function ()
{
result = "NOINDEX"
query = "tables where tablename = '" $ Suneido.cm_temp_currentTable $
"' join indexes"
QueryApply(query)
{ |x|
idx = x.columns.Replace(',' '/')
result $= ', ' $ idx
}
return result
}
Notes:
To use a TimeStamp autogenerated to set the Key inserting a new record.
For example, we suppose that the name of the field Key to autogenerate is "id_xyz".
We need to define the key Field and an associated Rule. They must have the same name with the difference that begin with "Field_" and "Rule_" prefix.
Field_id_xyz
Field_string
{
Prompt: 'record ID'
Control: (Field, width: 20)
Format: (Text, width: 20)
}
Rule_id_xyz
function()
{
return Timestamp()
}
When inserting the new record, automatically the key field "id_xyz" is set to the value returned from the Rule_id_xyz function.
If you want that the operator does not modify the key value, you have to change, in the layout() part, this code.
Object('Access' query title: '')
with this:
Object('Access' query title: '', protectField: 'protectRule')
and add this Rule:
Rule_protectRule
function()
{
return #(cm_id_xyz:, allowDelete:)
}
You can use whatever rule name you want; Rule_protectRule is an example. If you want that the operator does not delete records, you have to simply remove the word allowDelete: from the Rule_protectRule.
| << Previous | Suneido > Contents > Cookbook | Next >> |