Franklin Lee wrote:
> Subject: [Arsperl-users] How to get enumerated value mapping for a field (non 
> OO)
>
> For a given field of an enumerated data type, I want to create a mapping
> from the number to the text label.
>
> I see there is a method getEnumValues() that can be used with an ARS
> object, but I would prefer to use a non-OO function (I am having trouble
> getting the connection object to work but ars_Login seems to work).
>
> Any suggestions?

It isn't exactly what you're looking for, but you can use the following code to 
extract the label corresponding to a particular enumerated index for a 
particular form view. I extracted the code from a larger module, and had to 
clean it up a bit, so no guaratees that it will make it through the compiler, 
but in principle it works.  Also, it could be made much more efficient by 
cacheing stuff that it currently doesn't...

Cheers,
Robert Urban

-snip-
#--------------------------------------------------------------------
# getEnumValueLabel()
#
# assuming you have an open (non-OO) ARSPerl connection...
#
# getEnumValueLabel() will return the label from the View for $locale
# corresponding to the numerical field value for a particular request
#--------------------------------------------------------------------
sub getEnumValueLabel
{
    my ($ars_ctrl, $form_name, $request_id, $field_name, $locale) = @_;

    my $field_id = lookupFieldId($ars_ctrl, $form_name, $field_name);

    #--------------------------------------------------------------
    # call ars_GetEntry() to get the (numerical) field value, which
    # is an index into the enumerated value list.
    #--------------------------------------------------------------
    (my %fields = ars_GetEntry($ars_ctrl, $form_name, $request_id, $field_id))
        || die "ars_GetEntry failed: $ars_errstr";
    my $numeric_val = $fields{$field_id};

    my @values;

    #--------------------------------------------------------------
    # get field-information using ars_GetField()
    #--------------------------------------------------------------
    my $finfo = ars_GetField($ars_ctrl, $form_name, $field_id);
    my $value_str = getEnumValuesForLocale($ars_ctrl, $form_name, $finfo, 
$locale);
    @values = decodeEnumValues($value_str);
    @values || die "decode of enum values failed";

    return $values[$numeric_val];
}

#--------------------------------------------------------------------
# lookupFieldId() looks up the field-ID that corresponds to $field_name
# This implementation is only for demonstration purposes.  Really,
# ars_GetFieldTable() should be called only once for a particular form
# and the values should be cached...
#--------------------------------------------------------------------
sub lookupFieldId
{
    my ($ars_ctrl, $form_name, $field_name) = @_;

    (my %fields = ars_GetFieldTable($ars_ctrl, $schema))
        || die "schema [$schema] seems not to exist.\n";

    exists($fields{$field_name}) || die "field [$field_name] not found";

    return $fields{$field_name};
}
#--------------------------------------------------------------------
# getEnumValuesForLocale() goes through all available field "display instances"
# looking for the one corresponding to $locale
#--------------------------------------------------------------------
sub getEnumValuesForLocale
{
    my ($ars_ctrl, $form_name, $finfo, $locale) = @_;

    my @di_list = @{ $finfo->{displayInstanceList}->{dInstanceList} };
    my $result;
    foreach my $di (@di_list) {
        my $vinfo = ars_GetVUI($ars_ctrl, $form_name, $di->{vui});
        defined($vinfo) || die "GetVUI failed: $ars_errstr";
        next if ($locale ne $vinfo->{locale});

        my $enum_values = findProp($di, ARS::AR_DPROP_ENUM_LABELS);
        if (!defined($enum_values)) {
            print "prop AR_DPROP_ENUM_LABELS not found\n";
            next;
        }
        return $enum_values
    }
    die "view for locale [$locale] not found";
}

#--------------------------------------------------------------------
# the display instance structure in the field information structure
# stores the view-specific field labels as a wierd string looking something
# like "4\0\label0\1\label1\2\label2\3\label3"
#
# decodeEnumValues() returns an array of the labels, using the above
# example: ('label0', 'label1', 'label2', 'label3');
#--------------------------------------------------------------------
sub decodeEnumValues
{
    my $str = shift;

    $str =~ s/^(\d+)\\//;
    my $num_values = $1;

    my ($index, $value);
    my @values;
    while(defined($str)) {
        unless ($str =~ /^(\d+)\\([^\\]+)(?:\\(.*)|$)/) {
            die "match failed";
        }
        ($index, $value, $str) = ($1, $2, $3);
        push(@values, $value);
    }

    return @values;
}

#---------------------------------------------------------------------
# go though properties list looking for propery with value = $prop_num
#---------------------------------------------------------------------
sub findProp
{
    my ($vref, $prop_num) = @_;

    foreach my $pref (@{ $vref->{props} }) {
        if ($pref->{prop} == $prop_num) {
            return $pref->{value};
        }
    }
    return undef;
}
-snip-

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/


--
Arsperl-users mailing list
Arsperl-users@arsperl.org
https://lists.sourceforge.net/lists/listinfo/arsperl-users

Reply via email to