state_select — display state selector dropdown box
Interchange 5.9.0:
Source: code/Widget/country_select.widget
Lines: 386
# Copyright 2005-2009 Interchange Development Group and others # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. See the LICENSE file for details. CodeDef state_select Widget 1 CodeDef state_select Description State (needs country_select) CodeDef state_select Help Requires country_select widget for country to work properly CodeDef state_select Routine <<EOR sub { my $opt = shift; my $sel = $opt->{state_element}; if(! $sel) { my $n = $opt->{name}; my $pre = ''; if($n =~ /^([a-z]_)/) { $pre = $1; } $sel = "${pre}state_widget_container"; } $opt->{type} = 'hidden'; my $wid = Vend::Form::display($opt); return qq{$wid<span id="$sel"></span>}; } EOR CodeDef state_select ExtraMeta <<EOM { _order => [ qw/ state_element /], state_element => { label => 'State element ID', help => 'The CSS ID of the span containing the dynamic widget. The \ default is usually good (state_widget_container or b_state_widget_container)', widget => 'text_30', }, } EOM CodeDef country_select Widget 1 CodeDef country_select Description Country CodeDef country_select Help Requires state_select widget for state to work properly CodeDef country_select Routine <<EOR sub { my ($opt) = @_; my $name = $opt->{name} ||= 'country'; use vars qw/$Tag/; my $sel = $opt->{state_element}; my $pre = ''; if(! $sel) { my $n = $opt->{name}; if($n =~ /^([a-z]_)/) { $pre = $1; } $sel = "${pre}state_widget_container"; } my $svar = $opt->{state_var} || $opt->{state_variable} || "${pre}state"; my $svar_in = $svar . '_cs_in'; my $size = $opt->{state_size} || $opt->{cols} || $opt->{width} || '16'; my $ctab = $opt->{country_table} || 'country'; $opt->{state_style} ||= 'font-style: italic; font-size: smaller'; my $die = sub { my ($msg, @arg) = @_; $msg = errmsg($msg) if @arg; $Tag->error({ name => 'country_select widget', set => $msg}); ::logError($msg); return undef; }; my $pr; my $ap; my $stab = $opt->{state_table} || 'state'; my $csort = $opt->{country_sort} || ($opt->{no_region} ? 'name' : 'sorder,name'); my $ssort = $opt->{state_sort} || 'country,name'; my @csort = grep /\w/, split /[\s,\0]+/, $csort; my $csort_sub = sub { for(@csort) { my $so = $a->{$_} cmp $b->{$_}; return $so if $so; } return 0; }; my @ssort = grep /\w/, split /[\s,\0]+/, $ssort; my $ssort_sub = sub { for(@ssort) { my $so = $a->{$_} cmp $b->{$_}; return $so if $so; } return 0; }; my $cdb = dbref($ctab) or return $die->('country table %s not found', $ctab); my $sdb = dbref($stab) or return $die->('state table %s not found', $stab); $ctab = $cdb->name(); $stab = $sdb->name(); my $cq = "select * from $ctab"; my $sq = "select * from $stab"; my $cary = $cdb->query({ sql => $cq, hashref => 1}); my $sary = $sdb->query({ sql => $sq, hashref => 1}); @csort = grep exists($cary->[0]{$_}), @csort; @ssort = grep exists($sary->[0]{$_}), @ssort; @$cary = sort $csort_sub @$cary; @$sary = sort $ssort_sub @$sary; if($opt->{only_with_shipping}) { @$cary = grep $_->{shipmodes} =~ /\w/, @$cary; } my %states; for my $s (@$sary) { my $c = $s->{country}; push @{$states{$c} ||= []}, [ $s->{state}, $s->{name} ]; } my @copts; my %no_state; my $v_formv = "${pre}formv"; my $v_csval = "${pre}csval"; my $v_f = "${pre}f"; my $v_no_state = "${pre}no_state"; my $v_state_tary = "${pre}state_tary"; my $v_state_vary = "${pre}state_vary"; my $prev; for my $c (@$cary) { if($c->{no_state}) { $no_state{$c->{code}} = 1; } if(! $opt->{no_region} and $c->{region} and $c->{region} ne $prev) { push @copts, ["~~" . $c->{region} . "~~"]; $prev = $c->{region}; } push @copts, [ $c->{code}, $c->{name} ]; } my @pre; push @pre, <<EOF; <script> var $v_formv; var $v_no_state = new Array; EOF for(keys %no_state) { push @pre, "$v_no_state\['$_'] = 1"; } push @pre, <<EOF; var $v_state_vary = new Array; var $v_state_tary = new Array; EOF for(keys %states) { my $sa = $states{$_}; my @sv; my @st; my %seen; @$sa = grep !$seen{$_->[0]}++, @$sa; for my $e (@$sa) { push @sv, $e->[0]; push @st, $e->[1]; } for(@sv) { s/'/\\'/g; } for(@st) { s/'/\\'/g; } my $string = "$v_state_vary\['$_'] = ['"; $string .= join "','", '', @sv; $string .= "'];"; push @pre, $string; $string = "$v_state_tary\['$_'] = ['"; $string .= join "','", errmsg('--select state--'), @st; $string .= "'];"; push @pre, $string; } my $cvar = $opt->{name}; $cvar =~ s/\W+/_/g; my $extra = $opt->{state_extra} ? " $opt->{state_extra}" : ''; my $state_js = $opt->{state_js} ? "; $opt->{state_js}" : ''; my $state_class = $opt->{state_class} ? "$opt->{state_class}" : ''; my $country_js = $opt->{country_js} ? "; $opt->{country_js}" : ''; for ($state_js, $country_js) { s|\bthis\.form\b|$v_formv|g } push @pre, <<EOF; function ${cvar}_widget_adjust_state (cel,sval) { var sbox = document.getElementById('$sel'); var country = cel.value; if(! $v_formv) { $v_formv=cel.form; } if(! sval) { if($v_formv.$svar && $v_formv.$svar.value) sval = $v_formv.$svar.value; else sval = ''; } if(! sbox) return; if($v_no_state\[country]) { sbox.innerHTML = '<span style="$opt->{state_style}">No state required</span>'; $v_formv.$svar.value = ''; return; } var svary = $v_state_vary\[country]; if(! svary) { var val = ''; sbox.innerHTML = '<input type="text" size="$size" name="$svar_in" \ id="$svar_in" value="' + sval + '" onChange="$v_formv.$svar.value = this.value"$extra>'; $v_formv.$svar.value=sval; return; } var stary = $v_state_tary\[country]; var str = '<select name="$svar_in" id="$svar_in" onChange="$v_formv.$svar.value \ = this.value$state_js" class="$state_class"$extra>'; for(var i = 0; i < svary.length; i++) { str += '<option value="' + svary[i] + '"'; if(svary[i] == sval) str += ' SELECTED'; str += '>'; str += stary[i]; } str += '</select>'; sbox.innerHTML = str; return; } </script> EOF my $sval = $CGI::values{$svar} || $::Values->{$svar}; $sval = HTML::Entities::encode($sval, $ESCAPE_CHARS::std); $sval = $Tag->jsq($sval) || "''"; my $fname = $opt->{form_name} || 'nevairbe'; my $prepend = join "\n", @pre; if(my $sub = $opt->{callback_prescript}) { $sub->($prepend); } else { $opt->{prepend} = '' unless defined $opt->{prepend}; $opt->{prepend} .= "\n" if length $opt->{prepend}; $opt->{prepend} .= $prepend; } my $append = <<EOF; <script> var $v_f = document.$fname; var $v_csval = $sval; if(!$v_f) { for(var i = 0; i < document.forms.length; i++) { $v_f = document.forms[i]; if($v_f.$opt->{name}) { if($v_f.$svar && $v_f.$svar.value) $v_csval = $v_f.$svar.value; ${cvar}_widget_adjust_state($v_f.$opt->{name}, $v_csval); break; } } } $v_formv = $v_f; if($v_formv.$svar) { csval = $v_formv.$svar.value; } ${cvar}_widget_adjust_state($v_formv.$opt->{name}, $v_csval); </script> EOF if(my $sub = $opt->{callback_postscript}) { $sub->($append); } else { $opt->{append} = '' unless defined $opt->{append}; $opt->{append} .= "\n" if length $opt->{append}; $opt->{append} .= $append; } $opt->{js} = qq{ onLoad="${cvar}_widget_adjust_state(this)" onChange="${cvar}_widget_adjust_state \ (this)$country_js"}; my @out; #push @out, '<xmp>'; #push @out, ::uneval(\%states); #push @out, '</xmp>'; $opt->{type} = 'select'; push @out, Vend::Form::display($opt, {}, \@copts); return join "\n", @out; } EOR CodeDef country_select ExtraMeta <<EOM { _order => [ qw/ state_var state_style state_class country_sort no_region only_with_shipping form_name country_table state_table state_element state_js /], state_var => { label => 'State variable', help => 'default is <i>state</i>, might use <i>b_state</i> instead', widget => 'text_16', }, state_class => { label => 'CSS class for state', help => 'Modify look of state text', widget => 'text_20', }, state_style => { label => 'CSS style for state', help => 'Modify look of state text', widget => 'text_60', }, no_region => { label => 'Region sort', help => 'Controls country groupings', options => '=Region sort, 1=No region sort', widget => 'select', }, only_with_shipping => { label => 'Only with shipping', help => 'Only show countries that have value in shipmodes', options => '=All countries, 1=Only with shipping', widget => 'select', }, country_sort => { label => 'Country sort order', help => 'Should be "name" if no region sort, "sorder,name" with region', widget => 'text_16', }, country_table => { label => 'Country table', help => 'default is usually good (country)', widget => 'text_16', }, state_sort => { label => 'State sort order', help => 'Default of <i>country,name</i> is usually OK', widget => 'text_16', }, state_table => { label => 'State table', help => 'default is usually good (state)', widget => 'text_16', }, state_element => { label => 'State element ID', help => 'The CSS ID of the span containing the dynamic widget. The \ default is usually good (state_widget_container or b_state_widget_container)', widget => 'text_30', }, state_js => { label => 'State javascript', help => 'Runs specified javascript under onChange. E.g. "state_js=check_tax(this.form)"', widget => 'text_20', }, } EOM