+ $Ajax->addUpdate($name, "_{$name}_sel", $selector);
+
+ // span for select list/input field update
+ $selector = "<span id='_{$name}_sel'>".$selector."</span>\n";
+
+ // if selectable or editable list is used - add select button
+ if ($select_submit != false || $search_button) {
+ global $_select_button;
+ // button class selects form reload/ajax selector update
+ $selector .= sprintf($_select_button, $disabled, user_theme(),
+ (fallback_mode() ? '' : 'display:none;'),
+ '_'.$name.'_update')."\n";
+ }
+// ------ make combo ----------
+ $edit_entry = '';
+ if ($search_box != false) {
+ $edit_entry = "<input $disabled type='text' name='$search_box' id='$search_box' size='".
+ $opts['size']."' maxlength='".$opts['max'].
+ "' value='$txt' class='$class' rel='$name' autocomplete='off' title='"
+ .$opts['box_hint']."'"
+ .(!fallback_mode() && !$by_id ? " style=display:none;":'')
+ .">\n";
+ if ($search_submit != false || $opts['editable']) {
+ global $_search_button;
+ $edit_entry .= sprintf($_search_button, $disabled, user_theme(),
+ (fallback_mode() ? '' : 'display:none;'),
+ $search_submit ? $search_submit : "_{$name}_button")."\n";
+ }
+ }
+ default_focus(($search_box && $by_id) ? $search_box : $name);
+
+ if ($search_box && $opts['cells'])
+ $str = ($edit_entry!='' ? "<td>$edit_entry</td>" : '')."<td>$selector</td>";
+ else
+ $str = $edit_entry.$selector;
+ return $str;
+}
+
+/*
+ Helper function.
+ Returns true if selector $name is subject to update.
+*/
+function list_updated($name)
+{
+ return isset($_POST['_'.$name.'_update']) || isset($_POST['_'.$name.'_button']);
+}
+//----------------------------------------------------------------------------------------------
+// Universal array combo generator
+// $items is array of options 'value' => 'description'
+// Options is reduced set of combo_selector options and is merged with defaults.
+
+function array_selector($name, $selected_id, $items, $options=null)
+{
+ global $Ajax;
+
+$opts = array( // default options
+ 'spec_option'=>false, // option text or false
+ 'spec_id' => 0, // option id
+ 'select_submit' => false, //submit on select: true/false
+ 'async' => true, // select update via ajax (true) vs _page_body reload
+ 'default' => '', // default value when $_POST is not set
+ 'multi'=>false, // multiple select
+ // search box parameters
+ 'height' => false, // number of lines in select box
+ 'sel_hint' => null,
+ 'disabled' => false
+);
+// ------ merge options with defaults ----------
+ if($options != null)
+ $opts = array_merge($opts, $options);
+ $select_submit = $opts['select_submit'];
+ $spec_id = $opts['spec_id'];
+ $spec_option = $opts['spec_option'];
+ $disabled = $opts['disabled'] ? "disabled" : '';
+ $multi = $opts['multi'];
+
+ if ($selected_id == null) {
+ $selected_id = get_post($name, $opts['default']);
+ }
+ if(!is_array($selected_id))
+ $selected_id = array($selected_id); // code is generalized for multiple selection support
+
+ if (isset($_POST[ '_'.$name.'_update'])) {
+ if (!$opts['async'])
+ $Ajax->activate('_page_body');
+ else
+ $Ajax->activate($name);
+ }
+
+ // ------ make selector ----------
+ $selector = $first_opt = '';
+ $first_id = false;
+ $found = false;
+//if($name=='SelectStockFromList') display_error($sql);
+ foreach($items as $value=>$descr) {
+ $sel = '';
+ if (in_array((string)$value, $selected_id, true)) {
+ $sel = "selected='selected'";
+ $found = $value;
+ }
+ if ($first_id === false) {
+ $first_id = $value;
+ $first_opt = "<option %s value='$value'>$descr</option>\n";
+ }
+ else {
+ $selector .= "<option $sel value='$value'>$descr</option>\n";
+ }
+ }
+
+ if ($first_id!==false) {
+ $sel = ($found===$first_id) || ($found===false && ($spec_option===false)) ? "selected='selected'" : '';
+ $selector = sprintf($first_opt, $sel).$selector;
+ }
+ // Prepend special option.
+ if ($spec_option !== false) { // if special option used - add it
+ $first_id = $spec_id;
+ $first_opt = $spec_option;
+ $sel = $found===false ? "selected='selected'" : '';
+ $selector = "<option $sel value='$spec_id'>$spec_option</option>\n"
+ . $selector;