map_get_inputs()

Purpose

Control function for data entry in maps

Old name

#define get_inputs map_get_inputs

Syntax

int map_get_inputs(mapnr,start_field, data_inner,flags)

Parameters

int mapnr

Number of map being used

 

int start_field

Initial field to begin data entry

 

void (*data_inner)(int, int *)

User-supplied data entry function

 

int flags

Specifies display attributes

 

The parameter start_field indicates where the field entry should start.

The data_inner function is called each time data is input. Here is a typical example:

void data_inner(int m,int* f)
{
   int current_field_nr;
   switch (curr_field_nr = *f)
   {
      case 1:
        if (inpm_c(&customer.acc_nr))
          break;
         /* do any validation if fails put *f = current_field_nr */
        break;
      case 2:
        if (inpm_c(&customer.short_name))
          break; /* do any validation */
      case 3:
        ... 
      default:
        inpm_omit();
        break;
   }
}

The parameter m to the function data_inner is the same as the mapnr parameter passed to the function map_get_inputs(). The parameter f to data_inner points to the current map field for data entry. The parameter flags can be a combination of the following values:

 

Value

Meaning

 

NO_DISP

Indicates that the display map is already on the screen

 

ABORT_FUNC_KEYS

If this flag is set and the inner function returns a value greater than 0 in abort_code, map_get_inputs() returns without completing all the fields. It is intended for use with activating function keys. For example, if a program has a table describing the current state of a number of dialogs, each with a different activating function key. Pressing a function key starts or resumes a dialog which may be returned to in the same state in which it was left

 

GI_GLOBALS

When this flag is specified, the following variables are managed automatically:

  • jump Set to FALSE on entry to and exit from map_get_inputs()

  • range Set to the starting field number on entry to map_get_inputs() and to 0 on exit

  • clearfirst Set to 2 on entry to map_get_inputs() if PREDISPLAY is not specified and 0 otherwise and to 0 on exit

 

PREDISPLAY

All the fields are initially displayed before stopping for data entry. The global variable realpass is used to distinguish between a predisplay pass and a normal pass.

For a predisplay pass, the global variable jump is set to TRUE and the global variable realpass is set to FALSE.

inpm_x() functions all return RIGHT when realpass is FALSE so you will normally break before doing any validation. If you go into some validation code with realpass FALSE, and the validation fails and you reset the field number your program will hang.

 

GI_NO_ESC_CLEAR

Prevents the map from being cleared if the user escapes from rather than completing the dialog. Without this flag the map will always be cleared if the user escapes from the dialog, regardless of the other flags below.

 

RETAIN

The map is set to RETAIN on exit and not cleared

 

CLEAR

Clears the map on exit using map_change(,CLEAR)

 

HIDDEN

The map is hidden with map_change(,HIDDEN) when the dialog is completed normally. See map_change()

 

DEAD

The map is set to DEAD with map_change(,DEAD) when the dialog is completed normally. See map_change()

 

ASK_CONFIRM

If necessary puts up a confirmation menu after the user has entered the data, using sys_upd_confirm() (to which you should refer for an explanation of "if necessary"). You can replace this routine if desired. Depending on the value returned by sys_upd_confirm() map_getinputs() may return 0 for success, ESCAPE to cancel the dialog, or make another pass through the input fields.

Description

The map_get_inputs() function controls how the input is entered from several fields in a map.

This function is the preferred function for data entry and should be used with the inpm_x() functions. It simplifies considerably the development of data entry functions and reduces the code size of programs. Many of the checks that had to be done previously are automatically taken care of.

It is similar to the pick_record() function in that the user supplies a callback function which is called as necessary , in this case to actually get input from the user.

Note you do not need to call map_use() as this is automatically done for you. However if you make a nested call to map_get_inputs() from a data_inner() calllback function, you should call map_use() on return to correctly set the global variables input_map and input_field.

Return values

Returns ESCAPE if the user escapes from one of the data entry functions, or 0 when the dialog is completed.

See also

inpm_x(), inpm_omit(), map_predisplay()

Examples

The example below is a very basic one for the SALESORD database. A much better example, which is fully annotated, can be found at An Example Dialog in DP4

/*
#db salesord
#c
#tables customer, employee;
#end
*/

#include "dp4.h"
#include "map_get_.h"
/* generate this file by running LIBMAKE */
/* prototypes */
void get_new_cust(void);
void init_new_cust(void);
void cust_inner(int,int*);

void process()
{
   map_datamap(1);
   trm_read_user();
   get_new_cust();
}

void get_new_cust()
{
   map_datamap(2); /* initialise the new fields */
   init_new_cust();
   if (!map_get_inputs(2,1,cust_inner,
             DEFAULT|ASK_CONFIRM))
     rec_post_commit(&customer.l);
}

void init_new_cust()
{
 /* initialise fields for a new customer */

 /* get last customer and add 1 */
 rec_fetch_main(LAST,&customer.l);
 customer.customer_number++;
 customer.credit_customer = TRUE;
 customer.credit_limit = 1000.0;
 WIPE(customer.name);
 WIPE(customer.address);
 WIPE(customer.region_code);
}

void cust_inner(int m,int *f)
{
  int field_nr = *f;
  switch (field_nr)
  {
    case 1:
      inpm_c(customer.name);
      break;
    case 2: /* show it only */
      show_n(m,2,customer.customer_number);
      inpm_omit();
      break;
    case 3:
      inpm_c(customer.address[0]);
      break;
    case 4:
      inpm_y(&customer.credit_customer);
      break;
    case 5:
      if (customer.credit_customer)
        inpm_n(&customer.credit_limit);
      else
      {
        field_blank(m,field_nr);
        inpm_omit();
      }
      break;
     case 6:
       inpm_u(customer.region_code);
       /* check this is a valid region */
       break;
     default:
       inpm_omit();
       break;
  }
}