# inlineSearch: a component for searching codes and descriptions
# requires: wait.nebc
# WARNING: this module does not work if the form is not lambized.
# needed parameters:
# $table:
# the name of the table where the data is stored. is used for calculate some names.
# the name of the table can be simply 'stuff' instead of '_stuff_data'
# $target_field:
# the name of the field in the parent block that stores the wanted id.
# usualy is the mane of the table it 'points'
# if the target field has the form 'table.field', means that that table is multiple table
# the name of the table can be simply 'stuff' instead of '_stuff_data'
# calculated parameters:
# (puf!)
# name def value description
# $target_block * the name of the block where this component is declared
# $target_table ** the name of the table
# $object $table internal anme base of other calculable parameters
# $object_form ${object}.gfd the form that manages the searching object
# $object_select_form ${object}Select.gfd the form that lets us select one of the found items
# $ds_name search_${object}DataSource ...
# (more parameters missing)
# how it works:
##############
# it must be placed in the block where the datum wants to be stored.
# it defines the following things:
# * a datasource that is able to search the id
# given the code and/or name and viceversa.
# * 1 or 2 triggers that realize if there's a search by the criteria where [enter] is hit.
# * a trigger that does the search.
# * 2 or 4 triggers (depending on its a name search or a code/name serach)
# that copies data back and forth. keep reading to realize what I mean.
# * a label if $label is defined. the final text is "$label:"
# (i.e., only adds a colon to the end of $label).
# if the label is defined, the the other widgets appear in the next row.
# * an entry where the id of the found thing is stored.
# its name is given by the (required) $target_field parameter.
# * 2 or 4 entries, a pair for the optional code, one hidden, one shown.
# the shown one is where the user inputs the search criteria and/or
# the search result is shown and/or the actual value is presented.
# the hidden one stores the last search criteria.
# this is needed due to [enter] on the shown entry must do a search only if it was modified,
# and only in the criteria specified by the value of the entry where [enter] is hit;
# if the value wasn't modified, then only jump to the next record.
# also, if the user hits [tab] instead of [enter],
# the value is restrored to the last search criteria (or found value)
# another pair is defined for the name.
# the 'back and forth' mentioned above is meant to implement that behavior.
# * a button that loads the form that manages the kind of stuff being searched.
# the form name is taken from the $object_form parameter.
# * a block that uses the already mentioned datasource.
# this block contains an entry for each search citeria (i.e., name or code and name).
# * a trigger that loads the actual values from the id if it's defined.
# this trigger could be called in the pre-focusin trigger
# of the containing page to show the actual value.
$label=>''
$table
$target_block=>''
$target_field
$object=> ''
$object_form=> ''
$object_select_form=> ''
$ds_name=> ''
$block_name=> ''
# these should be left default unless the ${table}Select.gfd uses some weird names...
# for an example, see product.neb
$id_field=> ''
$id_entry=> ''
$name_entry=> ''
$name_field=> ''
$code_field=> ''
$code_entry=> ''
$code_width=> 10
$use_code=> '1'
$target_table=> ''
sub debug {
printf STDERR @_;
}
# hack to assing default values using other param's values
sub default {
my ($valueRef, $default)= @_;
${$valueRef}= ${$valueRef} eq ''? $default: ${$valueRef};
}
# default (\$target_field, "$object");
# let's see if it's a multiple-table situation
my @data= split /\./, $target_field;
if (scalar @data==2) {
($target_table, $target_field)= @data;
if ($target_table!~ /^_.*_data$/) {
$target_table= "_${target_table}_data";
}
}
default (\$object, $table);
default (\$object_form, "$object.gfd");
default (\$object_select_form, "${object}Select.gfd");
if ($code_field or $code_entry) {
$use_code= 1;
}
if ($table!~ /^_.*_data$/) {
$table= "_${table}_data";
}
default (\$id_field, "_table");
default (\$name_field, "name");
if ($use_code) {
default (\$code_field, "code");
}
default (\$id_entry, "${object}IdEntry");
default (\$name_entry, "${object}NameEntry");
if ($use_code) {
default (\$code_entry, "${object}CodeEntry");
}
default (\$block_name, "search_${object}Block");
default (\$ds_name, "search_${object}DataSource");
my $show_ds= "show_${object}DataSource";
if ($use_code) {
my ($code_fk, $code_fk_desc);
@data= split /\./, $code_field;
if (scalar @data==1) {
$code_fk= "${show_ds}_1._table";
$code_fk_desc= "$code_field";
} else {
my ($table, $field)= @data;
$code_fk= "${show_ds}_1.${table}._table";
$code_fk_desc= "$code_field";
}
}
if ($use_code) {
if str("$target_block\.$code_entry"):
callTrigger ('"idFor_${object}Trigger"')
else:
"$target_block\.hid_$code_entry"= ''
"$target_block\.$code_entry"= ''
"$target_block\.hid_$name_entry"= ''
"$target_block\.$name_entry"= ''
"$target_block\.$id_entry"= ''
}
if str("$target_block\.$name_entry"):
callTrigger ('"idFor_${object}Trigger"')
else:
if ($use_code) {"$target_block\.hid_$code_entry"= ''
"$target_block\.$code_entry"= ''
}"$target_block\.hid_$name_entry"= ''
"$target_block\.$name_entry"= ''
"$target_block\.$id_entry"= ''
callTrigger('startWaitingModeTrigger')
def set_$object (recNo):
if recNo>=0:
$block_name.jumpRecord (recNo)
"$target_block\.$id_entry"= str("$block_name\.$id_entry")
if ($use_code) {"$target_block\.$code_entry"= str("$block_name\.$code_entry")
}"$target_block\.$name_entry"= str("$block_name\.$name_entry")
callTrigger ('codePFI')
callTrigger ('namePFI')
# go fetch!...
$block_name.clear ()
$block_name.initQuery ()
if ($use_code) {
if str("$target_block\.hid_$code_entry")!=str("$target_block\.$code_entry"):
"$block_name\.$code_entry"= str("$target_block\.$code_entry")+'%'
else:
"$block_name\.$code_entry"= ''
}
if str("$target_block\.hid_$name_entry")!=str("$target_block\.$name_entry"):
"$block_name\.$name_entry"= str("$target_block\.$name_entry")+'%'
else:
"$block_name\.$name_entry"= ''
$block_name.processQuery ()
callTrigger('endWaitingModeTrigger')
# are there too much results?
resultCount= $block_name.getRecordCount ()
if resultCount>1:
# do the select-man
runForm ('$object_select_form', {
'data': $block_name,
'callback': set_$object
})
setStatusText('Listo')
elif resultCount==1:
set_$object (0)
setStatusText('Listo')
else:
setStatusText('No se encontraron registros')
if ($use_code) {
# copy our contents to the hidden one
"$target_block\.hid_$code_entry"= str("$target_block\.$code_entry")
"$target_block\.hid_$name_entry"= str("$target_block\.$name_entry")
# copy back
"$target_block\.$code_entry"= str("$target_block\.hid_$code_entry")
"$target_block\.$name_entry"= str("$target_block\.hid_$name_entry")
}
# copy our contents to the hidden one
if ($use_code) {"$target_block\.hid_$code_entry"= str("$target_block\.$code_entry")
}"$target_block\.hid_$name_entry"= str("$target_block\.$name_entry")
# copy back
if ($use_code) {"$target_block\.$code_entry"= str("$target_block\.hid_$code_entry")
}"$target_block\.$name_entry"= str("$target_block\.hid_$name_entry")
if ($label) {}if ($use_code) {}if ($use_code) {}
if str(qq($target_block.$id_entry))!='':
qq($block_name).clear ()
qq($block_name).initQuery ()
qq($block_name.$id_entry)= str(qq($target_block.$id_entry))
qq($block_name).processQuery ()
# copy the database contents in the fields
if ($use_code) {qq($target_block.$code_entry)= str(qq($block_name.$code_entry))
}qq($target_block.$name_entry)= str(qq($block_name.$name_entry))