<%doc> Performs searches whose return values are used to fill in objects in HTML pages via asynnchronous javascript calls. When debugging, turn DEBUG flag on and execute directly from browser: * Searching a single field: /generic/jsrs_netdot.html?table=Floor&form_field=floor_id&keywords=82&field=site * Searching label fields recursively: /generic/jsrs_netdot.html?table=Site&field=colname&form_field=site_srch&keywords=computing If 'field' is omitted it searches for 'name' by default. <%flags> inherit => undef <%shared> my $DEBUG = 0; <%perl> if ( $DEBUG ){ use Data::Dumper; print "

     ", Dumper(%ARGS), "

"; print &keyword_search($ARGS{table}, $ARGS{form_field}, $ARGS{keywords}, $ARGS{field}, $ARGS{nomax}); }else{ # Do not use 'require' here. # We need to make sure the file is read *each time* do "jsrsServer.pm"; jsrsDispatch("keyword_search"); } # Arguments: # - table: Table to search. # - form_field: Name of the form field to add the results into # - keywords: keywords to search for # - field: Name of the field for which we\'re searching foreign values # if undefined, search will be performed recursively on the # "label" fields of the table, as defined in metadata # - nomax: Do not limit the results sub keyword_search { my ( $table, $form_field, $keywords, $field, $nomax ) = @_; my $r; my @terms; my $MAX = $ui->config->get('DEFAULT_SELECTMAX'); if ( $keywords =~ /\w+/ ){ if ( $keywords =~ s/^\s*(.*)\s*$/$1/ ){ @terms = split /\s+/, $keywords; }else{ $terms[0] = $keywords; } }else{ return; } my $response = $form_field."&"; if ( $table eq 'Ipblock' ){ my @r = Ipblock->search(address=>$keywords); map { $r->{$_->id} = $_ } @r; if ( !(scalar (keys %$r)) ){ @r = Ipblock->search_like(address=>$keywords); map { $r->{$_->id} = $_ } @r; } }else{ if ( $field && $field ne "null" ){ my @r = $table->search($field=>$terms[0]); map { $r->{$_->id} = $_ } @r; if ( !(scalar (keys %$r)) ){ @r = $table->search_like($field=>$terms[0]); map { $r->{$_->id} = $_ } @r; } }else{ $r = $ui->select_query(table => $table, terms => \@terms); } } if ( my $n = scalar (keys %$r) ){ my $count = 0; if ( !$nomax && $n >= $MAX ){ $response .= "null=".$ui->url_encode("More than ".$MAX." matches.")."&"; $response .= "null=".$ui->url_encode("Refine search.")."&"; }else{ my @objs = map { $r->{$_} } keys %$r; if ( $table eq 'Interface' ){ # Always order interfaces by ifIndex @objs = sort { $a->number <=> $b->number } @objs; }else{ @objs = sort { $a->get_label cmp $b->get_label } @objs; } # Added this select tag so that the user is able to select # something which will trigger updating of related select # lists. This is important because if there is only one result then the # user can't trigger a change event, which is needed to trigger the # select update code specified via the onChange event handler # attribute of the selects in question. $response .= "null=-- Select --&"; foreach my $o ( @objs ){ my $lbl = $o->get_label(); $response .= $o->id."=".$ui->url_encode($lbl)."&"; last if (!$nomax && $count++) == $MAX; } } }else{ $response .= "null=".$ui->url_encode("No matches"); } return $response; }