The select model generates a php class that returns values to be used to build an HTML select control or a datalist for a text control. If you wish to generate a select control based on the contents of a SQL table, please use the help/model/select_db_column_values/overview..select_db_column_values model not defined.

Defining Select Values

Select and datalist controls allow the user to select from a list of values. The values shown to the user need not be the same as the values that will be assigned to the control value internally when a value is selected. In this example, we will will define a select control that allows the user to select a color:

Sample Color Selector Values

Let's assume this select definition is named color. Using the form model we can define a select field on-the-fly using the following field definition:

:tarp_color,type:select,*select:color,required:true

Notice that the *select property of the field references the color selector. In this example we also set the required property. Since there is no internal value associated with the "Please Select" value, the browser will force the user to select one of the color values.

This field would render the following drop down values:

Simple color selector

Similarly, we could use this same list to add proposed values for a text field as in:

:favorite_color,type:text,list:color

Unlike a select field, where the user must choose from the list of available values, the list attribute is used when the list is intended to provide suggestions. The user could choose one of the suggested items or enter something that is not on the list.

Of course these fields don't have to be defined on-the-fly on the form, they could also be defined using the html_field model or the html_field_type model.

Defining Group Headings

The select control allows values to be grouped. This is a good idea when dealing with a lot of values that can be logically grouped. Here we use groups to divide the colors into dark and light classifications. 

Select definition which includes group headings

Notice that the group heading should be placed to the left of the first item within the group. In this example we have introduced a new item which will show as Transparent to the user but, if this is selected, it will be posted as Clear. Since transparent is not a color, we don't want this within the other groups and since there is only one "colorless" item we don't want to introduce a new Group Heading so we can just enter a slash character which is used to terminate the previous group without introducing a new group. This select will be rendered as follows:

Selector with group headings

Dynamic Select Fields

Sometimes the list of values to be added to the select or datalist is not static. If this list is available in an sql database you may be able to use the model select_db_column_values to build the list automatically. Otherwise, it is possible to write some PHP code to populate the list of selection values. Often the php_array_data model is used to build lists and tables to be used for various purposes within your application. We can reuse these lists to build select fields rather than redundantly entering the same values using the select models. For example, one of the php_array_data specifications in system is called country_codes. Here we show a snippet of this definition:

Supplied country codes

We can use this same list to build the country selection field by using the Dynamic Options of the Select model.

Dynamic options can also be used to supplement Static Options. Here we use the Static list to define a singe item.

Static Select with One Item

In this case we want the static option to be translated into the user's spoken language so we have used the notation :class->variable to refer to a row in the translation class named general.

When including dynamic options, you must define a custom code row that includes the following settings:

Required Generate Row

Here is the code used to implement the generate method:

Dynamic list of countries

Notice that the function name and outer function brackets are not entered since we only supply the body of the generate function.

The dynamic values will supplement any static values entered above. Here we show the code again in case you want to copy it. Notice in this case we only need the key values (shown under the Row Index header) so we use the get_row_keys method of php_array_data_base. You can also pull this sample code into the select editor by using the example command.

$countries = $this->site->create_object('country_codes','',false,'array_data');
$all = $countries->get_row_keys();
foreach ($all as $country) {
  $this->add_option($country);
}

Defining Dynamic Groups

In this next example, we will show how you can also build dynamic code which groups the selection fields. Suppose we have used the php_array_data model to compile a list of information about tarp material as shown:

php Array Data Values

Again we could repeat the material type values manually as static select values but that would require these two sets of values to be kept in sync. A better option is to write some code to pull the select values from this php_array_data source. Here we see an example of the required code:

Example of building dynamic select code

Notice the following:

  1. We define a property named application. Since this property includes a set method, its value can be passed to the select class to influence the values that are returned,
  2. Use $this->add_optgroup('Group Name') if you want to introduce and option group.
  3. Use $this->add_option('internal value','external value') to add new options. The external value is optional and will default to the internal value if not supplied.

Here we show a sample html_field definition (also named material) which uses the material select field defined above.

html_field definition for a field that uses the material select class

Next we show a portion of a form that uses the material field defined above.

Form containing material field

Notice that we are passing a dynamic parameter *application to the select class. This tells the select class to only generate the material options that are suitable as golf impact screens.

Here is the same code from above which can be copied.

$material = $this->site->create_object('tarp_material','',false,'array_data');
$all_material = $material->get_data();
foreach ($all_material as $key => $info) {
  if (isset($this->application)) {
    if (empty($info[$this->application])) {
      continue; // Wrong application
    }
  }
  $group[$info['type']][$key] = $info['select'];
}
$groups = sizeof($group);
if (isset($group['solid'])) {
  if ($groups > 1) {
  	$this->add_optgroup('Solid Vinyl (Waterproof)');
  }
  foreach ($group['solid'] as $key => $desc) {
      $this->add_option($key,$desc);
  }
}
if (isset($group['mesh'])) {
    if ($groups > 1) {
      $this->add_optgroup('Mesh/Screen Material');
    }
	foreach ($group['mesh'] as $key => $desc) {
		$this->add_option($key,$desc);
	}
}
if (isset($group['other'])) {
  if ($groups > 1) {
  	$this->add_optgroup('Other');
  }
  foreach ($group['other'] as $key => $desc) {
      $this->add_option($key,$desc);
  }
}

Other Properties

Translation Id

This is used to support multilingual selection values supplied by a translation model generated class. If a translation class is supplied and if External Column is empty, the Internal Column value (select option) will be used to lookup the text to be shown for each option (based on the user's current language). If External Value or Group Heading is set, and this starts with the internationalization character (: by default) this will be substituted for the translation. This string can also contain an alternate translation class as in :some_class->some_field.

Cache Result

If the list of select values is created dynamically and particularly when significant resources are needed to generate the list and when the list does not tend to change frequently you should consider caching the select list. When this option is chosen, after building the select list for the first time, the resulting values will be cached in a text file. The next time the list is needed it can be built very quickly from the text file rather than using the resource intensive method used to create the list originally. 

When caching results, you are responsible for deleting the cache whenever the original data source is updated. This will trigger the cache to be recreated with the latest values. 

The select_field_base class provides a method for deleting the cache as shown here:

require_once(CLASS_PATH.'select_field_base.php');
select_field_base::remove_cache_item($this->site,'name_of_select','en');

The second parameter is the name of the select whose cache is to be deleted. The last parameter is the language for which the cache was saved. If you want to delete all languages you can omit this parameter or pass '*'.

Before Class

The code entered here will be placed above the generated class definition. This can be used to require components or to set a namespace.

Another Dynamic Parameter Example

When using code to build the list of select values, any number of parameters can be defined to configure the set of select values to be generated.

Let's suppose you want to create a drop down for a credit card expiry year. Generally, this year should not be less than the current year and cards usually expire within five years of being issued. One way to build such a dropdown dynamically would be to use $functions as shown here:

Select using dollar function

What if you wanted to make this select field more general? For example if you wanted to use it to select the year that an employee was hired you might want it to go back 40 years and continue to the current year. To select the year that a senior employee plans to retire this might go from the current year until a year 10 years from now. To make a dynamic select like this you need to add parameters to the select and pass these when the select is configured. For example, suppose we want to render these selects using the code:

:year_of_hire,type:select,*select:years,*years-back:40,*years-forward:0
:year_to_retire,type:select,*select:years,*years-back:0,*years-forward:10

Notice that the select accepts the special parameters *year-back and *years-forward. We need to define these parameters as properties within the select field definition. Furthermore, these properties must define a set method (as part of the property definition). We have used coerce in the Generate Set Function column to automatically convert passed parameters to integers. In this example, we are supplementing the default set methods by adding a check that prevents the supplied values from going backward or forward more than 1000 years.

You will then make use of these values when setting the select option values to be passed to the add_option method as shown here:

Dynamic year range select

Sample select definition
🡇
Sample select rendered