Exemplo n.º 1
0
 /**
  * Override the sensitivity control to create a simple select with default value 
  * set by user profile.
  */
 protected static function get_control_sensitivity($auth, $args, $tabAlias, $options)
 {
     // Obtain the default value for the user.
     global $user;
     $user = user_load($user->uid);
     $field_values = field_get_items('user', $user, 'field_icpveg_permission');
     $default_value = $field_values[0]['value'];
     if ($default_value == 0) {
         // Where Drupal stores 0, we want the Warehouse field to be NULL to indicate
         // no blurring of detail.
         $default_value = '';
     }
     return data_entry_helper::select(array_merge(array('fieldname' => 'occurrence:sensitivity_precision', 'label' => lang::get('ICPVeg Sensitivity'), 'lookupValues' => array('50000' => lang::get('ICPVeg Sensitivity 50km')), 'blankText' => lang::get('ICPVeg Sensitivity blankText'), 'default' => $default_value), $options));
 }
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     data_entry_helper::enable_tabs(array('divId' => 'controls'));
     $r = "<form method=\"post\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $r .= data_entry_helper::get_auth($args['website_id'], $args['password']);
     $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"record_status\" name=\"record_status\" value=\"C\" />\n";
     $r .= "<div id=\"controls\">\n";
     // Create a list which jQuery can parse to create the tabs.
     $r .= "<ul>\r\n      <li><a href=\"#recorder\"><span>Recorder</span></a></li>\r\n      <li><a href=\"#site\"><span>Site</span></a></li>\r\n      <li><a href=\"#species_tab_1\"><span>" . $args['tab_title_1'] . "</span></a></li>\n";
     if ($args['list_id_2']) {
         $r .= "<li><a href=\"#species_tab_2\"><span>" . $args['tab_title_2'] . "</span></a></li>\n";
     }
     if ($args['list_id_3']) {
         $r .= "<li><a href=\"#species_tab_3\"><span>" . $args['tab_title_3'] . "</span></a></li>\n";
     }
     if ($args['list_id_4']) {
         $r .= "<li><a href=\"#species_tab_4\"><span>" . $args['tab_title_4'] . "</span></a></li>\n";
     }
     $r .= "</ul>\n";
     $r .= "<div id=\"recorder\">\n";
     $r .= data_entry_helper::select(array('label' => 'Title', 'fieldname' => 'smpAttr:5', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $readAuth + array('termlist_external_key' => 'indicia:titles')));
     $r .= data_entry_helper::text_input(array('label' => 'First name', 'fieldname' => 'smpAttr:6'));
     $r .= data_entry_helper::text_input(array('label' => 'Last name', 'fieldname' => 'smpAttr:7'));
     $r .= data_entry_helper::text_input(array('label' => 'Email', 'fieldname' => 'smpAttr:8'));
     // Postcode before address since entering the postcode auto-populates part of the address.
     $r .= data_entry_helper::postcode_textbox(array('label' => 'Postcode', 'fieldname' => 'smpAttr:10', 'linkedAddressBoxId' => 'address', 'hiddenFields' => false));
     $r .= data_entry_helper::textarea(array('label' => 'Address', 'fieldname' => 'smpAttr:9', 'id' => 'address'));
     $r .= "</div>\n";
     $r .= "<div id=\"site\">\n";
     $r .= data_entry_helper::map();
     $r .= data_entry_helper::date_picker(array('label' => 'Date', 'fieldname' => 'sample:date'));
     $r .= "</div>\n";
     $r .= "<div id=\"species_tab_1\">\n";
     $species_list_args = array('label' => 'Species', 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'extraParams' => $readAuth + array('taxon_list_id' => $args['list_id_1']));
     $r .= data_entry_helper::species_checklist($species_list_args);
     $r .= "</div>\n";
     $r .= "</div>\n";
     $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     $r .= "</form>";
     return $r;
 }
Exemplo n.º 3
0
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     $r = "<form method=\"post\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $r .= data_entry_helper::get_auth($args['website_id'], $args['password']);
     $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"record_status\" name=\"record_status\" value=\"C\" />\n";
     $r .= "<div id=\"controls\">\n";
     if ($args['tabs']) {
         $r .= "<ul>\n        <li><a href=\"#species\"><span>Species</span></a></li>\n        <li><a href=\"#place\"><span>Place</span></a></li>\n        <li><a href=\"#other\"><span>Other Information</span></a></li>\n      </ul>\n";
         data_entry_helper::enable_tabs(array('divId' => 'controls'));
     }
     $r .= "<div id=\"species\">\n";
     $extraParams = $readAuth + array('taxon_list_id' => $args['list_id']);
     if ($args['preferred']) {
         $extraParams += array('preferred' => 't');
     }
     $species_list_args = array('label' => 'Species', 'itemTemplate' => 'select_species', 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'extraParams' => $extraParams);
     // Dynamically generate the species selection control required.
     $r .= call_user_func(array('data_entry_helper', $args['species_ctrl']), $species_list_args);
     $r .= "</div>\n";
     $r .= "<div id=\"place\">\n";
     // for this form, use bing and no geoplanet lookup, since then it requires no API keys so is a good
     // quick demo of how things work.
     $mapOptions = array('presetLayers' => array('bing_aerial'), 'locate' => false);
     if ($args['tabs']) {
         $mapOptions['tabDiv'] = 'place';
     }
     $r .= data_entry_helper::map($mapOptions);
     $r .= "</div>\n";
     $r .= "<div id=\"other\">\n";
     $r .= data_entry_helper::date_picker(array('label' => 'Date', 'fieldname' => 'sample:date'));
     $r .= data_entry_helper::select(array('label' => 'Survey', 'fieldname' => 'sample:survey_id', 'table' => 'survey', 'captionField' => 'title', 'valueField' => 'id', 'extraParams' => $readAuth));
     $r .= data_entry_helper::textarea(array('label' => 'Comment', 'fieldname' => 'sample:comment', 'class' => 'wide'));
     $r .= "</div>\n";
     $r .= "</div>\n";
     $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     $r .= "</form>";
     return $r;
 }
Exemplo n.º 4
0
 public static function my_sites_form($auth, $args, $tabalias, $options, $path)
 {
     if (!function_exists('iform_ajaxproxy_url')) {
         return 'An AJAX Proxy module must be enabled for the My Sites Form to work.';
     }
     $r = "<fieldset><legend>" . lang::get('Find additional sites to store in your sites list') . "</legend>";
     if (empty($options['locationTypes']) || !preg_match('/^([0-9]+,( )?)*[0-9]+$/', $options['locationTypes'])) {
         return 'The My sites form is not correctly configured. Please provide the location types to allow search by.';
     }
     $locationTypes = explode(',', str_replace(' ', '', $options['locationTypes']));
     if (empty($options['locationTypeResults']) || !preg_match('/^([0-9]+,( )?)*[0-9]+$/', $options['locationTypeResults'])) {
         return 'The My sites form is not correctly configured. Please provide the location types to allow results to be returned for.';
     }
     if (empty($options['mySitesPsnAttrId']) || !preg_match('/^[0-9]+$/', $options['mySitesPsnAttrId'])) {
         return 'The My sites form is not correctly configured. Please provide the person attribute ID used to store My Sites.';
     }
     $localityOpts = array('fieldname' => 'locality_id', 'id' => 'locality_id', 'extraParams' => $auth['read'] + array('orderby' => 'name'), 'blankText' => '<' . lang::get('all') . '>');
     if (count($locationTypes) > 1) {
         $r .= '<label>' . lang::get('Select site by type then locality:') . '</label> ';
         $r .= data_entry_helper::select(array('fieldname' => 'location_type_id', 'table' => 'termlists_term', 'valueField' => 'id', 'captionField' => 'term', 'extraParams' => $auth['read'] + array('orderby' => 'term', 'query' => urlencode(json_encode(array('in' => array('id', $locationTypes))))), 'blankText' => '<' . lang::get('please select') . '>'));
         // link the locality select to the location type select
         $localityOpts = array_merge(array('parentControlId' => 'location_type_id', 'parentControlLabel' => lang::get('Site type to search'), 'filterField' => 'location_type_id', 'filterIncludesNulls' => false, 'emptyFilterIsUnfiltered' => true), $localityOpts);
     } else {
         $r .= '<label>' . lang::get('Select site by locality') . '</label> ';
         // no need for a locality select, so just filter to the location type
         $localityOpts['extraParams']['location_type_id'] = $locationTypes[0];
         $localityOpts['default'] = hostsite_get_user_field('location');
     }
     $r .= data_entry_helper::location_select($localityOpts);
     $r .= data_entry_helper::location_select(array('id' => 'location-select', 'report' => 'library/locations/locations_for_my_sites', 'table' => '', 'valueField' => 'location_id', 'captionField' => 'q', 'extraParams' => $auth['read'] + array('location_type_ids' => $options['locationTypeResults'], 'locattrs' => '', 'user_id' => hostsite_get_user_field('indicia_user_id'), 'person_site_attr_id' => $options['mySitesPsnAttrId'], 'hide_existing' => 1), 'parentControlId' => 'locality_id', 'parentControlLabel' => lang::get('Locality to search'), 'filterField' => 'parent_id', 'filterIncludesNulls' => false, 'blankText' => '<' . lang::get('please select') . '>'));
     $r .= '<button id="add-site-button" type="button">' . lang::get('Add to My Sites') . '</button><br/>';
     $r .= data_entry_helper::location_autocomplete(array('id' => 'location-search', 'label' => lang::get('<strong>Or</strong> search for a site'), 'report' => 'library/locations/locations_for_my_sites', 'table' => '', 'valueField' => 'location_id', 'captionField' => 'q', 'extraParams' => $auth['read'] + array('location_type_ids' => $options['locationTypeResults'], 'locattrs' => '', 'user_id' => hostsite_get_user_field('indicia_user_id'), 'person_site_attr_id' => $options['mySitesPsnAttrId'], 'hide_existing' => 1, 'parent_id' => '')));
     $r .= '<button id="add-searched-site-button" type="button">' . lang::get('Add to My Sites') . '</button><br/>';
     $postUrl = iform_ajaxproxy_url(null, 'person_attribute_value');
     data_entry_helper::$javascript .= "\r\n      function addSite(locationId) {\r\n        if (!isNaN(locationId) && locationId!=='') {\r\n          \$.post('{$postUrl}', \r\n            {\"website_id\":" . $args['website_id'] . ",\"person_attribute_id\":" . $options['mySitesPsnAttrId'] . ",\"user_id\":" . hostsite_get_user_field('indicia_user_id') . ",\"int_value\":locationId} ,\r\n            function (data) {\r\n              if (typeof data.error === 'undefined') {\r\n                indiciaData.reports.dynamic.grid_report_grid_0.reload(true);\r\n              } else {\r\n                alert(data.error);\r\n              }\r\n            },\r\n            'json'\r\n          );\r\n        }\r\n      }\r\n      \$('#add-site-button').click(function() {\r\n        addSite(\$('#location-select').val());\r\n        if (!isNaN(\$('#location-select').val())) {\r\n          \$('#location-select option:selected').remove();\r\n        }\r\n      });\r\n      \$('#add-searched-site-button').click(function() {addSite(\$('#location-search').val());});\r\n      \$('#location-select, #location-search, #locality_id').change(function() {\r\n        if (typeof indiciaData.mapdiv!=='undefined') {\r\n          indiciaData.mapdiv.locationSelectedInInput(indiciaData.mapdiv, this.value);\r\n        }\r\n      });\r\n      \r\n      linked_site_delete = function(pav_id) {\r\n        var userId=" . hostsite_get_user_field('indicia_user_id') . ";\r\n        \$.post('{$postUrl}', \r\n          {\"website_id\":" . $args['website_id'] . ",\"id\":pav_id, \"deleted\":\"t\"},\r\n          function (data) {\r\n            if (typeof data.error === 'undefined') {\r\n              indiciaData.reports.dynamic.grid_report_grid_0.reload(true);\r\n            } else {\r\n              alert(data.error);\r\n            }\r\n          },\r\n          'json'\r\n        );\r\n      }\r\n    ";
     $r .= '</fieldset>';
     return $r;
 }
 private static function get_site_tab($auth, $args, $settings)
 {
     $r = '<div id="site-details" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="input-form">';
     $r .= $auth['write'];
     $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: 54%">';
     $r .= '<fieldset><legend>' . lang::get('Site Details') . '</legend>';
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $typeTerms = array();
     if (!empty($args['main_type_term_1'])) {
         $typeTerms[] = $args['main_type_term_1'];
     }
     if (!empty($args['main_type_term_2'])) {
         $typeTerms[] = $args['main_type_term_2'];
     }
     if (!empty($args['main_type_term_3'])) {
         $typeTerms[] = $args['main_type_term_3'];
     }
     $typeTermIDs = helper_base::get_termlist_terms($auth, 'indicia:location_types', $typeTerms);
     $lookUpValues = array('' => '<' . lang::get('please select') . '>');
     foreach ($typeTermIDs as $termDetails) {
         $lookUpValues[$termDetails['id']] = $termDetails['term'];
     }
     // if location is predefined, can not change unless a 'managerPermission'
     $canEditType = !$settings['locationId'] || isset($args['managerPermission']) && $args['managerPermission'] != '' && function_exists('user_access') && user_access($args['managerPermission']);
     if ($canEditType) {
         $r .= data_entry_helper::select(array('label' => lang::get('Site Type'), 'id' => 'location_type_id', 'fieldname' => 'location:location_type_id', 'lookupValues' => $lookUpValues));
         data_entry_helper::$javascript .= "\$('#location_type_id').change(function(){\r\n  switch(\$(this).val()){\n";
         for ($i = 1; $i < 4; $i++) {
             if (!empty($args['main_type_term_' . $i])) {
                 $type = helper_base::get_termlist_terms($auth, 'indicia:location_types', array($args['main_type_term_' . $i]));
                 data_entry_helper::$javascript .= "    case \"" . $type[0]['id'] . "\":\n";
                 if (!isset($args['can_change_section_number_' . $i]) || !$args['can_change_section_number_' . $i]) {
                     if ($settings['locationId']) {
                         // not saved yet, so no sections yet created, hence no need to worry about existing value. make number attribute readonly. set value. min value will be 1.
                         data_entry_helper::$javascript .= "      var minValue = \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').attr('min');\r\n      if(minValue > " . $args['section_number_' . $i] . ") { // existing value is greater than one we want to set\r\n        alert('You are reducing the number of sections below that already existing. Please use the Remove Section button on the Your Route tab to reduce the number of sections to " . $args['section_number_' . $i] . " before changing the Site type');\r\n        return false;\r\n      }\r\n      \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').val(" . $args['section_number_' . $i] . ").attr('readonly','readonly').css('color','graytext');\n";
                     } else {
                         // not saved yet, so no sections yet created, hence no need to worry about existing value. make number attribute readonly. set value. min value will be 1.
                         data_entry_helper::$javascript .= "      \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').val(" . $args['section_number_' . $i] . ").attr('readonly','readonly').css('color','graytext');\n";
                     }
                 } else {
                     // user modifiable number of sections. value of attribute is left alone: don't have to worry att his point whether existing data.
                     data_entry_helper::$javascript .= "      \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').removeAttr('readonly').css('color','');\n";
                 }
                 data_entry_helper::$javascript .= "      break;\n";
             }
         }
         data_entry_helper::$javascript .= "    default: break;\r\n  };\r\n  return true;\r\n});\n";
     }
     if ($settings['locationId']) {
         $r .= '<input type="hidden" name="location:id" id="location:id" value="' . $settings['locationId'] . "\" />\n";
     }
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Site Name'), 'class' => 'control-width-4 required', 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if (!$settings['canEditBody']) {
         $r .= '<p>' . lang::get('This site cannot be edited because there are walks recorded on it. Please contact the site administrator if you think there are details which need changing.') . '</p>';
     } else {
         if (count($settings['walks']) > 0) {
             // can edit it
             $r .= '<p>' . lang::get('This site has walks recorded on it. Please do not change the site details without considering the impact on the existing data.') . '</p>';
         }
     }
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     if (isset(data_entry_helper::$entity_to_load['location:centroid_sref_system']) && in_array(data_entry_helper::$entity_to_load['location:centroid_sref_system'], array('osgb', 'osie'))) {
         data_entry_helper::$entity_to_load['location:centroid_sref_system'] = strtoupper(data_entry_helper::$entity_to_load['location:centroid_sref_system']);
     }
     $r .= data_entry_helper::sref_and_system(array('fieldname' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Grid Ref.', 'systems' => $systems, 'class' => 'required', 'helpText' => lang::get('Click on the map to set the central grid reference.'), 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if ($settings['locationId'] && data_entry_helper::$entity_to_load['location:code'] != '' && data_entry_helper::$entity_to_load['location:code'] != null) {
         $r .= data_entry_helper::text_input(array('fieldname' => 'location:code', 'label' => lang::get('Site Code'), 'class' => 'control-width-4', 'disabled' => ' readonly="readonly" '));
     } else {
         $r .= "<p>" . lang::get('The Site Code will be allocated by the Administrator.') . "</p>";
     }
     // setup the map options
     $options = iform_map_get_map_options($args, $auth['read']);
     // find the form blocks that need to go below the map.
     $bottom = '';
     $bottomBlocks = explode("\n", isset($args['bottom_blocks']) ? $args['bottom_blocks'] : '');
     foreach ($bottomBlocks as $block) {
         $bottom .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read'], 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '), $block);
     }
     // other blocks to go at the top, next to the map
     if (isset($args['site_help']) && $args['site_help'] != '') {
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . t($args['site_help']) . '</p>';
     }
     $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']));
     $r .= '</fieldset>';
     $r .= "</div>";
     // left
     $r .= '<div class="right" style="width: 44%">';
     if (!$settings['locationId']) {
         $help = t('Use the search box to find a nearby town or village, then drag the map to pan and click on the map to set the centre grid reference of the transect. ' . 'Alternatively if you know the grid reference you can enter it in the Grid Ref box on the left.');
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
         $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']));
     }
     if (isset($args['maxPrecision']) && $args['maxPrecision'] != '') {
         $options['clickedSrefPrecisionMax'] = $args['maxPrecision'];
     }
     if (isset($args['minPrecision']) && $args['minPrecision'] != '') {
         $options['clickedSrefPrecisionMin'] = $args['minPrecision'];
     }
     $olOptions = iform_map_get_ol_options($args);
     $options['clickForSpatialRef'] = $settings['canEditBody'];
     $r .= map_helper::map_panel($options, $olOptions);
     $r .= '</div></div>';
     // right
     if (!empty($bottom)) {
         $r .= $bottom;
     }
     if ($args['branch_assignment_permission'] != '') {
         if ($settings['canAllocBranch'] || $settings['locationId']) {
             $r .= self::get_branch_assignment_control($auth['read'], $settings['branchCmsUserAttr'], $args, $settings);
         }
     }
     if ($args['allow_user_assignment']) {
         if ($settings['canAllocUser']) {
             $r .= self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
         } else {
             if (!$settings['locationId']) {
                 // for a new record, we need to link the current user to the location if they are not admin.
                 global $user;
                 $r .= '<input type="hidden" name="locAttr:' . self::$cmsUserAttrId . '" value="' . $user->uid . '">';
             }
         }
     }
     if ($settings['canEditBody']) {
         $r .= '<button type="submit" class="indicia-button right">' . lang::get('Save') . '</button>';
     }
     if ($settings['canEditBody'] && $settings['locationId']) {
         $r .= '<button type="button" class="indicia-button right" id="delete-transect">' . lang::get('Delete') . '</button>';
     }
     $r .= '</form>';
     $r .= '</div>';
     // site-details
     // This must go after the map panel, so it has created its toolbar
     data_entry_helper::$onload_javascript .= "\$('#current-section').change(selectSection);\n";
     if ($settings['canEditBody'] && $settings['locationId']) {
         $walkIDs = array();
         foreach ($settings['walks'] as $walk) {
             $walkIDs[] = $walk['id'];
         }
         $sectionIDs = array();
         foreach ($settings['sections'] as $code => $section) {
             $sectionIDs[] = $section['id'];
         }
         data_entry_helper::$javascript .= "\r\ndeleteSurvey = function(){\r\n  if(confirm(\"" . (count($settings['walks']) > 0 ? count($settings['walks']) . ' ' . lang::get('walks will also be deleted when you delete this location.') . ' ' : '') . lang::get('Are you sure you wish to delete this location?') . "\")){\r\n    deleteWalks([" . implode(',', $walkIDs) . "]);\r\n    deleteSections([" . implode(',', $sectionIDs) . "]);\r\n    \$('#delete-transect').html('Deleting Site');\r\n    deleteLocation(" . $settings['locationId'] . ");\r\n    \$('#delete-transect').html('Done');\r\n    window.location='" . url($args['sites_list_path']) . "';\r\n  };\r\n};\r\n\$('#delete-transect').click(deleteSurvey);\r\n";
     }
     return $r;
 }
Exemplo n.º 6
0
    /**
     * Return the generated form output.
     * @return Form HTML.
     */
    public static function get_form($args, $node)
    {
        global $user;
        // There is a language entry in the args parameter list: this is derived from the $language DRUPAL global.
        // It holds the 2 letter code, used to pick the language file from the lang subdirectory of prebuilt_forms.
        // There should be no explicitly output text in this file.
        // We must translate any field names and ensure that the termlists and taxonlists use the correct language.
        // For attributes, the caption is automatically translated by data_entry_helper.
        $logged_in = $user->uid > 0;
        $uid = $user->uid;
        $email = $user->mail;
        $username = $user->name;
        if (!user_access('IForm n' . $node->nid . ' access')) {
            return "<p>" . lang::get('LANG_Insufficient_Privileges') . "</p>";
        }
        $r = '';
        // Get authorisation tokens to update and read from the Warehouse.
        $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
        $svcUrl = data_entry_helper::$base_url . '/index.php/services';
        $language = iform_lang_iso_639_2($args['language']);
        drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module');
        data_entry_helper::link_default_stylesheet();
        data_entry_helper::add_resource('jquery_ui');
        if ($args['language'] != 'en') {
            data_entry_helper::add_resource('jquery_ui_' . $args['language']);
        }
        data_entry_helper::enable_validation('new-comments-form');
        // don't care about ID itself, just want resources
        $occID = '';
        $smpID = '';
        $userID = '';
        $mode = 'FILTER';
        if (array_key_exists('insect_id', $_GET)) {
            $occID = $_GET['insect_id'];
            $mode = 'INSECT';
        } else {
            if (array_key_exists('insect', $_GET)) {
                $occID = $_GET['insect'];
                $mode = 'INSECT';
            } else {
                if (array_key_exists('flower_id', $_GET)) {
                    $occID = $_GET['flower_id'];
                    $mode = 'FLOWER';
                } else {
                    if (array_key_exists('flower', $_GET)) {
                        $occID = $_GET['flower'];
                        $mode = 'FLOWER';
                    } else {
                        if (array_key_exists('collection_id', $_GET)) {
                            $smpID = $_GET['collection_id'];
                            $mode = 'COLLECTION';
                        } else {
                            if (array_key_exists('collection', $_GET)) {
                                $smpID = $_GET['collection'];
                                $mode = 'COLLECTION';
                            } else {
                                if (array_key_exists('user_id', $_GET)) {
                                    $userID = $_GET['user_id'];
                                } else {
                                    if (array_key_exists('user', $_GET)) {
                                        $userID = $_GET['user'];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        //	data_entry_helper::enable_validation('cc-1-collection-details'); // don't care about ID itself, just want resources
        // The only things that will be editable after the collection is saved will be the identifiaction of the flower/insects.
        // no id - just getting the attributes, rest will be filled in using AJAX
        $sample_attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $occurrence_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $location_attributes = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $defAttrOptions = array('extraParams' => $readAuth + array('orderby' => 'id'), 'lookUpListCtrl' => 'checkbox_group', 'lookUpKey' => 'meaning_id', 'booleanCtrl' => 'checkbox_group', 'sep' => ' &nbsp; ', 'language' => $language, 'suffixTemplate' => 'nosuffix', 'default' => '-1');
        // note we have to proxy the post. Every time a write transaction is carried out, the write nonce is trashed.
        // For security reasons we don't want to give the user the ability to generate their own nonce, so we use
        // the fact that the user is logged in to drupal as the main authentication/authorisation/identification
        // process for the user. The proxy also packages the post into the correct format
        // the controls for the filter include all taxa, not just the ones allowed for data entry, as does the one for checking the tool, just to be on the safe side.
        $flower_ctrl_args = array('label' => lang::get('LANG_Flower_Species'), 'fieldname' => 'flower:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order'), 'suffixTemplate' => 'nosuffix');
        $focus_flower_ctrl_args = $flower_ctrl_args;
        $focus_flower_ctrl_args['fieldname'] = 'determination:taxa_taxon_list_id';
        $focus_flower_ctrl_args['extraParams'] = $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order', 'allow_data_entry' => 't');
        $insect_ctrl_args = array('label' => lang::get('LANG_Insect_Species'), 'fieldname' => 'insect:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order'), 'suffixTemplate' => 'nosuffix');
        $focus_insect_ctrl_args = $insect_ctrl_args;
        $focus_insect_ctrl_args['fieldname'] = 'determination:taxa_taxon_list_id';
        $focus_insect_ctrl_args['extraParams'] = $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order', 'allow_data_entry' => 't');
        $options = iform_map_get_map_options($args, $readAuth);
        $olOptions = iform_map_get_ol_options($args);
        // The maps internal projection will be left at its default of 900913.
        $options['initialFeatureWkt'] = null;
        $options['proxy'] = '';
        $options['suffixTemplate'] = 'nosuffix';
        if (lang::get('msgGeorefSelectPlace') != 'msgGeorefSelectPlace') {
            $options['msgGeorefSelectPlace'] = lang::get('msgGeorefSelectPlace');
        }
        if (lang::get('msgGeorefNothingFound') != 'msgGeorefNothingFound') {
            $options['msgGeorefNothingFound'] = lang::get('msgGeorefNothingFound');
        }
        $options2 = $options;
        $options['searchLayer'] = 'true';
        $options['editLayer'] = 'false';
        $options['layers'] = array('polygonLayer');
        $options2['divId'] = "map2";
        $options2['layers'] = array('locationLayer');
        $options2['height'] = $args['2nd_map_height'];
        data_entry_helper::$javascript .= "var flowerTaxa = [";
        $extraParams = $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'view' => 'list');
        $species_data_def = array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams);
        $taxa = data_entry_helper::get_population_data($species_data_def);
        $first = true;
        foreach ($taxa as $taxon) {
            data_entry_helper::$javascript .= ($first ? '' : ',') . "{id: " . $taxon['id'] . ", taxon: \"" . htmlSpecialChars($taxon['taxon']) . "\"}\n";
            $first = false;
        }
        data_entry_helper::$javascript .= "];\nvar insectTaxa = [";
        $extraParams['taxon_list_id'] = $args['insect_list_id'];
        $species_data_def['extraParams'] = $extraParams;
        $taxa = data_entry_helper::get_population_data($species_data_def);
        $first = true;
        foreach ($taxa as $taxon) {
            data_entry_helper::$javascript .= ($first ? '' : ',') . "{id: " . $taxon['id'] . ", taxon: \"" . htmlSpecialChars($taxon['taxon']) . "\"}\n";
            $first = false;
        }
        data_entry_helper::$javascript .= "];";
        // TBD Breadcrumb
        $r .= '<h1 id="poll-banner">' . lang::get('LANG_Main_Title') . '</h1>
<div id="refresh-message" style="display:none" ><p>' . lang::get('LANG_Please_Refresh_Page') . '</p></div>
<div id="filter" class="ui-accordion ui-widget ui-helper-reset">
	<div id="filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-accordion-content-active ui-corner-top">
	  	<div id="results-collections-title">
	  		<span>' . lang::get('LANG_Filter_Title') . '</span>
    	</div>
	</div>';
        if (user_access('IForm n' . $node->nid . ' save filter')) {
            $r .= '<div id="filter-save" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active"><div id="gallery-filter-retrieve-wrapper">
<div id="gallery-filter-retrieve-image"><img
src="/' . path_to_theme() . '/css/gallery_filter.png" 
alt="Mes filtres" title="Mes filtres" /></div> <div id="gallery-filter-retrieve"></div>
</div>
   <input value="' . lang::get('LANG_Enter_Filter_Name') . '" type="text" id="gallery-filter-save-name" /><input value="' . lang::get('LANG_Save_Filter_Button') . '" type="button" id="gallery-filter-save-button" /></div>';
        }
        $r .= '<div id="filter-spec" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
	  <div class="ui-accordion ui-widget ui-helper-reset">
		<div id="name-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-name-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
	  		<div id="reset-name-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="general-filter-title">
		  		<span>' . lang::get('LANG_Name_Filter_Title') . '</span>
      		</div>
		</div>
	    <div id="name-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
	        ' . data_entry_helper::text_input(array('label' => lang::get('LANG_Name'), 'fieldname' => 'username', 'suffixTemplate' => 'nosuffix')) . '
  		</div>
		<div id="date-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-date-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
	  		<div id="reset-date-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="general-filter-title">
		  		<span>' . lang::get('LANG_Date_Filter_Title') . '</span>
      		</div>
		</div>
	    <div id="date-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
        	<label for="start_date" >' . lang::get('LANG_Created_Between') . ':</label>
  			<input type="text" size="10" id="start_date" name="start_date" value="' . lang::get('click here') . '" />
  			<input type="hidden" id="real_start_date" name="real_start_date" />
  			<label for="end_date" >' . lang::get('LANG_And') . ':</label>
  			<input type="text" size="10" id="end_date" name="end_date" value="' . lang::get('click here') . '" />
  			<input type="hidden" id="real_end_date" name="real_end_date" />
  		</div>
  		<div id="flower-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-flower-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
	  		<div id="reset-flower-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="flower-filter-title">
		  		<span>' . lang::get('LANG_Flower_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="flower-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
		  ' . data_entry_helper::select($flower_ctrl_args) . '
 		  <input type="text" name="flower:taxon_extra_info" class="taxon-info" value="' . lang::get('LANG_More_Precise') . '"
	 		onclick="if(this.value==\'' . lang::get('LANG_More_Precise') . '\'){this.value=\'\'; this.style.color=\'#000\'}"  
            onblur="if(this.value==\'\'){this.value=\'' . lang::get('LANG_More_Precise') . '\'; this.style.color=\'#555\'}" />
		  ' . str_replace("\n", "", data_entry_helper::outputAttribute($occurrence_attributes[$args['flower_type_attr_id']], $defAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($location_attributes[$args['habitat_attr_id']], $defAttrOptions)) . '
    	</div>
		<div id="insect-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-insect-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
			<div id="reset-insect-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="insect-filter-title">
		  		<span>' . lang::get('LANG_Insect_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="insect-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
		  ' . data_entry_helper::select($insect_ctrl_args) . '
 		  <input type="text" name="insect:taxon_extra_info" class="taxon-info" value="' . lang::get('LANG_More_Precise') . '"
	 		onclick="if(this.value==\'' . lang::get('LANG_More_Precise') . '\'){this.value=\'\'; this.style.color=\'#000\'}"  
            onblur="if(this.value==\'\'){this.value=\'' . lang::get('LANG_More_Precise') . '\'; this.style.color=\'#555\'}" />
		</div>
		<div id="conditions-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-conditions-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
			<div id="reset-conditions-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="conditions-filter-title">
		  		<span>' . lang::get('LANG_Conditions_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="conditions-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
    	  ' . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['sky_state_attr_id']], $defAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['temperature_attr_id']], $defAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['wind_attr_id']], $defAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['shade_attr_id']], $defAttrOptions)) . '
		</div>
		<div id="location-filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  		<div id="fold-location-button" class="ui-state-default ui-corner-all fold-button">&nbsp;</div>
			<div id="reset-location-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
			<div id="location-filter-title">
		  		<span>' . lang::get('LANG_Location_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="location-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-all">
		  <div id="location-entry">
		    ' . data_entry_helper::georeference_lookup(iform_map_get_georef_options($args)) . '
    		<span id="location-georef-notes" >' . lang::get('LANG_Georef_Notes') . '</span>
    		<label for="place:INSEE">' . lang::get('LANG_Or') . '</label>
 		    <input type="text" id="place:INSEE" name="place:INSEE" value="' . lang::get('LANG_INSEE') . '"
	 		  onclick="if(this.value==\'' . lang::get('LANG_INSEE') . '\'){this.value=\'\'; this.style.color=\'#000\'}"  
              onblur="if(this.value==\'\'){this.value=\'' . lang::get('LANG_INSEE') . '\'; this.style.color=\'#555\'}" />
    	    <input type="button" id="search-insee-button" class="ui-corner-all ui-widget-content ui-state-default search-button" value="' . lang::get('search') . '" />
 	      </div>';
        // this is a bit of a hack, because the apply_template method is not public in data entry helper.
        $tempScript = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = '';
        $r .= data_entry_helper::map_panel($options, $olOptions);
        $map1JS = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = $tempScript;
        $r .= '
		</div>
      </div>
    </div>
    <div id="filter-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
	  <div id="search-insects-button" class="ui-state-default ui-corner-all search-button">' . lang::get('LANG_Search_Insects') . '</div>
      <div id="search-collections-button" class="ui-state-default ui-corner-all search-button">' . lang::get('LANG_Search_Collections') . '</div>
    </div>
	<div id="results-collections-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	  <div id="results-collections-title">
	  	<span>' . lang::get('LANG_Collections_Search_Results') . '</span>
      </div>
	</div>
	<div id="results-collections-results" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
    </div>
	<div id="results-insects-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	  <div id="results-insects-title">
	  	<span>' . lang::get('LANG_Insects_Search_Results') . '</span>
      </div>
	</div>
	<div id="results-insects-results" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
    </div>
</div>
<div id="focus-collection" class="ui-accordion ui-widget ui-helper-reset">
	<div id="fc-header" class="ui-accordion-content ui-helper-reset ui-state-active ui-corner-top ui-accordion-content-active">
	  <div id="fc-header-buttons">';
        if (user_access('IForm n' . $node->nid . ' add preferred collection')) {
            $r .= '<span id="fc-add-preferred" class="ui-state-default ui-corner-all preferred-button">' . lang::get('LANG_Add_Preferred_Collection') . '</span>';
        }
        $r .= '  
	    <span id="fc-prev-button" class="ui-state-default ui-corner-all previous-button">' . lang::get('LANG_Previous') . '</span>
	    <span id="fc-next-button" class="ui-state-default ui-corner-all next-button">' . lang::get('LANG_Next') . '</span>
	  	<span id="fc-filter-button" class="ui-state-default ui-corner-all collection-button">' . lang::get('LANG_List') . '</span>
	  </div>
	</div>
	<div id="collection-details" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
	  <div id="flower-image-container" ><div id="flower-image" class="flower-image"></div>
        <div id="show-flower-button" class="ui-state-default ui-corner-all display-button">' . lang::get('LANG_Display') . '</div>
      </div>
      <div id="environment-image" class="environment-image"></div>
      <div id="collection-description">
	    <p id="collection-date"></p>
	    <p id="collection-flower-name"></p>
	    <p>' . lang::get($occurrence_attributes[$args['flower_type_attr_id']]['caption']) . ': <span id="collection-flower-type" class=\\"collection-value\\"></span></p>
	    <p>' . lang::get($location_attributes[$args['habitat_attr_id']]['caption']) . ': <span id="collection-habitat" class=\\"collection-value\\"></span></p>
	    <p id="collection-locality"></p>
	    <p id="collection-user-name"></p>
	    <a id="collection-user-link">' . lang::get('LANG_User_Link') . '</a>
	  </div>
      <div id="map2_container">';
        // this is a bit of a hack, because the apply_template method is not public in data entry helper.
        $tempScript = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = '';
        $r .= data_entry_helper::map_panel($options2, $olOptions);
        $map2JS = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = $tempScript;
        $r .= '</div>
    </div>
	<div id="collection-insects">
    </div>
	<div id="fc-comments-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	    <div id="fc-new-comment-button" class="ui-state-default ui-corner-all new-comment-button">' . lang::get('LANG_New_Comment') . '</div>
		<span>' . lang::get('LANG_Comments_Title') . '</span>
	</div>
	<div id="fc-new-comment" class="ui-accordion-content ui-helper-reset ui-widget-content">
		<form id="fc-new-comment-form" action="' . iform_ajaxproxy_url($node, 'smp-comment') . '" method="POST">
		    <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    		<input type="hidden" name="sample_comment:sample_id" value="" />
    		<label for="sample_comment:person_name">' . lang::get('LANG_Username') . ':</label>
		    <input type="text" name="sample_comment:person_name" value="' . $username . '" readonly="readonly" />  
    		<label for="sample_comment:email_address">' . lang::get('LANG_Email') . ':</label>
		    <input type="text" name="sample_comment:email_address" value="' . $email . '" readonly="readonly" />
		    ' . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'sample_comment:comment', 'class' => 'required', 'suffixTemplate' => 'nosuffix')) . '
    		<input type="submit" id="fc_comment_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Submit_Comment') . '" />
    	</form>
	</div>
	<div id="fc-comment-list" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	</div>
</div>
<div id="focus-occurrence" class="ui-accordion ui-widget ui-helper-reset">
	<div id="fo-header" class="ui-accordion-content ui-helper-reset ui-state-active ui-corner-top ui-accordion-content-active">
	  <div id="fo-header-buttons">
 	    <span id="fo-collection-button" class="ui-state-default ui-corner-all collection-button">' . lang::get('LANG_Collection') . '</span>
	    <span id="fo-prev-button" class="ui-state-default ui-corner-all previous-button">' . lang::get('LANG_Previous') . '</span>
	    <span id="fo-next-button" class="ui-state-default ui-corner-all next-button">' . lang::get('LANG_Next') . '</span>
	  	<span id="fo-filter-button" class="ui-state-default ui-corner-all collection-button">' . lang::get('LANG_List') . '</span>
	  </div>
	</div>
	<div id="fo-picture" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	  <div id="fo-warning"></div>
	  <div id="fo-image">
      </div>
    </div>
	<div id="fo-identification" class="ui-accordion-header ui-helper-reset ui-corner-top ui-state-active">
	  <div id="fo-id-title">
	  	<span>' . lang::get('LANG_Indentification_Title') . '</span>
      </div>
    </div>
	<div id="fo-current-id" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
	</div>
	<div id="fo-new-insect-id" class="ui-accordion-content ui-helper-reset ui-widget-content">
	  <form id="fo-new-insect-id-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST">
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" name="determination:occurrence_id" value="" />
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />  
    	<input type="hidden" name="determination:person_name" value="' . $username . '" />  
		<input type="hidden" name="determination:email_address" value="' . $email . '" />';
        if (user_access('IForm n' . $node->nid . ' insect expert')) {
            $r .= '		<select name="determination:determination_type" />
			<option value="C" selected>' . lang::get('LANG_Det_Type_C') . '</option>
			<option value="X">' . lang::get('LANG_Det_Type_X') . '</option>
		</select>';
        } else {
            $r .= '		<input type="hidden" name="determination:determination_type" value="A" />';
        }
        $r .= '		<div class="id-tool-group">
          <input type="hidden" name="determination:taxon_details" />
          <span id="insect-id-button" class="ui-state-default ui-corner-all poll-id-button" >' . lang::get('LANG_Launch_ID_Key') . '</span>
		  <span id="insect-id-cancel" class="ui-state-default ui-corner-all poll-id-cancel" >' . lang::get('LANG_Cancel_ID') . '</span>
 	      <p id="insect_taxa_list"></p>
 	    </div>
 	    <div class="id-specified-group">
 	      ' . data_entry_helper::select($focus_insect_ctrl_args) . '
          <label for="insect:taxon_extra_info" class="follow-on">' . lang::get('LANG_More_Precise') . ' </label> 
          <input type="text" id="insect:taxon_extra_info" name="determination:taxon_extra_info" class="taxon-info" />
        </div>
 	    <div class="id-comment">
          <label for="insect:comment" class="follow-on">' . lang::get('LANG_ID_Comment') . ' </label>
          <textarea id="insect:comment" name="determination:comment" class="taxon-comment" rows="5" ></textarea>
        </div>
        <input type="submit" id="insect_id_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>
    <div id="fo-new-flower-id" class="ui-accordion-content ui-helper-reset ui-widget-content">
	  <form id="fo-new-flower-id-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST">
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" name="determination:occurrence_id" value="" />
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />  
    	<input type="hidden" name="determination:person_name" value="' . $username . '" />  
		<input type="hidden" name="determination:email_address" value="' . $email . '" />';
        if (user_access('IForm n' . $node->nid . ' flower expert')) {
            $r .= '		<select name="determination:determination_type" />
			<option value="C" selected>' . lang::get('LANG_Det_Type_C') . '</option>
			<option value="X">' . lang::get('LANG_Det_Type_X') . '</option>
		</select>';
        } else {
            $r .= '		<input type="hidden" name="determination:determination_type" value="A" />';
        }
        $r .= '		<div class="id-tool-group">
          <input type="hidden" name="determination:taxon_details" />
          <span id="flower-id-button" class="ui-state-default ui-corner-all poll-id-button" >' . lang::get('LANG_Launch_ID_Key') . '</span>
		  <span id="flower-id-cancel" class="ui-state-default ui-corner-all poll-id-cancel" >' . lang::get('LANG_Cancel_ID') . '</span>
 	      <p id="flower_taxa_list" class="taxa_list" ></p>
 	    </div>
 	    <div class="id-specified-group">
 	      ' . data_entry_helper::select($focus_flower_ctrl_args) . '
          <label for="flower:taxon_extra_info" class="follow-on">' . lang::get('LANG_More_Precise') . ' </label> 
          <input type="text" id="flower:taxon_extra_info" name="determination:taxon_extra_info" class="taxon-info" />
        </div>
 	    <div class="id-comment">
          <label for="flower:comment" class="follow-on">' . lang::get('LANG_ID_Comment') . ' </label>
          <textarea id="flower:comment" name="determination:comment" class="taxon-comment" rows="5" ></textarea>
        </div>
        <input type="submit" id="flower_id_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>
	<div id="fo-express-doubt" class="ui-accordion-content ui-helper-reset ui-widget-content">
	  <form id="fo-express-doubt-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST">
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" name="determination:occurrence_id" value="" />
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />  
    	<input type="hidden" name="determination:person_name" value="' . $username . '" />  
		<input type="hidden" name="determination:email_address" value="' . $email . '" />
    	<input type="hidden" name="determination:determination_type" value="B" />
        <input type="hidden" name="determination:taxon_extra_info" />
        <input type="hidden" name="determination:taxa_taxon_list_id" />
 	    <div class="doubt-comment">
          <label for="determination:comment" class="follow-on">' . lang::get('LANG_Doubt_Comment') . ' </label>
          <textarea id="determination:comment" name="determination:comment" class="taxon-comment" rows="5" ></textarea>
        </div>
        <input type="submit" id="doubt_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>
	
	<div id="fo-id-history" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active"></div>
	<div id="fo-id-buttons" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
		<div id="fo-new-insect-id-button" class="ui-state-default ui-corner-all new-id-button">' . lang::get('LANG_New_ID') . '</div>
		<div id="fo-new-flower-id-button" class="ui-state-default ui-corner-all new-id-button">' . lang::get('LANG_New_ID') . '</div>
		<div id="fo-doubt-button" class="ui-state-default ui-corner-all doubt-button">' . lang::get('LANG_Doubt') . '</div>
    </div>	
	<div id="fo-insect-addn-info" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	    <span class="addn-info-title">' . lang::get('LANG_Additional_Info_Title') . '</span>
	    <p>' . lang::get('LANG_Date') . ': <span id="fo-insect-date"></span></p>
	    <p>' . lang::get('LANG_Time') . ': <span id="fo-insect-start-time"></span> ' . lang::get('LANG_To') . ' <span id="fo-insect-end-time"></span></p>
	    <p>' . $sample_attributes[$args['sky_state_attr_id']]['caption'] . ': <span id="fo-insect-sky"></span></p>
	    <p>' . $sample_attributes[$args['temperature_attr_id']]['caption'] . ': <span id="fo-insect-temp"></span></p>
	    <p>' . $sample_attributes[$args['wind_attr_id']]['caption'] . ': <span id="fo-insect-wind"></span></p>
	    <p>' . $sample_attributes[$args['shade_attr_id']]['caption'] . ': <span id="fo-insect-shade"></span></p>
	</div>
	<div id="fo-flower-addn-info" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	    <p>' . $occurrence_attributes[$args['flower_type_attr_id']]['caption'] . ': <span id="focus-flower-type"></span></p>
	    <p>' . $location_attributes[$args['habitat_attr_id']]['caption'] . ': <span id="focus-habitat"></span></p>
	</div>
	<div id="fo-comments-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	    <div id="fo-new-comment-button" class="ui-state-default ui-corner-all new-comment-button">' . lang::get('LANG_New_Comment') . '</div>
		<span>' . lang::get('LANG_Comments_Title') . '</span>
	</div>
	<div id="fo-new-comment" class="ui-accordion-content ui-helper-reset ui-widget-content">
		<form id="fo-new-comment-form" action="' . iform_ajaxproxy_url($node, 'occ-comment') . '" method="POST">
		    <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    		<input type="hidden" name="occurrence_comment:occurrence_id" value="" />
    		<label for="occurrence_comment:person_name">' . lang::get('LANG_Username') . ':</label>
		    <input type="text" name="occurrence_comment:person_name" value="' . $username . '" readonly="readonly" />  
    		<label for="occurrence_comment:email_address">' . lang::get('LANG_Email') . ':</label>
		    <input type="text" name="occurrence_comment:email_address" value="' . $email . '" readonly="readonly" />
		    ' . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence_comment:comment', 'class' => 'required', 'suffixTemplate' => 'nosuffix')) . '
    		<input type="submit" id="comment_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Submit_Comment') . '" />
    	</form>
	</div>
	<div id="fo-comment-list" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	</div>
</div>
';
        data_entry_helper::$javascript .= "\n// We need to leave the AJAX calls for the search alone, but abort other focus-on calls,\n// so we put a dummy REMOVEABLEJSONP in the URL, and search on that. This is ignored by the service call itself.\najaxStack = [];\nabortAjax = function()\n{\n\tjQuery('script').each(function(){\n\t\tif(this.src.indexOf('REMOVEABLEJSONP')>0){\n\t\t\tvar test = this.src.match(/jsonp\\d*/);\n\t\t\twindow[test] = function(){};\n\t\t\tjQuery(this).remove();\n\t\t}\n\t});\n\t// This deals with any non cross domain calls.\n\twhile(ajaxStack.length > 0){\n\t\tvar request = ajaxStack.shift();\n\t\tif(!(typeof request == 'undefined')) request.abort();\n\t}\n}\n\n\nalertIndiciaError = function(data){\n\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\tif(data.error){\terrorString = errorString + ' : ' + data.error;\t}\n\tif(data.errors){\n\t\tfor (var i in data.errors){\n\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t}\t\t\t\t\n\t}\n\talert(errorString);\n\t// the most likely cause is authentication failure - eg the read authentication has timed out.\n\t// prevent further use of the form:\n\tjQuery('#filter,#focus-occurrence,#focus-collection').hide();\n\tjQuery('#refresh-message').show();\n};\n\njQuery('#imp-georef-search-btn').removeClass('indicia-button').addClass('search-button');\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";\n\n// remove the (don't know) entry from flower type filter.\njQuery('[name=occAttr\\:" . $args['flower_type_attr_id'] . "]').filter('[value=" . $args['flower_type_dont_know'] . "]').parent().remove();\n \njQuery('#start_date').datepicker({\n  dateFormat : 'dd/mm/yy',\n  constrainInput: false,\n  maxDate: '0',\n  altField : '#real_start_date',\n  altFormat : 'yy-mm-dd'\n});\njQuery('#end_date').datepicker({\n  dateFormat : 'dd/mm/yy',\n  constrainInput: false,\n  maxDate: '0',\n  altField : '#real_end_date',\n  altFormat : 'yy-mm-dd'\n});\n\nmyScrollTo = function(selector){\n\tjQuery(selector).filter(':visible').each(function(){\n\t\twindow.scroll(0, jQuery(this).offset().top);\n\t});\n};\n\njQuery('#reset-name-button').click(function(){\n\tjQuery('[name=username]').val('');\n});\njQuery('#fold-name-button').click(function(){\n\tjQuery('#name-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-name-button').toggleClass('fold-button-folded');\n\tjQuery('#name-filter-body').toggleClass('ui-accordion-content-active');\n});\njQuery('#reset-date-button').click(function(){\n\tjQuery('[name=start_date]').val('" . lang::get('click here') . "');\n\tjQuery('[name=real_start_date]').val('');\n\tjQuery('[name=end_date]').val('" . lang::get('click here') . "');\n\tjQuery('[name=real_end_date]').val('');\n});\njQuery('#fold-date-button').click(function(){\n\tjQuery('#date-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-date-button').toggleClass('fold-button-folded');\n\tjQuery('#date-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#reset-flower-button').click(function(){\n\tjQuery('[name=flower\\:taxa_taxon_list_id]').val('');\n\tjQuery('[name=flower\\:taxon_extra_info]').val(\"" . lang::get('LANG_More_Precise') . "\");\n\tjQuery('#flower-filter-body').find(':checkbox').removeAttr('checked');\n});\njQuery('#fold-flower-button').click(function(){\n\tjQuery('#flower-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-flower-button').toggleClass('fold-button-folded');\n\tjQuery('#flower-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#reset-insect-button').click(function(){\n\tjQuery('[name=insect\\:taxa_taxon_list_id]').val('');\n\tjQuery('[name=insect\\:taxon_extra_info]').val(\"" . lang::get('LANG_More_Precise') . "\");\n\tjQuery('#insect-filter-body').find(':checkbox').removeAttr('checked');\n});\n\njQuery('#fold-insect-button').click(function(){\n\tjQuery('#insect-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-insect-button').toggleClass('fold-button-folded');\n\tjQuery('#insect-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#reset-conditions-button').click(function(){\n\tjQuery('#conditions-filter-body').find(':checkbox').removeAttr('checked');\n});\n\njQuery('#fold-conditions-button').click(function(){\n\tjQuery('#conditions-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-conditions-button').toggleClass('fold-button-folded');\n\tjQuery('#conditions-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#reset-location-button').click(function(){\n\tpolygonLayer.destroyFeatures();\n\tpolygonLayer.map.searchLayer.destroyFeatures();\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroyFeatures();\n\tjQuery('#imp-georef-search').val('');\n\tjQuery('[name=place\\:INSEE]').val('" . lang::get('LANG_INSEE') . "');\n\tvar div = jQuery('#map')[0];\n\tvar center = new OpenLayers.LonLat(" . $args['map_centroid_long'] . ", " . $args['map_centroid_lat'] . ");\n\tcenter.transform(div.map.displayProjection, div.map.projection);\n\tdiv.map.setCenter(center, " . (int) $args['map_zoom'] . ");\n});\njQuery('#fold-location-button').click(function(){\n\tjQuery('#location-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-location-button').toggleClass('fold-button-folded');\n\tjQuery('#location-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#flower-image').click(function(){\n\tif(jQuery('#flower-image').data('occID') != 'none'){\n\t\tloadFlower(jQuery('#flower-image').data('occID'), jQuery('#flower-image').data('collectionIndex'));\n\t}\n});\njQuery('#show-flower-button').click(function(){\n\tif(jQuery('#flower-image').data('occID') != 'none'){\n\t\tloadFlower(jQuery('#flower-image').data('occID'), jQuery('#flower-image').data('collectionIndex'));\n\t}\n});\n\njQuery('#fo-doubt-button').click(function(){\n\tjQuery('#fo-new-insect-id,#fo-new-flower-id').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-express-doubt [name=determination\\:comment]').val(\"" . lang::get('LANG_Default_Doubt_Comment') . "\");\n\tjQuery('#fo-express-doubt').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#fc-next-button,#fc-prev-button').click(function(){\n\tvar index = jQuery(this).data('index');\n\tvar id = searchResults.features[index].attributes.collection_id;\n\tloadCollection(id, index);\n});\n\njQuery('#fc-filter-button,#fo-filter-button').click(function(){\n    jQuery('#filter').show();\n\tjQuery('#focus-occurrence,#focus-collection,#results-insects-header,#results-collections-header,#results-insects-results,#results-collections-results').hide();\n    loadFilter();\n    if(searchResults != null){\n    \tif(searchResults.type == 'C')\n    \t\tjQuery('#results-collections-header,#results-collections-results').show();\n    \telse \n    \t\tjQuery('#results-insects-header,#results-insects-results').show();\n\t}\n});\n\nhtmlspecialchars = function(value){\n\treturn value.replace(/[<>\"'&]/g, function(m){return replacechar(m)})\n};\n\nreplacechar = function(match){\n\tif (match==\"<\") return \"&lt;\"\n\telse if (match==\">\") return \"&gt;\"\n\telse if (match=='\"') return \"&quot;\"\n\telse if (match==\"'\") return \"&#039;\"\n\telse if (match==\"&\") return \"&amp;\"\n};\n\nconvertDate = function(dateStr, incTime){\n\tvar retDate = '';\n\t// assume date is in in YYYY/MM/DD[+Time] format.\n\t// if language is french convert to DD/MM/YYYY[+Time] format.\n\tif('" . $args['language'] . "' == 'fr'){\n\t\tretDate = dateStr.slice(8,10)+'-'+dateStr.slice(5,7)+'-'+dateStr.slice(0,4);\n\t\tif(incTime) retDate = retDate+dateStr.slice(10);\n\t} else if(incTime)\n\t\tretDate = dateStr;\n\telse\n\t\tretDate = dateStr.slice(0,10);\n\treturn retDate;\n} \n\nloadCollection = function(id, index){\n\tabortAjax();\n    jQuery('[name=sample_comment\\:sample_id]').val(id);\n\tjQuery('#fc-add-preferred').attr('smpID', id);\n\tcollection_preferred_object.collection_id = id;\n\tjQuery('#fc-new-comment-button')." . (user_access('IForm n' . $node->nid . ' create collection comment') ? "show()" : "hide()") . ";\n    jQuery('#focus-occurrence,#filter,#fc-next-button,#fc-prev-button').hide();\n    jQuery('#focus-collection').show();\n    if(index != null){\n    \tif(index < (searchResults.features.length-1) )\n    \t\tjQuery('#fc-next-button').show().data('index', index+1);\n    \tif(index > 0)\n    \t\tjQuery('#fc-prev-button').show().data('index', index-1);\n    }\n    if(jQuery('#map2').children().length == 0) {\n    \tlocationLayer = new OpenLayers.Layer.Vector('Location Layer',{displayInLayerSwitcher: false});\n    \t" . $map2JS . "\n \t};\n    locationLayer.destroyFeatures();\n \tjQuery('#map2').width('auto');\n\tjQuery('#flower-image').data('occID', 'none').data('collectionIndex', index);\n\tjQuery('#collection-insects,#collection-date,#collection-flower-name,#collection-flower-type,#collection-habitat,#collection-user-name').empty();\n\tloadComments(id, '#fc-comment-list', 'sample_comment', 'sample_id', 'sample-comment-block', 'sample-comment-body', true);\n\t// only need to reset the timeout on the first fetch as rest follow on quickly.\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence\" +\n\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\"&sample_id=\"+id+\"&deleted=f&REMOVEABLEJSONP&callback=?\", function(flowerData) {\n   \t\tif(!(flowerData instanceof Array)){\n   \t\t\talertIndiciaError(flowerData);\n   \t\t} else if (flowerData.length>0) {\n   \t\t\tloadImage('occurrence_image', 'occurrence_id', flowerData[0].id, '#flower-image', " . $args['Flower_Image_Ratio'] . ", function(imageRecord){collection_preferred_object.flower_image_path = imageRecord.path}, 'med-', false);\n\t\t\tjQuery('#flower-image').data('occID', flowerData[0].id);\n\t\t\tcollection_preferred_object.flower_id = flowerData[0].id;\n\t\t\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\t\"&occurrence_id=\" + flowerData[0].id + \"&deleted=f&orderby=id&REMOVEABLEJSONP&callback=?\", function(detData) {\n   \t\t\t\tif(!(detData instanceof Array)){\n   \t\t\t\t\talertIndiciaError(detData);\n   \t\t\t\t} else if (detData.length>0) {\n   \t\t\t\t\tvar i = detData.length-1;\n\t\t\t\t\tvar string = '';\n\t\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\t\tstring = detData[i].taxon;\n\t\t  \t\t\t}\n\t\t\t\t\tif(detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != null){\n\t\t\t\t\t\tdetData[i].taxa_taxon_list_id_list;\n\t\t\t  \t\t\tvar resultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t\t\t\tif(resultsIDs[0] != '') {\n\t\t\t\t\t\t\tfor(var j=0; j < resultsIDs.length; j++){\n\t\t\t\t\t\t\t\tfor(k = 0; k< flowerTaxa.length; k++){\n\t\t\t\t\t\t\t\t\tif(flowerTaxa[k].id == resultsIDs[j]){\n\t\t\t\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + flowerTaxa[k].taxon;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t  \t\t}\n\t\t\t\t\t  \t}\n\t\t\t\t\t}\n\t\t  \t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\t\t\tstring = (string == '' ? '' : string + ' ') + '('+detData[i].taxon_extra_info+')';\n\t\t\t\t\t}\n\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Flower_Name') . ": <span class=\"collection-value\">'+htmlspecialchars(string)+'</span></span>').appendTo('#collection-flower-name');\n\t\t\t\t}}));\n\t\t\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence_attribute_value\"  +\n   \t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&occurrence_id=\" + flowerData[0].id + \"&iso=" . $language . "&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\t\t\tif(!(attrdata instanceof Array)){\n   \t\t\t\t\talertIndiciaError(attrdata);\n   \t\t\t\t} else if (attrdata.length>0) {\n   \t\t\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\t\t\tswitch(parseInt(attrdata[i].occurrence_attribute_id)){\n\t\t\t\t\t\t\t\tcase " . $args['flower_type_attr_id'] . ":\n\t\t\t\t\t\t\t\t\tjQuery('<span>'+attrdata[i].value+'</span>').appendTo('#collection-flower-type');\n\t\t\t\t\t\t\t\t\tbreak;\n  \t\t\t}}}}}));\n\t\t\t\t\n\t\t}\n\t}));\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample_attribute_value\"  +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&sample_id=\" + id + \"&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].sample_attribute_id)){\n\t\t\t\t\t\tcase " . $args['username_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Comment_By') . "'+attrdata[i].value+'</span>').appendTo('#collection-user-name');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase " . $args['uid_attr_id'] . ":\n\t\t\t\t\t\t\tcollection_preferred_object.user_id = attrdata[i].value\n\t\t\t       \t\t    jQuery('#collection-user-link').attr('href', '" . url('node/' . $node->nid) . "?user_id='+attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n    }}}}}));\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample/\" +id+\n\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\"&REMOVEABLEJSONP&callback=?\", function(collectionData) {\n   \t\tif(!(collectionData instanceof Array)){\n   \t\t\talertIndiciaError(collectionData);\n   \t\t} else if (collectionData.length>0) {\n\t\t\tif(collectionData[0].date_start == collectionData[0].date_end){\n\t\t\t\tcollection_preferred_object.date = collectionData[0].date_start.slice(0,10);\n\t\t\t\tjQuery('<span>'+convertDate(collectionData[0].date_start, false)+'</span>').appendTo('#collection-date');\n\t\t\t} else {\n\t\t\t\tcollection_preferred_object.date = collectionData[0].date_start.slice(0,10)+' - '+collectionData[0].date_end.slice(0,10);\n\t\t\t\tjQuery('<span>'+convertDate(collectionData[0].date_start, false)+' - '+convertDate(collectionData[0].date_end, false)+'</span>').appendTo('#collection-date');\n\t\t\t}\n\t\t\tjQuery('#poll-banner').empty().append(collectionData[0].location_name);\n\t  \t\tcollection_preferred_object.collection_name = collectionData[0].location_name;\n\t        ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/location/\" +collectionData[0].location_id +\n\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\t\t\"&REMOVEABLEJSONP&callback=?\", function(locationData) {\n   \t\t\t\tif(!(locationData instanceof Array)){\n   \t\t\t\t\talertIndiciaError(locationData);\n   \t\t\t\t} else if (locationData.length>0) {\n\t\t\t\t\tloadImage('location_image', 'location_id', locationData[0].id, '#environment-image', " . $args['Environment_Image_Ratio'] . ", function(imageRecord){collection_preferred_object.environment_image_path = imageRecord.path}, 'med-', false);\n\t\t\t\t\tvar parser = new OpenLayers.Format.WKT();\n\t\t\t\t\tvar feature = parser.read(locationData[0].centroid_geom);\n\t\t\t\t\tlocationLayer.addFeatures([feature]);\n\t\t\t\t\tvar bounds=locationLayer.getDataExtent();\n\t\t\t\t\tlocationLayer.map.setCenter(bounds.getCenterLonLat(), 13);\n\t\t\t        var filter = new OpenLayers.Filter.Spatial({\n  \t\t\t\t\t\ttype: OpenLayers.Filter.Spatial.CONTAINS ,\n    \t\t\t\t\tproperty: 'the_geom',\n    \t\t\t\t\tvalue: feature.geometry\n\t\t\t\t  \t});\n\t\t\t\t\tvar locality = jQuery('#collection-locality');\n\t\t\t\t  \tvar scope = {target: locality};\n\t\t\t\t\tinseeProtocol.read({filter: filter, callback: fillLocationDetails, scope: scope});\n\t\t\t\t}\n\t\t\t}));\n\t        ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/location_attribute_value\"  +\n   \t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&location_id=\" + collectionData[0].location_id + \"&iso=" . $language . "&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\t\t\tif(!(attrdata instanceof Array)){\n   \t\t\t\t\talertIndiciaError(attrdata);\n   \t\t\t\t} else if (attrdata.length>0) {\n\t\t\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\t\t\tswitch(parseInt(attrdata[i].location_attribute_id)){\n\t\t\t\t\t\t\t\tcase " . $args['habitat_attr_id'] . ":\n\t\t\t\t\t\t\t\t\tjQuery('<span>'+attrdata[i].value+' / </span>').appendTo('#collection-habitat');\n\t\t\t\t\t\t\t\t\tbreak;\n  \t\t\t}}}}}));\n\t\t}\n\t}));\n\t// we want to tag end of row pictuure, so we need to keep track of its position in list.\n\tcollection_preferred_object.insects = [];\n\tajaxStack.push(jQuery.ajax({\n\t\turl: \"" . $svcUrl . "/data/sample?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&REMOVEABLEJSONP&callback=?&parent_id=\"+id,\n\t\tdataType: 'json',\n\t\tmyIndex: index,\n\t\tsuccess: function(sessiondata) {\n          if(!(sessiondata instanceof Array)){\n   \t\t\talertIndiciaError(sessiondata);\n   \t\t  } else if (sessiondata.length>0) {\n   \t\t\tvar sessList=[];\n   \t\t\t// code has been changed to fetch all insects at once, so we can now go async\n\t\t\tfor (var i=0;i<sessiondata.length;i++)\n\t\t\t\tsessList.push(sessiondata[i].id);\n\t\t\t\tajaxStack.push(jQuery.ajax({\n\t\t\t\t\turl: \"" . $svcUrl . "/data/occurrence?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&deleted=f&orderby=id&REMOVEABLEJSONP&callback=?&query=\"+escape(JSON.stringify({'in': ['sample_id', sessList]})),\n\t\t\t\t\tdataType: 'json',\n\t\t\t\t\tmyIndex: this.myIndex,\n\t\t\t\t\tsuccess: function(insectData) {\n\t\t\t\t\t  if(!(insectData instanceof Array)){\n   \t\t\t\t\t\talertIndiciaError(insectData);\n   \t\t  \t\t\t  } else if (insectData.length>0) {\n\t\t\t\t\t\tfor (var j=0;j<insectData.length;j++){\n\t\t\t\t\t\t\tvar insect=jQuery('<div class=\"ui-widget-content ui-corner-all collection-insect\" />').attr('occID', insectData[j].id).appendTo('#collection-insects');\n\t\t\t\t\t\t\tif((j+1)/" . $args['insectsPerRow'] . " == parseInt((j+1)/" . $args['insectsPerRow'] . "))\n\t\t\t\t\t\t\t\tinsect.addClass('end-of-row');\n\t\t\t\t\t\t\tjQuery('<p class=\"insect-tag insect-unknown\" />').appendTo(insect);\n\t\t\t\t\t\t\tvar image = jQuery('<div class=\"insect-image empty\" />').appendTo(insect).data('occID',insectData[j].id)\n\t\t\t\t\t\t\t\t\t.data('collectionIndex',this.myIndex).click(function(){\n\t\t\t\t\t\t\t\tloadInsect(jQuery(this).data('occID'),jQuery(this).data('collectionIndex'),null,'C');\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tjQuery('<p class=\"insect-determination empty\" />').appendTo(insect);\n\t\t\t\t\t\t\tjQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>')\n\t\t\t\t\t\t\t\t\t.appendTo(insect).attr('occID',insectData[j].id).data('collectionIndex',this.myIndex).data('collectionInsectIndex',j).click(function(){\n\t\t\t\t\t\t\t\tloadInsect(jQuery(this).attr('occID'),jQuery(this).data('collectionIndex'),null,'C');\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tloadImage('occurrence_image', 'occurrence_id', insectData[j].id, image, " . $args['Insect_Image_Ratio'] . ", function(imageRecord){collection_preferred_object.insects.push({insect_id: imageRecord.occurrence_id, insect_image_path: imageRecord.path})}, 'med-',\n\t\t\t\t\t\t\t\tfunction(img){\n\t\t\t\t\t\t\t\t\tvar group = jQuery('#collection-insects').find('.collection-insect');\n\t\t\t\t\t\t\t\t\tjQuery(img).parent().removeClass('empty');\n\t\t\t\t\t\t\t\t\tif(group.find('.empty').length == 0){\n\t\t\t\t\t\t\t\t\t\tvar tallest = 0;\n\t\t\t\t\t\t\t\t\t\tgroup.each(function(){ tallest = Math.max(\$(this).height(), tallest); });\n\t\t\t\t\t\t\t\t\t\tgroup.each(function(){ \$(this).height(Math.max(\$(this).height(), tallest)); }); // have synchronicity problems.\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tajaxStack.push(jQuery.ajax({\n\t\t\t\t\t\t\t\turl: \"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t    \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\t    \t\t\t\"&occurrence_id=\" + insectData[j].id + \"&deleted=f&orderby=id&REMOVEABLEJSONP&callback=?\",\n\t\t\t\t\t\t\t\tdataType: 'json',\n\t\t\t\t\t\t\t\tmyID: insectData[j].id,\n\t\t\t\t\t\t\t\tsuccess: function(detData) {\n   \t\t\t\t\t\t\t\t  if(!(detData instanceof Array)){\n   \t\t\t\t\t\t\t\t\talertIndiciaError(detData);\n   \t\t  \t\t\t  \t\t\t  } else {\n   \t\t  \t\t\t  \t\t\t   if (detData.length>0) {\n\t\t\t\t\t    \t\t\tvar insect = jQuery('.collection-insect').filter('[occID='+detData[0].occurrence_id+']');\n\t\t\t\t\t    \t\t\tvar tag = insect.find('.insect-tag');\n\t\t\t\t\t    \t\t\tvar det = insect.find('.insect-determination');\n\t\t\t\t\t\t\t\t\tvar i = detData.length-1;\n\t\t\t\t\t\t\t\t\tvar string = '';\n\t\t\t\t\t\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\t\t\t\t\t\tstring = detData[i].taxon;\n\t\t\t\t\t\t  \t\t\t}\n\t\t\t\t\t\t\t\t\tif(detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != null){\n\t\t\t\t\t\t\t\t\t\tdetData[i].taxa_taxon_list_id_list;\n\t\t\t\t\t\t\t\t\t  \tvar resultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t\t\t\t\t\t\t\tif(resultsIDs[0] != '') {\n\t\t\t\t\t\t\t\t\t\t\tfor(var j=0; j < resultsIDs.length; j++){\n\t\t\t\t\t\t\t\t\t\t\t\tfor(var k = 0; k< insectTaxa.length; k++){\n\t\t\t\t\t\t\t\t\t\t\t\t\tif(insectTaxa[k].id == resultsIDs[j]){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + insectTaxa[k].taxon;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t  \t\t}\n\t\t\t\t\t\t\t\t\t}\t\n\t\t\t\t\t\t\t\t\tif(string != '')\n\t\t\t\t\t\t\t\t\t\tjQuery('<div><p>" . lang::get('LANG_Last_ID') . ":</p><p><strong>'+string+'</strong></p></div>').addClass('insect-id').appendTo(det);\n\t\t\t\t\t\t\t\t\tif(detData[i].determination_type == 'B' || detData[i].determination_type == 'I' || detData[i].determination_type == 'U'){\n\t\t\t\t\t\t\t\t\t\ttag.removeClass('insect-unknown').addClass('insect-dubious');\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\ttag.removeClass('insect-unknown').addClass('insect-ok');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t   }\n\t\t\t\t\t\t\t\t\tvar group = jQuery('#collection-insects').find('.collection-insect');\n\t\t\t\t\t\t\t\t\tgroup.filter('[occID='+this.myID+']').find('.insect-determination').removeClass('empty');\n\t\t\t\t\t\t\t\t\tif(group.find('.empty').length == 0){\n\t\t\t\t\t\t\t\t\t\tvar tallest = 0;\n\t\t\t\t\t\t\t\t\t\tgroup.each(function(){ tallest = Math.max(\$(this).height(), tallest); });\n\t\t\t\t\t\t\t\t\t\tgroup.each(function(){ \$(this).height(Math.max(\$(this).height(), tallest)); }); // have synchronicity problems.\n\t\t\t\t\t\t\t}}}}));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t  }})); \n\t\t\t}}\n\t    }));\n\tmyScrollTo('#poll-banner');\n};\nfillLocationDetails = function(a1)\n{\n\tjQuery(this.target).empty();\n\tcollection_preferred_object.location_description = '';\n\tif(a1.features.length > 0) {\n\t   \tvar text = a1.features[0].attributes.NOM+' ('+a1.features[0].attributes.INSEE_NEW+'), '+a1.features[0].attributes.DEPT_NOM+' ('+a1.features[0].attributes.DEPT_NUM+'), '+a1.features[0].attributes.REG_NOM+' ('+a1.features[0].attributes.REG_NUM+')';\n\t\tcollection_preferred_object.location_description = text;\n\t   \tjQuery('<span>'+text+'</span>').appendTo(this.target);\n  }\n}\naddCollection = function(index, attributes, geom, first){\n\t// first the text, then the flower and environment picture, then the small insect pictures, then the afficher button\n\tvar collection=jQuery('<div class=\"ui-widget-content ui-corner-all filter-collection\" />').appendTo('#results-collections-results');\n\tvar details = jQuery('<div class=\"collection-details\" />').appendTo(collection); \n\tvar flower = jQuery('<div class=\"collection-image collection-flower\" />').data('occID', attributes.flower_id).\n\t\tdata('collectionIndex', index).click(function(){\n\t\t\tloadFlower(jQuery(this).data('occID'), jQuery(this).data('collectionIndex'));\n\t});\n\tvar filter = new OpenLayers.Filter.Spatial({\n  \t\t\ttype: OpenLayers.Filter.Spatial.CONTAINS ,\n    \t\tproperty: 'the_geom',\n    \t\tvalue: geom\n  \t});\n\tflower.appendTo(collection);\n\tinsertImage('med-'+attributes.image_de_la_fleur, flower, " . $args['Flower_Image_Ratio'] . ", false);\n\tvar location = jQuery('<div class=\"collection-image collection-environment\" />').appendTo(collection);\n\tinsertImage('med-'+attributes.image_de_environment, location, " . $args['Environment_Image_Ratio'] . ", false);\n\tjQuery('<div class=\"collection-photoreel\"></div>').attr('collID', attributes.collection_id).appendTo(collection);\n\tvar displayButtonContainer = jQuery('<div class=\"collection-buttons\"></div>').appendTo(collection);\n\tjQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>').click(function(){\n\t\tloadCollection(jQuery(this).data('value'), jQuery(this).data('index'));\n\t}).appendTo(displayButtonContainer).data('value',attributes.collection_id).data('index',index);\n\tif(attributes.datedebut == attributes.datefin){\n\t  jQuery('<p class=\"collection-date\">'+convertDate(attributes.datedebut,false)+'</p>').appendTo(details);\n    } else {\n\t  jQuery('<p class=\"collection-date\">'+convertDate(attributes.datedebut,false)+' - '+convertDate(attributes.datefin,false)+'</p>').appendTo(details);\n    }\n\tjQuery('<p class=\"collection-name\">'+attributes.nom+'</p>').appendTo(details);\n\tvar locality = jQuery('<p  class=\"collection-locality\"></p>').appendTo(details);\n\tvar scope = {target: locality};\n\tinseeProtocol.read({filter: filter, callback: fillLocationDetails, scope: scope});\n\tjQuery.getJSON(\"" . $svcUrl . "/data/sample?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + (first ? \"&reset_timeout=true\" : \"\") + \"&callback=?&parent_id=\"+attributes.collection_id,\n        function(sessiondata) {\n\t\t  if(!(sessiondata instanceof Array)){\n   \t\t\talertIndiciaError(sessiondata);\n   \t\t  } else for (var i=0;i<sessiondata.length;i++){\n   \t\t  \tvar photoreel = jQuery('.collection-photoreel').filter('[collID='+sessiondata[i].parent_id+']');\n   \t\t  \tjQuery('<span class=\"photoreel-session\"></span>').attr('sessID', sessiondata[i].id).appendTo(photoreel);\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&orderby=id\" +\n\t\t\t\t\t\"&sample_id=\"+sessiondata[i].id+\"&deleted=f&callback=?\", function(insectData) {\n\t\t    \tif(!(insectData instanceof Array)){\n   \t\t\t\t\talertIndiciaError(insectData);\n   \t\t\t\t} else if (insectData.length>0) {\n \t\t\t\t\tfor (var j=0;j<insectData.length;j++){\n\t\t\t\t\t\tvar container = jQuery('<div/>').addClass('thumb').attr('occID', insectData[j].id.toString()).data('collectionIndex',index).click(function () {\n\t\t\t\t\t\t\tloadInsect(jQuery(this).attr('occID'),jQuery(this).data('collectionIndex'),null,'P');\n\t\t\t\t\t\t});\n\t\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Unknown') . "</span>').addClass('thumb-text').appendTo(container);\n\t\t\t\t\t\tjQuery('.photoreel-session').filter('[sessID='+insectData[j].sample_id+']').append(container);\n\t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_image\" +\n\t\t\t\t\t   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\t\t\t\"&occurrence_id=\" + insectData[j].id + \"&callback=?\", function(imageData) {\n\t\t\t\t\t\t\t  if(!(imageData instanceof Array)){\n   \t\t\t\t\t\t\t\talertIndiciaError(imageData);\n   \t\t\t\t\t\t\t  } else if (imageData.length>0) {\n\t\t\t\t\t\t      \tvar container = jQuery('.thumb').filter('[occID='+imageData[0].occurrence_id.toString()+']');\n\t\t\t\t\t\t\t    var img = new Image();\n\t\t\t\t\t\t\t    // thumbs are fixed in size, and small - dont worry about ratios\n\t\t\t\t\t\t\t\tjQuery(img).attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "thumb-'+imageData[0].path)\n\t\t\t    \t\t\t\t\t.attr('width', container.width()).attr('height', container.height()).addClass('thumb-image').appendTo(container);\n\t\t\t\t\t\t\t  }}); \n\t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t    \t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\t    \t\t\"&occurrence_id=\" + insectData[j].id + \"&orderby=id&deleted=f&callback=?\", function(detData) {\n\t\t\t\t\t\t      if(!(detData instanceof Array)){\n   \t\t\t\t\t\t\t\talertIndiciaError(detData);\n   \t\t\t\t\t\t\t  } else if (detData.length>0) {\n\t\t\t\t\t\t        var container = jQuery('.thumb').filter('[occID='+detData[0].occurrence_id.toString()+']');\n\t\t\t\t\t\t        if(detData[detData.length-1].determination_type == 'B' || detData[detData.length-1].determination_type == 'I' || detData[detData.length-1].determination_type == 'U'){\n\t\t\t\t\t\t        \tcontainer.find('.thumb-text').remove();\n\t\t\t\t\t\t        \tjQuery('<span>" . lang::get('LANG_Dubious') . "</span>').addClass('thumb-text').appendTo(container);\n\t\t\t\t\t\t\t  \t} else {\n\t\t\t\t\t\t\t\t\tcontainer.find('.thumb-text').remove();\n\t\t\t\t\t\t\t  \t}\n  \t\t\t\t\t\t}});  \t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t}});\n\t\t}});\n};\naddInsect = function(index, attributes, endOfRow, first){\n\tvar container=jQuery('<div class=\"ui-widget-content ui-corner-all filter-insect\" />').attr('occID',attributes.insect_id).appendTo('#results-insects-results');\n\tif(endOfRow) container.addClass('end-of-row');\n\tjQuery('<div />').addClass('insect-unknown').appendTo(container); // flag\n\tvar insect = jQuery('<div class=\"insect-image empty\" />').data('occID',attributes.insect_id).data('insectIndex',index).click(function(){\n\t\tloadInsect(jQuery(this).data('occID'), null, jQuery(this).data('insectIndex'), 'S');\n\t});\n\tinsect.appendTo(container);\n\tjQuery('<div class=\"insect-determinationX empty\" />').attr('occID',attributes.insect_id).appendTo(container).append(\"<p>" . lang::get('LANG_No_Determinations') . "</p>\");\n\tinsertImage('med-'+attributes.image_d_insecte, insect, " . $args['Insect_Image_Ratio'] . ", function(img){\n\t\t\tvar group = jQuery('#results-insects-results').find('.filter-insect');\n\t\t\tjQuery(img).parent().removeClass('empty');\n\t\t\tif(group.find('.empty').length == 0){\n\t\t\t\tvar tallest = 0;\n\t\t\t\tgroup.each(function(){ tallest = Math.max(\$(this).height(), tallest); });\n\t\t\t\tgroup.each(function(){ \$(this).height(Math.max(\$(this).height(), tallest)); }); // have synchronicity problems.\n\t\t\t}\n\t\t});\n\tjQuery.ajax({\n\t\turl: \"" . $svcUrl . "/data/determination?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + (first ? \"&reset_timeout=true\" : \"\") + \"&orderby=id&callback=?&occurrence_id=\" + attributes.insect_id,\n\t\tdataType: 'json',\n\t\tmyID: attributes.insect_id,\n\t\tsuccess: function(detData) {\n   \t\t  if(!(detData instanceof Array)){\n   \t\t\talertIndiciaError(detData);\n   \t\t  } else {\n   \t\t   if (detData.length>0) {\n\t\t\tvar i = detData.length-1;\n   \t\t\tvar string = '';\n\t\t\tvar determination = jQuery('.insect-determinationX').filter('[occID='+detData[i].occurrence_id+']').empty();\n\t\t\tvar flag = determination.parent().find('.insect-unknown');\n\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\tstring = detData[i].taxon;\n\t\t\t}\n\t\t\tif(detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != null && detData[i].taxa_taxon_list_id_list != '{}'){\n\t\t\t\tdetData[i].taxa_taxon_list_id_list;\n\t\t\t\tvar resultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t\tif(resultsIDs[0] != '') {\n\t\t\t\t\tfor(var j=0; j < resultsIDs.length; j++){\n\t\t\t\t\t\tfor(var k = 0; k< insectTaxa.length; k++){\n\t\t\t\t\t\t\tif(insectTaxa[k].id == resultsIDs[j]){\n\t\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + insectTaxa[k].taxon;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tjQuery('<p>'+string+'</p>').appendTo(determination)\n\t\t\tif(detData[i].determination_type == 'B' || detData[i].determination_type == 'I' || detData[i].determination_type == 'U'){\n\t\t\t\tflag.removeClass('insect-unknown').addClass('insect-dubious');\n\t\t\t} else \n\t\t\t\tflag.removeClass('insect-unknown').addClass('insect-ok');\n\t\t   }\n\t\t   var group = jQuery('#results-insects-results').find('.filter-insect');\n\t\t   group.filter('[occID='+this.myID+']').find('.insect-determinationX').removeClass('empty');\n\t\t   if(group.find('.empty').length == 0){\n\t\t\t\tvar tallest = 0;\n\t\t\t\tgroup.each(function(){ tallest = Math.max(\$(this).height(), tallest); });\n\t\t\t\tgroup.each(function(){ \$(this).height(Math.max(\$(this).height(), tallest)); }); // have synchronicity problems.\n\t\t   \n  \t\t  }}\n\t}});\n\tjQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>').click(function(){\n\t\tloadInsect(jQuery(this).attr('occID'), null, jQuery(this).data('insectIndex'), 'S');\n\t}).appendTo(container).attr('occID',attributes.insect_id).data('insectIndex',index);\n};\n\n\nsetCollectionPage = function(pageNum){\n\tvar no_units = 4;\n\tvar no_tens = 2;\n\tvar no_hundreds = 1;\n\tjQuery('#results-collections-results').empty();\n\tvar numPages = Math.ceil(searchResults.features.length/" . $args['collectionsPerPage'] . ");\n\tif(numPages > 1) {\n\t\tvar item;\n\t\tvar itemList = jQuery('<div class=\"item-list\"></div>').appendTo('#results-collections-results');\n\t\tvar pageCtrl = jQuery('<ul>').addClass('pager').appendTo(itemList);\n\t\tfor (var j = pageNum - no_units; j<= pageNum + no_units; j++){\n\t\t\tif(j <= numPages && j >= 1){\n\t\t\t\tif(j == pageNum)\n\t\t\t\t\tjQuery('<li class=\"pager-current\">'+pageNum+'</li>').appendTo(pageCtrl);\n\t\t\t\telse {\n\t\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t\t}\n  \t\t\t}\n\t\t}\n\t\tvar start = Math.ceil(j/10)*10;\n\t\tfor (j = start; j< start + no_tens*10; j=j+10){\n\t\t\tif(j <= numPages){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tstart = Math.ceil(j/100)*100;\n\t\tfor (j = start; j< start + no_hundreds*100; j=j+100){\n\t\t\tif(j <= numPages){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tif(pageNum != numPages){\n\t\t\titem = jQuery('<li class=\"pager-next\"></li>').attr('value',pageNum+1).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t\titem = jQuery('<li class=\"pager-last\"></li>').attr('value',numPages).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">'+numPages+'</a>').appendTo(item);\n  \t\t}\n\t\tstart = Math.floor((pageNum - no_units -1)/10)*10;\n\t\tfor (j = start; j> start - no_tens*10; j=j-10){\n\t\t\tif(j >= 1){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tstart = Math.floor(j/100)*100;\n\t\tfor (j = start; j> start - no_hundreds*100; j=j-100){\n\t\t\tif(j >= 1){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tif(pageNum != 1){\n\t\t\titem = jQuery('<li class=\"pager-previous\"></li>').attr('value',pageNum-1).click(function(){setCollectionPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t\titem = jQuery('<li class=\"pager-first\"></li>').click(function(){setCollectionPage(1)}).prependTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t}\n  \t\tpageCtrl.find('li').filter(':first').addClass('first');\n  \t\tpageCtrl.find('li').filter(':last').addClass('last');\n\t}\n    for (var i = (pageNum-1)*" . $args['collectionsPerPage'] . ", first = true; i < searchResults.features.length && i < pageNum*" . $args['collectionsPerPage'] . "; i++, first = false){\n\t\taddCollection(i, searchResults.features[i].attributes,searchResults.features[i].geometry, first);\n\t}\n\tif(numPages > 1) {\n\t\titemList.clone(true).appendTo('#results-collections-results');\n\t}\n}\nsetInsectPage = function(pageNum){\n\tjQuery('#results-insects-results').empty();\n\tvar numPages = Math.ceil(searchResults.features.length/(" . $args['insectsRowsPerPage'] . "*" . $args['insectsPerRow'] . "));\n\tvar no_units = 4;\n\tvar no_tens = 2;\n\tvar no_hundreds = 1;\n\tif(numPages > 1) {\n\t\tvar item;\n\t\tvar itemList = jQuery('<div class=\"item-list\"></div>').appendTo('#results-insects-results');\n\t\tvar pageCtrl = jQuery('<ul>').addClass('pager').appendTo(itemList);\n\t\tfor (var j = pageNum - no_units; j<= pageNum + no_units; j++){\n\t\t\tif(j <= numPages && j >= 1){\n\t\t\t\tif(j == pageNum)\n\t\t\t\t\tjQuery('<li class=\"pager-current\">'+pageNum+'</li>').appendTo(pageCtrl);\n\t\t\t\telse {\n\t\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t\t}\n  \t\t\t}\n\t\t}\n\t\tvar start = Math.ceil(j/10)*10;\n\t\tfor (j = start; j< start + no_tens*10; j=j+10){\n\t\t\tif(j <= numPages){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tstart = Math.ceil(j/100)*100;\n\t\tfor (j = start; j< start + no_hundreds*100; j=j+100){\n\t\t\tif(j <= numPages){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tif(pageNum != numPages){\n\t\t\titem = jQuery('<li class=\"pager-next\"></li>').attr('value',pageNum+1).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t\titem = jQuery('<li class=\"pager-last\"></li>').attr('value',numPages).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">'+numPages+'</a>').appendTo(item);\n  \t\t}\n\t\tstart = Math.floor((pageNum - no_units -1)/10)*10;\n\t\tfor (j = start; j> start - no_tens*10; j=j-10){\n\t\t\tif(j >= 1){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tstart = Math.floor(j/100)*100;\n\t\tfor (j = start; j> start - no_hundreds*100; j=j-100){\n\t\t\tif(j >= 1){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tif(pageNum != 1){\n\t\t\titem = jQuery('<li class=\"pager-previous\"></li>').attr('value',pageNum-1).click(function(){setInsectPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t\titem = jQuery('<li class=\"pager-first\"></li>').click(function(){setInsectPage(1)}).prependTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t}\n  \t\tpageCtrl.find('li').filter(':first').addClass('first');\n  \t\tpageCtrl.find('li').filter(':last').addClass('last');\n\t}\n    for (var i = (pageNum-1)*" . $args['insectsRowsPerPage'] . "*" . $args['insectsPerRow'] . ", first = true; i < searchResults.features.length && i < pageNum*" . $args['insectsRowsPerPage'] . "*" . $args['insectsPerRow'] . "; i++, first = false){\n\t\taddInsect(i, searchResults.features[i].attributes, (i+1)/" . $args['insectsPerRow'] . " == parseInt((i+1)/" . $args['insectsPerRow'] . "), first);\n\t}\n\tif(numPages > 1) {\n\t\titemList.clone(true).appendTo('#results-insects-results');\n\t}\n}\n\n// searchLayer in map is used for georeferencing.\n// map editLayer is switched off. TODO: need to switch off click control\nsearchLayer = null;\ninseeLayer = null;\npolygonLayer = null;     \nlocationLayer = null;\ninseeProtocol = new OpenLayers.Protocol.WFS({\n              url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n              featurePrefix: '" . $args['INSEE_prefix'] . "',\n              featureType: '" . $args['INSEE_type'] . "',\n              geometryName:'the_geom',\n              featureNS: '" . $args['INSEE_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0'                  \n      \t\t  ,propertyNames: ['NOM', 'INSEE_NEW', 'DEPT_NUM', 'DEPT_NOM', 'REG_NUM', 'REG_NOM']\n});\n\n\nflowerIDstruc = {\n\ttype: 'flower',\n\tmainForm: 'form#fo-new-flower-id-form',\n\ttimeOutTimer: null,\n\tpollTimer: null,\n\tpollFile: '',\n\tinvokeURL: '" . $args['ID_tool_flower_url'] . "',\n\tpollURL: '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['ID_tool_flower_poll_dir']) . "',\n\tname: 'flowerIDstruc',\n\tdeterminationType: '" . (user_access('IForm n' . $node->nid . ' flower expert') ? 'C' : 'A') . "',\n\ttaxaList: flowerTaxa\n};\n\ntoolPoller = function(toolStruct){\n\tif(toolStruct.pollFile == '') return;\n\ttoolStruct.pollTimer = setTimeout('toolPoller('+toolStruct.name+');', " . $args['ID_tool_poll_interval'] . ");\n\tjQuery.ajax({\n\t url: toolStruct.pollURL+toolStruct.pollFile,\n\t toolStruct: toolStruct,\n\t success: function(data){\n\t  pollReset(this.toolStruct);\n\t  var da = data.split('\\n');\n      jQuery(this.toolStruct.mainForm+' [name=determination\\:taxon_details]').val(da[2]); // Stores the state of identification, which details how the identification was arrived at within the tool.\n\t  da[1] = da[1].replace(/\\\\\\\\i\\{\\}/g, '').replace(/\\\\\\\\i0\\{\\}/g, '').replace(/\\\\/g, '');\n\t  var items = da[1].split(':');\n\t  var count = items.length;\n\t  if(items[count-1] == '') count--;\n\t  if(items[count-1] == '') count--;\n\t  if(count <= 0){\n\t  \t// no valid stuff so blank it all out.\n\t  \tjQuery('#'+this.toolStruct.type+'_taxa_list').append(\"" . lang::get('LANG_Taxa_Unknown_In_Tool') . "\");\n\t  \tjQuery(this.toolStruct.mainForm+' [name=determination\\:determination_type]').val('X'); // Unidentified.\n      } else {\n      \tvar resultsIDs = [];\n      \tvar resultsText = \"" . lang::get('LANG_Taxa_Returned') . "<br />{ \";\n      \tvar notFound = '';\n\t\tfor(var j=0; j < count; j++){\n\t\t\tvar found = false;\n\t\t\titemText = items[j].replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\t\t\tfor(i = 0; i< this.toolStruct.taxaList.length; i++){\n\t\t\t\tif(this.toolStruct.taxaList[i].taxon == itemText){\n\t\t\t\t\tresultsIDs.push(this.toolStruct.taxaList[i].id);\n\t\t\t\t\tresultsText = resultsText + (j == 0 ? '' : '<br />&nbsp;&nbsp;') + itemText;\n\t\t\t\t\tfound = true;\n  \t\t\t\t}\n  \t\t\t};\n  \t\t\tif(!found){\n  \t\t\t\tnotFound = (notFound == '' ? '' : notFound + ', ') + itemText;\n  \t\t\t}\n  \t\t}\n\t\tjQuery('#'+this.toolStruct.type+'_taxa_list').append(resultsText+ ' }');\n\t\tjQuery('#'+this.toolStruct.type+'-id-button').data('toolRetValues', resultsIDs);\n\t  \tif(notFound != ''){\n\t\t\tvar comment = jQuery(this.toolStruct.mainForm+' [name=determination\\:comment]');\n\t\t\tcomment.val('" . lang::get('LANG_ID_Unrecognised') . " '+notFound+' '+comment.val());\n\t\t}\n  \t  }\n  \t }\n    });\n};\n\npollReset = function(toolStruct){\n\tclearTimeout(toolStruct.timeOutTimer);\n\tclearTimeout(toolStruct.pollTimer);\n\tjQuery('#'+toolStruct.type+'-id-cancel').hide();\n\tjQuery('#'+toolStruct.type+'-id-button').show();\n\ttoolStruct.pollFile='';\n\ttoolStruct.timeOutTimer = null;\n\ttoolStruct.pollTimer = null;\n};\n\nidButtonPressed = function(toolStruct){\n\tjQuery(toolStruct.mainForm+' [name=determination\\:determination_type]').val(toolStruct.determinationType);\n\tjQuery('#'+toolStruct.type+'-id-button').data('toolRetValues', []);\n\tjQuery(toolStruct.mainForm+' [name=determination\\:taxon_details]').val('');\n\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\tjQuery(toolStruct.mainForm+' [name=determination\\:taxa_taxon_list_id]').val('');\n\tjQuery('#'+toolStruct.type+'-id-cancel').show();\n\tjQuery('#'+toolStruct.type+'-id-button').hide();\n\tvar d = new Date;\n\tvar s = d.getTime();\n\ttoolStruct.pollFile = '" . session_id() . "_'+s.toString()\n\tclearTimeout(toolStruct.timeOutTimer);\n\tclearTimeout(toolStruct.pollTimer);\n\twindow.open(toolStruct.invokeURL+toolStruct.pollFile,'','');\n\ttoolStruct.pollTimer = setTimeout('toolPoller('+toolStruct.name+');', " . $args['ID_tool_poll_interval'] . ");\n\ttoolStruct.timeOutTimer = setTimeout('toolReset('+toolStruct.name+');', " . $args['ID_tool_poll_timeout'] . ");\n};\njQuery('#flower-id-button').click(function(){\n\tidButtonPressed(flowerIDstruc);\n});\njQuery('#flower-id-cancel').click(function(){\n\tpollReset(flowerIDstruc);\n});\n\njQuery('#flower-id-cancel').hide();\n\ntaxonChosen = function(toolStruct){\n\tjQuery('#'+toolStruct.type+'-id-button').data('toolRetValues', []);\n\tjQuery(toolStruct.mainForm+' [name=determination\\:taxon_details]').val('');\n\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\tjQuery(toolStruct.mainForm+' [name=determination\\:comment]').val('');\n  \tjQuery(toolStruct.mainForm+' [name=determination\\:determination_type]').val(toolStruct.determinationType);\n};\njQuery('form#fo-new-flower-id-form select[name=determination\\:taxa_taxon_list_id]').change(function(){\n\tpollReset(flowerIDstruc);\n\ttaxonChosen(flowerIDstruc);\n});\n\ninsectIDstruc = {\n\ttype: 'insect',\n\tmainForm: 'form#fo-new-insect-id-form',\n\ttimeOutTimer: null,\n\tpollTimer: null,\n\tpollFile: '',\n\tinvokeURL: '" . $args['ID_tool_insect_url'] . "',\n\tpollURL: '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['ID_tool_insect_poll_dir']) . "',\n\tname: 'insectIDstruc',\n\tdeterminationType: '" . (user_access('IForm n' . $node->nid . ' insect expert') ? 'C' : 'A') . "',\n\ttaxaList: insectTaxa\n};\n\njQuery('#insect-id-button').click(function(){\n\tidButtonPressed(insectIDstruc);\n});\njQuery('#insect-id-cancel').click(function(){\n\tpollReset(insectIDstruc);\n});\njQuery('#insect-id-cancel').hide();\njQuery('form#fo-new-insect-id-form select[name=determination\\:taxa_taxon_list_id]').change(function(){\n\tpollReset(insectIDstruc);\n\ttaxonChosen(insectIDstruc);\n});\n\njQuery('#search-insee-button').click(function(){\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroy();\n\tpolygonLayer.map.searchLayer.destroyFeatures();\n\tpolygonLayer.destroyFeatures();\n\tvar filters = [];\n  \tvar place = jQuery('input[name=place\\:INSEE]').val();\n  \tif(place == '" . lang::get('LANG_INSEE') . "') return;\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_NEW',\n    \t\tvalue: place\n  \t\t}));\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_OLD',\n    \t\tvalue: place\n  \t\t}));\n\n\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\tvar styleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Red\",\n                    strokeColor: \"Red\",\n                    fillOpacity: 0,\n                    strokeWidth: 1\n                  })\n\t});\n\tinseeLayer = new OpenLayers.Layer.Vector('INSEE Layer', {\n\t\t  styleMap: styleMap,\n          strategies: [strategy],\n          displayInLayerSwitcher: false,\n\t      protocol: new OpenLayers.Protocol.WFS({\n              url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n\t          featurePrefix: '" . $args['INSEE_prefix'] . "',\n              featureType: '" . $args['INSEE_type'] . "',\n              geometryName:'the_geom',\n              featureNS: '" . $args['INSEE_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0'                  \n      \t\t  ,propertyNames: ['the_geom']\n  \t\t\t})\n    });\n\tinseeLayer.events.register('featuresadded', {}, function(a1){\n\t\tvar div = jQuery('#map')[0];\n\t\tdiv.map.searchLayer.destroyFeatures();\n\t\tvar bounds=inseeLayer.getDataExtent();\n    \tvar dy = (bounds.top-bounds.bottom)/10;\n    \tvar dx = (bounds.right-bounds.left)/10;\n    \tbounds.top = bounds.top + dy;\n    \tbounds.bottom = bounds.bottom - dy;\n    \tbounds.right = bounds.right + dx;\n    \tbounds.left = bounds.left - dx;\n    \t// if showing a point, don't zoom in too far\n    \tif (dy===0 && dx===0) {\n    \t\tdiv.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n    \t} else {\n    \t\tdiv.map.zoomToExtent(bounds);\n    \t}\n    });\n\tinseeLayer.events.register('loadend', {}, function(){\n\t\tif(inseeLayer.features.length == 0){\n\t\t\talert(\"" . lang::get('LANG_NO_INSEE') . "\");\n\t\t}\n    });\n    jQuery('#map')[0].map.addLayer(inseeLayer);\n\tstrategy.load({filter: new OpenLayers.Filter.Logical({\n\t\t\t      type: OpenLayers.Filter.Logical.OR,\n\t\t\t      filters: filters\n\t\t  \t  })});\n});\n\njQuery('#search-collections-button').click(function(){\n\tjQuery('#results-insects-header,#results-insects-results').hide();\n\tjQuery('#results-collections-header,#results-collections-results').show();\n\tjQuery('#results-collections-header').addClass('ui-state-active').removeClass('ui-state-default');\n\trunSearch(true);\n});\njQuery('#search-insects-button').click(function(){\n\tjQuery('#results-collections-header,#results-collections-results').hide();\n\tjQuery('#results-insects-header,#results-insects-results').show();\n\tjQuery('#results-insects-header').addClass('ui-state-active').removeClass('ui-state-default');\n\trunSearch(false);\n});\n\ncombineOR = function(ORgroup){\n\tif(ORgroup.length > 1){\n\t\treturn new OpenLayers.Filter.Logical({\n\t\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\t\tfilters: ORgroup\n\t\t\t});\n\t}\n\treturn ORgroup[0];\n};\n\nencodeMap = function(){\n\tvar features = [];\n\tif(inseeLayer != null && inseeLayer.features.length > 0)\n\t\tfeatures = inseeLayer.features;\n\telse if(polygonLayer != null && polygonLayer.features.length > 0)\n\t\tfeatures = polygonLayer.features\n\telse {\n\t\tvar mapBounds = jQuery('#map')[0].map.getExtent();\n\t\tvar feature = new OpenLayers.Feature.Vector(mapBounds.toGeometry());\n\t\tfeatures = [feature];\n\t}\n      var format=new OpenLayers.Format.GML.v2({featureName: 'user', featureType: 'user',\n          featureNS: 'user', featurePrefix: 'user'});\n      return format.write(features);\n    }\n\ndecodeMap = function(string){\n      var format=new OpenLayers.Format.GML.v2({featureName: 'user', featureType: 'user',\n          featureNS: 'user', featurePrefix: 'user'});\n      var features=format.read(string);\n\tif(inseeLayer != null) inseeLayer.destroyFeatures();\n\tif(polygonLayer!= null) polygonLayer.destroyFeatures();\n\tvar div = jQuery('#map')[0];\n\tdiv.map.searchLayer.destroyFeatures();\n\tpolygonLayer.addFeatures(features, {});\n\tvar bounds= polygonLayer.getDataExtent();\n    div.map.zoomToExtent(bounds);\n\n}\n    \nrunSearch = function(forCollections){\n  \tvar ORgroup = [];\n  \tif(searchLayer != null)\n\t\tsearchLayer.destroy();\n    jQuery('#results-collections-results,#results-insects-results').empty();\n\tjQuery('#focus-occurrence,#focus-collection').hide();\n\tvar filters = [];\n\n\t// By default restrict selection to area displayed on map. When using the georeferencing system the map searchLayer\n\t// will contain a single point zoomed in appropriately.\n\tvar mapBounds = jQuery('#map')[0].map.getExtent();\n\tif (mapBounds != null) filters.push(new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.BBOX, property: 'geom', value: mapBounds}));\n\t// should only be one entry in the inseeLayer\n\tif(inseeLayer != null)\n  \t\tif(inseeLayer.features.length > 0)\n\t\t\tfilters.push(new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.WITHIN, property: 'geom',value: inseeLayer.features[0].geometry}));\n\tif(polygonLayer != null)\n  \t\tif(polygonLayer.features.length > 0){\n  \t\t\tORgroup = [];\n  \t\t\tfor(i=0; i< polygonLayer.features.length; i++)\n\t\t\t\tORgroup.push(new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.WITHIN, property: 'geom', value: polygonLayer.features[i].geometry}));\n\t\t  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n\t\t}\n\n  \t// filters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'survey_id', value: '" . $args['survey_id'] . "' }));\n\n  \tvar user = jQuery('input[name=username]').val();\n  \tif(user != '') filters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'username', value: user}));\n  \tvar start_date = jQuery('input[name=real_start_date]').val();\n  \tvar end_date = jQuery('input[name=real_end_date]').val();\n  \tif(start_date != '" . lang::get('click here') . "' && start_date != '')\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO, property: 'datefin', value: start_date}));\n  \tif(end_date != '" . lang::get('click here') . "' && end_date != '')\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO, property: 'datedebut', value: end_date}));\n \t\n  \tvar flower = jQuery('select[name=flower\\:taxa_taxon_list_id]').val();\n  \tif(flower != '') filters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'flower_taxon_ids', value: '*|'+flower+'|*'}));\n  \tflower = jQuery('[name=flower\\:taxon_extra_info]').val();\n  \tif(flower != '' && flower != '" . lang::get('LANG_More_Precise') . "')\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'taxons_fleur_precise', value: '*'+flower+'*' }));\n\n  \tORgroup = [];\n  \tjQuery('#flower-filter-body').find('[name^=occAttr:" . $args['flower_type_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'flower_type_id', value: elem.value}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \tORgroup = [];\n  \tjQuery('#flower-filter-body').find('[name^=locAttr:" . $args['habitat_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'habitat_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n\n  \tvar insect = jQuery('select[name=insect\\:taxa_taxon_list_id]').val();\n  \tif(insect != '') filters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'insect_taxon_ids', value: '*|'+insect+'|*'}));\n  \tinsect = jQuery('[name=insect\\:taxon_extra_info]').val();\n  \tif(insect != '' && insect != '" . lang::get('LANG_More_Precise') . "')\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'taxons_insecte_precise', value: '*'+insect+'*'}));\n\n  \tORgroup = [];\n  \tjQuery('#conditions-filter-body').find('[name^=smpAttr:" . $args['sky_state_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'sky_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \t\n  \tORgroup = [];\n  \tjQuery('#conditions-filter-body').find('[name^=smpAttr:" . $args['temperature_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'temp_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \t\n  \tORgroup = [];\n  \tjQuery('#conditions-filter-body').find('[name^=smpAttr:" . $args['wind_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'wind_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \t\n  \tORgroup = [];\n  \tjQuery('#conditions-filter-body').find('[name^=smpAttr:" . $args['shade_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'shade_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \tif(forCollections){\n\t\tproperties = ['collection_id','datedebut','datefin','geom','nom','image_de_environment','image_de_la_fleur','flower_id']\n\t\tfeature = 'spipoll_collections_cache_view';\n  \t} else {\n  \t\tfeature = 'spipoll_insects_cache_view';\n  \t\tproperties = ['insect_id','collection_id','geom','image_d_insecte'];\n  \t}\n\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\tsearchLayer = new OpenLayers.Layer.Vector('Search Layer', {\n          strategies: [strategy],\n          displayInLayerSwitcher: false,\n\t      protocol: new OpenLayers.Protocol.WFS({\n              url: '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['search_url']) . "',\n              featurePrefix: '" . $args['search_prefix'] . "',\n              featureType: feature,\n              geometryName:'geom',\n              featureNS: '" . $args['search_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0',   \n              maxFeatures: " . $args['max_features'] . ",\n              propertyNames: properties,\n              sortBy: 'datedebut' // not supported by Openlayers, so have to use orderby in a DB view.\n\t\t  })\n\t});\n\tif(forCollections) {\n\t\tjQuery('#results-collections-results').empty().append('<div class=\"collection-loading-panel\" ><img src=\"" . helper_config::$base_url . "media/images/ajax-loader2.gif\" />" . lang::get('loading') . "...</div>');\n\t\tsearchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tsearchResults = a1;\n\t\t\tsearchResults.type = 'C';\n\t\t\tif(searchResults.features.length >= " . $args['max_features'] . "){\n\t\t\t\talert(\"" . lang::get('LANG_Max_Features_Reached') . "\");\n\t\t\t}\n\t\t\tsetCollectionPage(1);\n\t\t});\n\t\tsearchLayer.events.register('loadend', {}, function(){\n\t\t\tif(searchLayer.features.length == 0){\n\t\t\t\tjQuery('#results-collections-results').empty().text('" . lang::get('LANG_No_Collection_Results') . "');\n\t\t\t}\n\t\t});\n\t} else {\n\t\tjQuery('#results-insects-results').empty().append('<div class=\"insect-loading-panel\" ><img src=\"" . helper_config::$base_url . "media/images/ajax-loader2.gif\" />" . lang::get('loading') . "...</div>');\n\t\tsearchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tsearchResults = a1;\n\t\t\tsearchResults.type = 'I';\n\t\t\tif(searchResults.features.length >= " . $args['max_features'] . "){\n\t\t\t\talert(\"" . lang::get('LANG_Max_Features_Reached') . "\");\n\t\t\t}\n\t\t\tsetInsectPage(1);\n\t\t});\n\t\tsearchLayer.events.register('loadend', {}, function(){\n\t\t\tif(searchLayer.features.length == 0){\n\t\t\t\tjQuery('#results-insects-results').empty().text('" . lang::get('LANG_No_Insect_Results') . "');\n\t\t\t}\n\t\t});\n\t}\n\tjQuery('#map')[0].map.addLayer(searchLayer);\n\tstrategy.load({filter: new OpenLayers.Filter.Logical({\n\t\t\t      type: OpenLayers.Filter.Logical.AND,\n\t\t\t      filters: filters\n\t\t  \t  })});\n};\n\nsearchResults = null;  \ncollection = '';\n\nerrorPos = null;\nclearErrors = function(formSel) {\n\tjQuery(formSel).find('.inline-error').remove();\n\terrorPos = null;\n};\n\nmyScrollToError = function(){\n\tjQuery('.inline-error,.error').filter(':visible').prev().each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\n\nvalidateRequiredField = function(name, formSel){\n    var control = jQuery(formSel).find('[name='+name+']');\n    if(control.val() == '') {\n        var label = \$('<p/>')\n\t\t\t\t.attr({'for': name})\n\t\t\t\t.addClass('inline-error')\n\t\t\t\t.html(\$.validator.messages.required);\n\t\tlabel.insertBefore(control);\n\t\treturn false;\n    }\n    return true;\n}\n\nvar insect_alert_object = {\n\tinsect_id: null,\n\tinsect_image_path: null,\n\tdate: null,\n\tuser_id: null,\n\tcollection_user_id: null,\n\tdetails: []\n};\nvar flower_alert_object = {\n\tflower_id: null,\n\tflower_image_path: null,\n\tdate: null,\n\tuser_id: null,\n\tcollection_user_id: null,\n\tdetails: []\n};\n\nvar collection_preferred_object = {\n\tcollection_id: null,\n\tcollection_name: null,\n\tflower_id: null,\n\tflower_image_path: null,\n\tenvironment_image_path: null,\n\tdate: null,\n\tlocation_description: null,\n\tuser_id: null,\n\tinsects: []\n};\n\njQuery('form#fo-express-doubt-form').ajaxForm({\n\tasync: false,\n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif(!confirm(\"" . lang::get('LANG_Confirm_Express_Doubt') . "\")){\n\t\t\treturn FALSE;\n\t\t}\t\n\t\tvar toolValues = jQuery('#fo-doubt-button').data('toolRetValues');\n\t\tif(toolValues.length == 0)\n\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: ''});\n\t\telse {\n\t\t\tfor(var i = 0; i<toolValues.length; i++){\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: toolValues[i]});\n\t\t\t}\n\t\t}\n  \t\tjQuery('#doubt_submit_button').addClass('loading-button');\n   \t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('#fo-express-doubt').removeClass('ui-accordion-content-active');\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id', insect_alert_object.insect_id == null ? 'form#fo-new-flower-id-form' : 'form#fo-new-insect-id-form', function(args, type){\n\t\t\t";
        if ($args['alert_js_function'] != '') {
            data_entry_helper::$javascript .= "\n\t\t\t\tif(type == 'F'){\n\t\t\t\t\tflower_alert_object.details = [];\n\t\t\t\t\tfor(i=0; i< args.length && i < 5; i++){\n\t\t\t\t\t\tflower_alert_object.details.push({flower_taxa: args[i].taxa, date: args[i].date, user_id: args[i].user_id});\n\t\t\t\t\t\tflower_alert_object.date = flower_alert_object.details[0].date;\n\t\t\t\t\t}\n\t\t\t\t\tflower_alert_object.details = JSON.stringify(flower_alert_object.details);\n\t\t\t\t\t" . $args['alert_js_function'] . "({alert_type: 'D', type: 'F', flower: flower_alert_object});\n\t\t\t\t} else {\n\t\t\t\t\tinsect_alert_object.details = [];\n\t\t\t\t\tfor(i=0; i< args.length && i < 5; i++){\n\t\t\t\t\t\tinsect_alert_object.details.push({insect_taxa: args[i].taxa, date: args[i].date, user_id: args[i].user_id});\n\t\t\t\t\t\tinsect_alert_object.date = insect_alert_object.details[0].date;\n\t\t\t\t\t}\n\t\t\t\t\tinsect_alert_object.details = JSON.stringify(insect_alert_object.details);\n\t\t\t\t\t" . $args['alert_js_function'] . "({alert_type: 'D', type: 'I', insect: insect_alert_object});\n\t\t\t\t}";
        }
        data_entry_helper::$javascript .= "\n\t\t\t}, insect_alert_object.insect_id == null ? " . (user_access('IForm n' . $node->nid . ' flower expert') ? '1' : '0') . " : " . (user_access('IForm n' . $node->nid . ' insect expert') ? '1' : '0') . ",\n\t\t\tinsect_alert_object.insect_id == null ? " . (user_access('IForm n' . $node->nid . ' flag dubious flower') ? '1' : '0') . " : " . (user_access('IForm n' . $node->nid . ' flag dubious insect') ? '1' : '0') . ",\n\t\t\tinsect_alert_object.insect_id == null ? flowerTaxa : insectTaxa,\n\t\t\tinsect_alert_object.insect_id == null ? 'F' : 'I');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t},\n\tcomplete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t} \n});\n\njQuery('form#fo-new-insect-id-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tvar valid = true;\n\t\tclearErrors('form#fo-new-insect-id-form');\n\t\tif (!jQuery('form#fo-new-insect-id-form input').valid()) { valid = false; }\n\t\tif (jQuery('form#fo-new-insect-id-form [name=determination\\:taxon_details]').val() == ''){\n\t\t\tif (!validateRequiredField('determination\\:taxa_taxon_list_id', '#fo-new-insect-id-form')) {\n\t\t\t\tvalid = false;\n  \t\t\t} else {\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: ''});\n  \t\t\t}\n\t\t} else {\n\t\t\tvar toolValues = jQuery('#insect-id-button').data('toolRetValues');\n\t\t\tfor(var i = 0; i<toolValues.length; i++){\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: toolValues[i]});\n\t\t\t}\t\t\t\n\t\t}\n   \t\tif ( valid == false ) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n  \t\tjQuery('#insect_id_submit_button').addClass('loading-button');\n   \t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery(insectIDstruc.mainForm+' [name=determination\\:determination_type]').val(insectIDstruc.determinationType);\n\t\t\tjQuery(insectIDstruc.mainForm+' [name=determination\\:taxa_taxon_list_id],[name=determination\\:comment],[name=determination\\:taxon_details],[name=determination\\:taxon_extra_info]').val('');\n\t\t\tjQuery('#insect_taxa_list').empty();\n\t\t\tjQuery('#fo-new-insect-id').removeClass('ui-accordion-content-active');\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id', 'form#fo-new-insect-id-form', function(args, type){\n\t\t\t";
        if ($args['alert_js_function'] != '') {
            data_entry_helper::$javascript .= "\n\t\t\t\tinsect_alert_object.details = [];\n\t\t\t\tfor(i=0; i< args.length && i < 5; i++){\n\t\t\t\t\tinsect_alert_object.details.push({insect_taxa: args[i].taxa, date: args[i].date, user_id: args[i].user_id});\n\t\t\t\t\tinsect_alert_object.date = insect_alert_object.details[0].date;\n\t\t\t\t}\n\t\t\t\tinsect_alert_object.details = JSON.stringify(insect_alert_object.details);\n\t\t\t\t" . $args['alert_js_function'] . "({alert_type: 'R', type: 'I', insect: insect_alert_object});";
        }
        data_entry_helper::$javascript .= "\n\t\t\t  \t\t\t}, " . (user_access('IForm n' . $node->nid . ' insect expert') ? '1' : '0') . ", " . (user_access('IForm n' . $node->nid . ' flag dubious insect') ? '1' : '0') . ", insectTaxa, 'I');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t},\n\tcomplete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n\t\n});\njQuery('form#fo-new-flower-id-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tvar valid = true;\n\t\tclearErrors('form#fo-new-flower-id-form');\n\t\tif (!jQuery('form#fo-new-flower-id-form input').valid()) { valid = false; }\n\t\tif (jQuery('form#fo-new-flower-id-form [name=determination\\:taxon_details]').val() == ''){\n\t\t\tif (!validateRequiredField('determination\\:taxa_taxon_list_id', '#fo-new-flower-id-form')) {\n\t\t\t\tvalid = false;\n  \t\t\t} else {\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: ''});\n  \t\t\t}\n\t\t} else {\n\t\t\tvar toolValues = jQuery('#flower-id-button').data('toolRetValues');\n\t\t\tfor(var i = 0; i<toolValues.length; i++){\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: toolValues[i]});\n\t\t\t}\t\t\t\n\t\t}\n   \t\tif ( valid == false ) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n  \t\tjQuery('#flower_id_submit_button').addClass('loading-button');\n   \t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery(flowerIDstruc.mainForm+' [name=determination\\:determination_type]').val(flowerIDstruc.determinationType);\n\t\t\tjQuery(flowerIDstruc.mainForm+' [name=determination\\:taxa_taxon_list_id],[name=determination\\:comment],[name=determination\\:taxon_details],[name=determination\\:taxon_extra_info]').val('');\n\t\t\tjQuery('#flower_taxa_list').empty();\n\t\t\tjQuery('#fo-new-flower-id').removeClass('ui-accordion-content-active');\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id', 'form#fo-new-flower-id-form', function(args, type){\n\t\t\t";
        if ($args['alert_js_function'] != '') {
            data_entry_helper::$javascript .= "\n\t\t\t\tflower_alert_object.details = [];\n\t\t\t\tfor(i=0; i< args.length && i < 5; i++) {\n\t\t\t\t\tflower_alert_object.details.push({flower_taxa: args[i].taxa, date: args[i].date, user_id: args[i].user_id});\n\t\t\t\t\tflower_alert_object.date = flower_alert_object.details[0].date;\n\t\t\t\t}\n\t\t\t\tflower_alert_object.details = JSON.stringify(flower_alert_object.details);\n\t\t\t\t" . $args['alert_js_function'] . "({alert_type: 'R', type: 'F', flower: flower_alert_object});";
        }
        data_entry_helper::$javascript .= "\n\t\t\t  \t\t\t}, " . (user_access('IForm n' . $node->nid . ' flower expert') ? '1' : '0') . ", " . (user_access('IForm n' . $node->nid . ' flag dubious flower') ? '1' : '0') . ", flowerTaxa, 'F');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t},\n\tcomplete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n\t\n});\njQuery('#fo-new-comment-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n\t// success identifies the function to invoke when the server response \n\t// has been received \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fo-new-comment-form').valid()) { return false; }\n\t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('[name=occurrence_comment\\:comment]').val('');\n\t\t\tjQuery('#fo-new-comment').removeClass('ui-accordion-content-active');\n\t\t\tloadComments(jQuery('[name=occurrence_comment\\:occurrence_id]').val(), '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body', true);\n  \t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('#fc-new-comment-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fc-new-comment-form').valid()) { return false; }\n\t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('[name=sample_comment\\:comment]').val('');\n\t\t\tjQuery('#fc-new-comment').removeClass('ui-accordion-content-active');\n\t\t\tloadComments(jQuery('[name=sample_comment\\:sample_id]').val(), '#fc-comment-list', 'sample_comment', 'sample_id', 'sample-comment-block', 'sample-comment-body', true);\n  \t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\n\nloadSampleAttributes = function(keyValue){\n    jQuery('#fo-insect-start-time,#fo-insect-end-time,#fo-insect-sky,#fo-insect-temp,#fo-insect-wind,#fo-insect-shade').empty();\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample_attribute_value\"  +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&sample_id=\" + keyValue + \"&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id && (attrdata[i].iso == null || attrdata[i].iso == '' || attrdata[i].iso == '" . $language . "')){\n\t\t\t\t\tswitch(parseInt(attrdata[i].sample_attribute_id)){\n\t\t\t\t\t\tcase " . $args['start_time_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-start-time').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase " . $args['end_time_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-end-time').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['sky_state_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-sky').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['temperature_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-temp').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['wind_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-wind').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['shade_attr_id'] . ":\n  \t\t\t\t\t\t\tif(attrdata[i].value == '1'){\n\t\t\t\t\t\t\t\tjQuery('#fo-insect-shade').append(\"" . lang::get('Yes') . "\");\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery('#fo-insect-shade').append(\"" . lang::get('No') . "\");\n  \t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}));\n}\nloadOccurrenceAttributes = function(keyValue){\n    jQuery('#focus-flower-type').empty();\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence_attribute_value\"  +\n\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&occurrence_id=\" + keyValue + \"&iso=" . $language . "&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].occurrence_attribute_id)){\n\t\t\t\t\t\tcase " . $args['flower_type_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('<span>'+attrdata[i].value+'</span>').appendTo('#focus-flower-type');\n\t\t\t\t\t\t\tbreak;\n  \t}}}}}));\n}\nloadLocationAttributes = function(keyValue){\n    jQuery('#focus-habitat').empty();\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/location_attribute_value\"  +\n\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&location_id=\" + keyValue + \"&iso=" . $language . "&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n   \t\t\tvar habitat_string = '';\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].location_attribute_id)){\n\t\t\t\t\t\tcase " . $args['habitat_attr_id'] . ":\n\t\t\t\t\t\t\thabitat_string = (habitat_string == '' ? attrdata[i].value : (habitat_string + ' | ' + attrdata[i].value));\n\t\t\t\t\t\t\tbreak;\n\t\t\t}}}\n\t\t\tjQuery('<span>'+habitat_string+'</span>').appendTo('#focus-habitat');\n  }}));\n}\n\ninsertImage = function(path, target, ratio, callback){\n    var img = new Image();\n\tjQuery(img).load(function () {\n        target.append(this);\n        if(this.width/this.height > ratio){\n\t    \tjQuery(this).css('width', '100%').css('height', 'auto').css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n  \t\t} else {\n\t        jQuery(this).css('width', (100*this.width/(this.height*ratio))+'%').css('height', 'auto').css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n  \t\t}\n  \t\tif(callback)\n  \t\t\tcallback(this);\n\t}).attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "'+path);\n}\n\nloadImage = function(imageTable, key, keyValue, target, imageRatio, callback, prepend, imgCallback){\n    jQuery(target).empty();\n    ajaxStack.push(jQuery.ajax({ \n        type: \"GET\",\n        myTarget: target,\n        myCallback: callback,\n        myPrepend: prepend,\n        myImgCallback: imgCallback,\n        url: \"" . $svcUrl . "/data/\" + imageTable +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&REMOVEABLEJSONP&callback=?\", \n        success: function(imageData) {\n\t\t  if(!(imageData instanceof Array)){\n   \t\t\talertIndiciaError(imageData);\n   \t\t  } else if (imageData.length>0) {\n \t\t\tinsertImage(this.myPrepend+imageData[0].path, jQuery(this.myTarget), imageRatio, this.myImgCallback);\n\t\t\tif(this.myCallback) this.myCallback(imageData[0]);\n\t\t  }},\n\t\tdataType: 'json'\n\t}));\n}\n\nloadDeterminations = function(keyValue, historyID, currentID, lookup, callback, expert, can_doubt, taxaList, type){\n    jQuery(historyID).empty().append('<strong>" . lang::get('LANG_History_Title') . "</strong>');\n\tjQuery(currentID).empty();\n\tjQuery('#poll-banner').empty();\n\tjQuery('#fo-doubt-button').hide();\n\tjQuery('#fo-express-doubt-form').find('[name=determination:taxon_extra_info]').val('');\n\tjQuery('#fo-express-doubt-form').find('[name=determination:taxa_taxon_list_id]').val('');\n\tjQuery('#fo-doubt-button').data('toolRetValues',[]);\n\tjQuery('.poll-id-button').data('toolRetValues',[]);\n\tjQuery('#fo-warning').addClass('occurrence-ok').removeClass('occurrence-dubious').removeClass('occurrence-unknown');\n\tjQuery('.taxa_list').empty();\n    ajaxStack.push(jQuery.ajax({ \n        type: \"GET\", \n        url: \"" . $svcUrl . "/data/determination?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&reset_timeout=true&orderby=id&REMOVEABLEJSONP&callback=?&occurrence_id=\" + keyValue,\n        myCurrentID: currentID,\n        myHistoryID: historyID,\n        myCallback: callback,\n        myLookup: lookup,\n\t\tdataType: 'json',\n        success: function(detData) {\n   \t\t  var callbackArgs = [];\n   \t\t  if(!(detData instanceof Array)){\n   \t\t\talertIndiciaError(detData);\n   \t\t  } else if (detData.length>0) {\n\t\t\tvar i = detData.length-1;\n\t\t\tvar callbackEntry = {date: detData[i].updated_on, user_id: detData[i].cms_ref, taxa: []};\n   \t\t\tjQuery('#fo-express-doubt-form').find('[name=determination\\:occurrence_id]').val(detData[i].occurrence_id);\n   \t\t\tvar string = '';\n   \t\t\tvar resultsText = \"" . lang::get('LANG_Taxa_Returned') . "<br />{ \";\n\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\tstring = detData[i].taxon;\n\t\t\t\tcallbackEntry.taxa.push(detData[i].taxon);\n  \t\t\t}\n\t\t\tjQuery('#fo-express-doubt-form').find('[name=determination\\:taxa_taxon_list_id]').val(detData[i].taxa_taxon_list_id);\n\t\t\tjQuery(this.myLookup).find('[name=determination:taxa_taxon_list_id]').val(detData[i].taxa_taxon_list_id);\n\t\t\tif(detData[i].taxa_taxon_list_id_list != null && detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != '{}'){\n\t\t\t  \tresultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t  \tfor(j=0; j < resultsIDs.length; j++){\n\t\t\t\t\tfor(k = 0; k< taxaList.length; k++)\n\t\t\t\t\t\tif(taxaList[k].id == resultsIDs[j]) {\n\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + taxaList[k].taxon;\n\t\t\t\t\t\t\tcallbackEntry.taxa.push(taxaList[k].taxon);\n\t\t\t\t\t\t\tresultsText = resultsText + (j == 0 ? '' : '<br />&nbsp;&nbsp;') + taxaList[k].taxon;\n  \t\t\t\t\t\t}\n\t\t  \t\t}\n\t  \t\t\tif(resultsIDs.length>1 || resultsIDs[0] != '') {\n\t\t\t\t\tjQuery('#fo-doubt-button').data('toolRetValues',resultsIDs);\n\t\t\t\t\tjQuery('.poll-id-button').data('toolRetValues',resultsIDs);\n\t\t\t\t\tjQuery('.taxa_list').append(resultsText+ ' }');\n\t\t\t\t}\n\t\t\t}\n\t\t\tcallbackArgs.push(callbackEntry);\n\t\t\tjQuery('#poll-banner').append(string);\n\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\tstring = (string == '' ? '' : string + ' ') + '('+detData[i].taxon_extra_info+')';\n\t\t\t}\n\t\t\tjQuery('#fo-express-doubt-form').find('[name=determination\\:taxon_extra_info]').val(detData[i].taxon_extra_info);\n\t\t\tjQuery(this.myLookup).find('[name=determination:taxon_extra_info]').val(detData[i].taxon_extra_info);\n\t\t\tif(string != '')\n\t\t\t\tjQuery('<p><strong>'+string+ '</strong> " . lang::get('LANG_Comment_By') . "' + detData[i].person_name + ' ' + convertDate(detData[i].updated_on,false) + '</p>').appendTo(this.myCurrentID)\n\t\t\telse\n\t\t\t\tjQuery('<p>" . lang::get('LANG_Comment_By') . "' + detData[i].person_name + ' ' + convertDate(detData[i].updated_on,false) + '</p>').appendTo(this.myCurrentID)\n\t\t\tif(detData[i].determination_type == 'A' && (expert || can_doubt)){\n\t\t\t\tjQuery('#fo-doubt-button').show();\n\t\t\t} else if(detData[i].determination_type == 'B'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Doubt_Expressed') . "</p>\").appendTo(this.myCurrentID);\n\t\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-dubious');\n\t\t\t} else if(detData[i].determination_type == 'C'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Valid') . "</p>\").appendTo(this.myCurrentID);\n\t\t\t\tif(!expert)\n\t\t\t\t\tjQuery('.new-id-button').hide();\n\t\t\t} else if(detData[i].determination_type == 'I'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Incorrect') . "</p>\").appendTo(this.myCurrentID);\n\t\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-dubious');\n\t\t\t} else if(detData[i].determination_type == 'U'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Unconfirmed') . "</p>\").appendTo(this.myCurrentID);\n\t\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-dubious');\n\t\t\t} else if(detData[i].determination_type == 'X'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Unknown') . "</p>\").appendTo(this.myCurrentID);\n//\t\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-unknown');\n\t\t\t}\n\t\t\tif(detData[i].comment != '' && detData[i].comment != null){\n\t\t\t\tjQuery('<p>'+detData[i].comment+'</p>').appendTo(this.myCurrentID);\n\t\t\t}\n\t\t\t\n\t\t\tfor(i=detData.length - 2; i >= 0; i--){ // deliberately miss last one, in reverse order\n\t\t\t\tcallbackEntry = {date: detData[i].updated_on, user_id: detData[i].cms_ref, taxa: []};\n\t\t\t\tstring = '';\n\t\t\t\tvar item = jQuery('<div></div>').addClass('history-item').appendTo(this.myHistoryID);\n\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\tstring = detData[i].taxon;\n\t\t  \t\t\tcallbackEntry.taxa.push(detData[i].taxon);\n  \t\t\t\t}\n\t\t\t\tif(detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != null && detData[i].taxa_taxon_list_id_list != '{}'){\n\t\t\t\t\tvar resultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t\t\tfor(j=0; j < resultsIDs.length; j++){\n\t\t\t\t\t\tfor(k = 0; k< taxaList.length; k++)\n\t\t\t\t\t\t\tif(taxaList[k].id == resultsIDs[j]) {\n\t\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + taxaList[k].taxon;\n\t\t\t\t\t\t\t\tcallbackEntry.taxa.push(taxaList[k].taxon);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\t\tstring = (string == '' ? '' : string + ' ') + '('+detData[i].taxon_extra_info+')' ;\n\t\t\t\t}\n\t\t\t\tstring = convertDate(detData[i].updated_on,false) + ' : ' + string;\n\t\t\t\tjQuery('<p><strong>'+string+ '</strong> " . lang::get('LANG_Comment_By') . "' + detData[i].person_name+'</p>').appendTo(item)\n\t\t\t\tif(detData[i].determination_type == 'B'){\n\t\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Doubt_Expressed') . "</p>\").appendTo(item)\n\t\t\t\t} else if(detData[i].determination_type == 'I'){\n\t\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Incorrect') . "</p>\").appendTo(item)\n\t\t\t\t} else if(detData[i].determination_type == 'U'){\n\t\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Unconfirmed') . "</p>\").appendTo(item)\n\t\t\t\t} else if(detData[i].determination_type == 'X'){\n\t\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Unknown') . "</p>\").appendTo(item)\n\t\t\t\t}\n\t\t\t\tif(detData[i].comment != '' && detData[i].comment != null){\n\t\t\t\t\tjQuery('<p>'+detData[i].comment+'</p>').appendTo(item);\n\t\t\t\t}\n\t\t\t\tcallbackArgs.push(callbackEntry);\n  \t\t\t}\n\t\t\t\n\t\t  } else {\n\t\t\tjQuery('#fo-doubt-button').hide();\n\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-unknown');\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Determinations') . "</p>')\n\t\t\t\t\t.appendTo(this.myHistoryID);\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Determinations') . "</p>')\n\t\t\t\t\t.appendTo(this.myCurrentID);\n\t\t  }\n\t\t  if(this.myCallback) this.myCallback(callbackArgs, type);\n\t\t}  \n\t}));\n\t// when the occurrence is loaded (eg in loadInsect) all determination:occurrence_ids are set.\n\tjQuery(lookup).find('[name=determination\\:determination_type]').val(expert ? 'C' : 'A');\n};\n\nloadComments = function(keyValue, block, table, key, blockClass, bodyClass, reset_timeout){\n    jQuery(block).empty();\n    ajaxStack.push(jQuery.ajax({ \n        type: \"GET\",\n        url: \"" . $svcUrl . "/data/\" + table + \"?mode=json&view=list\" +\n        \t(reset_timeout ? \"&reset_timeout=true\" : \"\") + \"&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&REMOVEABLEJSONP&callback=?\", \n        myBlock: block,\n        myBlockClass: blockClass,\n        myBodyClass: bodyClass,\n\t\tdataType: 'json',\n        success: function(commentData) {\n   \t\t  if(!(commentData instanceof Array)){\n   \t\t\talertIndiciaError(commentData);\n   \t\t  } else if (commentData.length>0) {\n   \t\t\tfor(i=commentData.length - 1; i >= 0; i--){\n\t   \t\t\tvar newCommentDetails = jQuery('<div class=\"'+this.myBlockClass+'\"/>')\n\t\t\t\t\t.appendTo(block);\n\t\t\t\tjQuery('<span>" . lang::get('LANG_Comment_By') . "' + commentData[i].person_name + ' ' + convertDate(commentData[i].updated_on,false) + '</span>')\n\t\t\t\t\t.appendTo(newCommentDetails);\n\t   \t\t\tvar newComment = jQuery('<div class=\"'+bodyClass+'\"/>')\n\t\t\t\t\t.appendTo(this.myBlock);\n\t\t\t\tjQuery('<p>' + commentData[i].comment + '</p>')\n\t\t\t\t\t.appendTo(newComment);\n\t\t\t}\n\t\t  } else {\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Comments') . "</p>')\n\t\t\t\t\t.appendTo(this.myBlock);\n\t\t  }\n\t\t}\n    }));\n};\n\ncollectionProcessing = function(keyValue, expert){\n    ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample_attribute_value\"  +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&sample_id=\" + keyValue + \"&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].sample_attribute_id)){\n\t\t\t\t\t\tcase " . $args['uid_attr_id'] . ":\n\t\t\t\t\t\t\tinsect_alert_object.collection_user_id = attrdata[i].value;\n\t\t\t\t\t\t\tflower_alert_object.collection_user_id = attrdata[i].value;\n\t\t\t\t\t\t\tif(!expert && parseInt(attrdata[i].value) != " . $uid . ")\n\t\t\t\t\t\t\t\tjQuery('.new-id-button').hide();\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n    }));\n}\n\nloadInsectAddnInfo = function(keyValue, collectionIndex){\n    // TODO convert buttons into thumbnails\n\tcollection = '';\t\n\t// fetch occurrence details first to get the sample_id.\n\t// Get the sample to get the parent_id.\n\t// get all the samples (sessions) with the same parent_id;\n\t// fetch all the occurrences of the sessions.\n    ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" + keyValue +\n   \t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&REMOVEABLEJSONP&callback=?\", function(occData) {\n   \t\tif(!(occData instanceof Array)){\n   \t\t\talertIndiciaError(occData);\n   \t\t} else if (occData.length > 0) {\n            ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample/\" + occData[0].sample_id +\n   \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&REMOVEABLEJSONP&callback=?\", function(smpData) {\n   \t\t\t\tif(!(smpData instanceof Array)){\n   \t\t\t\t\talertIndiciaError(smpData);\n   \t\t\t\t} else if (smpData.length > 0) {\n   \t\t\t\t\tcollection = smpData[0].parent_id;\n\t\t\t\t\tcollectionProcessing(collection, " . (user_access('IForm n' . $node->nid . ' insect expert') ? "true" : "false") . ");\n\t\t\t\t\tjQuery('#fo-insect-date').empty().append(convertDate(smpData[0].date_start,false));\n\t\t\t\t\tloadSampleAttributes(smpData[0].id);\n\t\t\t\t\tjQuery('#fo-collection-button').data('smpID',smpData[0].parent_id).data('collectionIndex', collectionIndex).show();\n  \t\t\t\t}\n   \t\t   \t  }));\n   \t\t}\n    }));\n}\nloadFlowerAddnInfo = function(keyValue, collectionIndex){\n    // fetch occurrence details first to get the collection id.\n    loadOccurrenceAttributes(keyValue);\n    ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" + keyValue +\n   \t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&REMOVEABLEJSONP&callback=?\", function(occData) {\n   \t\tif(!(occData instanceof Array)){\n   \t\t\talertIndiciaError(occData);\n   \t\t} else if (occData.length > 0) {\n\t\t\tjQuery('#fo-collection-button').data('smpID',occData[0].sample_id).data('collectionIndex',collectionIndex).show();\n\t\t\tcollectionProcessing(occData[0].sample_id, " . (user_access('IForm n' . $node->nid . ' flower expert') ? "true" : "false") . ");\n            ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample/\" + occData[0].sample_id +\n   \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&REMOVEABLEJSONP&callback=?\", function(collection) {\n   \t\t\t\tif(!(collection instanceof Array)){\n   \t\t\t\t\talertIndiciaError(collection);\n   \t\t\t\t} else if (collection.length > 0) {\n\t\t\t\t\tloadLocationAttributes(collection[0].location_id);\n  \t\t\t\t}\n   \t\t   \t  }));\n   \t\t}\n    }));\n}\n\nloadInsect = function(insectID, collectionIndex, insectIndex, type){\n    abortAjax();\n\tjQuery('#fo-prev-button,#fo-next-button').hide();\n\tjQuery('#fo-filter-button').show();\n\tif(type == 'S'){ // called from search\n\t\tif(insectIndex > 0)\n\t\t\tjQuery('#fo-prev-button').show().data('occID', searchResults.features[insectIndex-1].attributes.insect_id).data('collectionIndex', null).data('insectIndex', insectIndex-1).data('type', 'S');\n\t\tif(insectIndex < searchResults.features.length-1)\n\t\t\tjQuery('#fo-next-button').show().data('occID', searchResults.features[insectIndex+1].attributes.insect_id).data('collectionIndex', null).data('insectIndex', insectIndex+1).data('type', 'S');\n\t} else if(type == 'C'){ // called from collection\n\t\tjQuery('#fo-filter-button').hide();\n\t\tvar myThumb = jQuery('.collection-insect').filter('[occID='+insectID+']').prev();\n\t\tif(myThumb.length > 0)\n\t\t\tjQuery('#fo-prev-button').show().data('occID', myThumb.attr('occID')).data('collectionIndex', collectionIndex).data('insectIndex', null).data('type', 'C');\n\t\tmyThumb = jQuery('.collection-insect').filter('[occID='+insectID+']').next();\n\t\tif(myThumb.length > 0)\n\t\t\tjQuery('#fo-next-button').show().data('occID', myThumb.attr('occID')).data('collectionIndex', collectionIndex).data('insectIndex', null).data('type', 'C');\t\t\n  \t} else if(type == 'P'){ // called from photoreel\n\t\tvar myThumb = jQuery('.thumb').filter('[occID='+insectID+']').prev();\n\t\tif(myThumb.length > 0)\n\t\t\tjQuery('#fo-prev-button').show().data('occID', myThumb.attr('occID')).data('collectionIndex', collectionIndex).data('insectIndex', null).data('type', 'P');\n\t\tmyThumb = jQuery('.thumb').filter('[occID='+insectID+']').next();\n\t\tif(myThumb.length > 0)\n\t\t\tjQuery('#fo-next-button').show().data('occID', myThumb.attr('occID')).data('collectionIndex', collectionIndex).data('insectIndex', null).data('type', 'P');\t\t\n\t}\n\tinsect_alert_object.insect_id = insectID;\n\tinsect_alert_object.user_id = \"" . $uid . "\";\n\tflower_alert_object.flower_id = null;\n\tjQuery('#focus-collection,#filter,#fo-flower-addn-info').hide();\n    jQuery('#focus-occurrence,#fo-addn-info-header,#fo-insect-addn-info').show();\n\tjQuery('[name=determination\\:occurrence_id]').val(insectID);\n\tjQuery('[name=occurrence_comment\\:occurrence_id]').val(insectID);\n\tjQuery('#fo-new-comment,#fo-new-insect-id,#fo-new-flower-id,#fo-express-doubt').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-new-insect-id-button').show();\n\tjQuery('#fo-new-flower-id-button').hide();\n\tjQuery('#fo-new-comment-button')." . (user_access('IForm n' . $node->nid . ' insect expert') || user_access('IForm n' . $node->nid . ' create insect comment') ? "show()" : "hide()") . ";\n\tloadDeterminations(insectID, '#fo-id-history', '#fo-current-id', 'form#fo-new-insect-id-form', null, " . (user_access('IForm n' . $node->nid . ' insect expert') ? '1' : '0') . ", " . (user_access('IForm n' . $node->nid . ' flag dubious insect') ? '1' : '0') . ", insectTaxa, 'I');\n\tloadImage('occurrence_image', 'occurrence_id', insectID, '#fo-image', " . $args['Insect_Image_Ratio'] . ", function(imageRecord){insect_alert_object.insect_image_path = imageRecord.path}, '', false);\n\tloadInsectAddnInfo(insectID, collectionIndex);\n\tloadComments(insectID, '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body', false);\n\tmyScrollTo('#poll-banner');\n}\nloadFlower = function(flowerID, collectionIndex){\n    abortAjax();\n\tinsect_alert_object.insect_id = null;\n\tflower_alert_object.flower_id = flowerID;\n\tflower_alert_object.user_id = \"" . $uid . "\";\n\tjQuery('#fo-filter-button').show();\n\tjQuery('#fo-prev-button,#fo-next-button').hide(); // only one flower per collection, and don't search flowers: no next or prev buttons.\n\tjQuery('#focus-collection,#filter,#fo-insect-addn-info').hide();\n\tjQuery('#focus-occurrence,#fo-addn-info-header,#fo-flower-addn-info').show();\n\tjQuery('#fo-new-comment,#fo-new-insect-id,#fo-new-flower-id,#fo-express-doubt').removeClass('ui-accordion-content-active');\n\tjQuery('[name=determination\\:occurrence_id]').val(flowerID);\n\tjQuery('[name=occurrence_comment\\:occurrence_id]').val(flowerID);\n\tjQuery('#fo-new-flower-id-button').show();\n\tjQuery('#fo-new-insect-id-button').hide();\n\tjQuery('#fo-new-comment-button')." . (user_access('IForm n' . $node->nid . ' flower expert') || user_access('IForm n' . $node->nid . ' create flower comment') ? "show()" : "hide()") . ";\n\tloadDeterminations(flowerID, '#fo-id-history', '#fo-current-id', 'form#fo-new-flower-id-form', null, " . (user_access('IForm n' . $node->nid . ' flower expert') ? '1' : '0') . ", " . (user_access('IForm n' . $node->nid . ' flag dubious flower') ? '1' : '0') . ", flowerTaxa, 'F');\n\tloadImage('occurrence_image', 'occurrence_id', flowerID, '#fo-image', " . $args['Flower_Image_Ratio'] . ", function(imageRecord){flower_alert_object.flower_image_path = imageRecord.path}, '', false);\n\tloadFlowerAddnInfo(flowerID, collectionIndex);\n\tloadComments(flowerID, '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body', false);\n\tmyScrollTo('#poll-banner');\n}\n\naddDrawnGeomToSelection = function(geometry) {\n   \t// Create the polygon as drawn\n   \tvar feature = new OpenLayers.Feature.Vector(geometry, {});\n   \tpolygonLayer.addFeatures([feature]);\n};\n\nMyEditingToolbar=OpenLayers.Class(\n\t\tOpenLayers.Control.Panel,{\n\t\t\tinitialize:function(layer,options){\n\t\t\t\tOpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);\n\t\t\t\tthis.addControls([new OpenLayers.Control.Navigation()]);\n\t\t\t\tvar controls=[new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Polygon,{'displayClass':'olControlDrawFeaturePolygon', drawFeature: addDrawnGeomToSelection})];\n\t\t\t\tthis.addControls(controls);\n\t\t\t},\n\t\t\tdraw:function(){\n\t\t\t\tvar div=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);\n\t\t\t\tthis.activateControl(this.controls[0]);\n\t\t\t\treturn div;\n\t\t\t},\n\tCLASS_NAME:\"MyEditingToolbar\"});\n\nloadFilter = function(){\n    if(jQuery('#map').children().length == 0) {\n    \tpolygonLayer = new OpenLayers.Layer.Vector('Polygon Layer', {\n\t\t\tstyleMap: new OpenLayers.StyleMap({\n                \t\t\"default\": new OpenLayers.Style({\n                    \t\tfillColor: \"Red\",\n        \t\t            strokeColor: \"Red\",\n\t\t                    fillOpacity: 0,\n                \t\t    strokeWidth: 1\n        \t\t          })\n\t\t\t}),\n\t\t\tdisplayInLayerSwitcher: false\n\t\t});\n\t\tpolygonLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tpolygonLayer.map.searchLayer.destroyFeatures();\n\t\t\tif(inseeLayer != null)\n\t\t\t\tinseeLayer.destroyFeatures();\n\t\t});\n    \t" . $map1JS . "\n    \teditControl = new MyEditingToolbar(polygonLayer, {'displayClass':'olControlEditingToolbar'});\n\t\tpolygonLayer.map.addControl(this.editControl);\n\t\teditControl.activate();\n\t\tpolygonLayer.map.searchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tif(inseeLayer != null)\n\t\t\t\tinseeLayer.destroyFeatures();\n\t\t\tpolygonLayer.destroyFeatures();\n\t\t});\n\t}\n}\n\njQuery('#fc-add-preferred').click(function(){\n\tif(collection_preferred_object.collection_id == null) return;\n\tvar newObj = {};\n\tfor (i in collection_preferred_object) {\n\t\tnewObj[i] = collection_preferred_object[i]\n\t};\n\tnewObj.insects = JSON.stringify(newObj.insects);";
        if ($args['preferred_js_function'] != '') {
            data_entry_helper::$javascript .= "\n\t\t" . $args['preferred_js_function'] . "({type: 'C', collection: newObj});";
        }
        data_entry_helper::$javascript .= "\n});\njQuery('#fc-new-comment-button').click(function(){ \n\tjQuery('#fc-new-comment').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-comment-button').click(function(){ \n\tjQuery('#fo-new-comment').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-insect-id-button').click(function(){ \n\tjQuery('#fo-express-doubt').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-new-insect-id [name=determination\\:comment]').val(\"" . lang::get('LANG_Default_ID_Comment') . "\");\n\tjQuery('#fo-new-insect-id').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-flower-id-button').click(function(){ \n\tjQuery('#fo-express-doubt').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-new-flower-id [name=determination\\:comment]').val(\"" . lang::get('LANG_Default_ID_Comment') . "\");\n\tjQuery('#fo-new-flower-id').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-collection-button').click(function(){\n\tloadCollection(jQuery(this).data('smpID'), jQuery(this).data('collectionIndex'));\n});\njQuery('#fo-prev-button,#fo-next-button').click(function(){\n\tloadInsect(jQuery(this).data('occID'), // my occurrence id.\n\t\tjQuery(this).data('collectionIndex'), // index of my collection within search results. Used when called from a focus on collection or from search collection photoreel thumbnail\n\t\tjQuery(this).data('insectIndex'), // index of me within search results. Used when called from search\n\t\tjQuery(this).data('type') // type: 'P' from photoreel, 'S' from search, 'C' from collection, 'X' NA\n\t);\n});\n  ";
        switch ($mode) {
            case 'INSECT':
                data_entry_helper::$onload_javascript .= "loadInsect(" . $occID . ", null, null, 'X');";
                break;
            case 'FLOWER':
                data_entry_helper::$onload_javascript .= "loadFlower(" . $occID . ", null);";
                break;
            case 'COLLECTION':
                data_entry_helper::$onload_javascript .= "loadCollection(" . $smpID . ", null);";
                break;
            default:
                data_entry_helper::$onload_javascript .= "\n    \t\tjQuery('#focus-occurrence,#focus-collection,#results-insects-header,#results-collections-header,#results-insects-results,#results-collections-results').hide();\n    \t\tloadFilter();";
                if ($userID != '') {
                    $thisuser = user_load($userID);
                    data_entry_helper::$onload_javascript .= "jQuery('[name=username]').val('" . $thisuser->name . "');\n    \t\t\tjQuery('#fold-name-button').click();";
                }
                data_entry_helper::$onload_javascript .= "jQuery('#search-collections-button').click();";
                break;
        }
        return $r;
    }
Exemplo n.º 7
0
    /**
     * Return the generated form output.
     * @return Form HTML.
     */
    public static function get_form($args, $node)
    {
        global $user;
        // There is a language entry in the args parameter list: this is derived from the $language DRUPAL global.
        // It holds the 2 letter code, used to pick the language file from the lang subdirectory of prebuilt_forms.
        // There should be no explicitly output text in this file.
        // We must translate any field names and ensure that the termlists and taxonlists use the correct language.
        // For attributes, the caption is automatically translated by data_entry_helper.
        $logged_in = $user->uid > 0;
        $uid = $user->uid;
        $email = $user->mail;
        $username = $user->name;
        if (!user_access('IForm n' . $node->nid . ' access')) {
            return "<p>" . lang::get('LANG_Insufficient_Privileges') . "</p>";
        }
        $r = '';
        // Get authorisation tokens to update and read from the Warehouse.
        $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
        $svcUrl = data_entry_helper::$base_url . '/index.php/services';
        drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module');
        data_entry_helper::link_default_stylesheet();
        data_entry_helper::add_resource('jquery_ui');
        data_entry_helper::enable_validation('cc-1-collection-details');
        // don't care about ID itself, just want resources
        if ($args['help_module'] != '' && $args['help_inclusion_function'] != '' && module_exists($args['help_module']) && function_exists($args['help_inclusion_function'])) {
            $use_help = true;
            data_entry_helper::$javascript .= call_user_func($args['help_inclusion_function']);
        } else {
            $use_help = false;
        }
        if ($args['ID_tool_module'] != '' && $args['ID_tool_inclusion_function'] != '' && module_exists($args['ID_tool_module']) && function_exists($args['ID_tool_inclusion_function'])) {
            $use_ID_tool = true;
            data_entry_helper::$javascript .= call_user_func($args['ID_tool_inclusion_function']);
        } else {
            $use_ID_tool = false;
        }
        // The only things that will be editable after the collection is saved will be the identifiaction of the flower/insects.
        // no id - just getting the attributes, rest will be filled in using AJAX
        $sample_attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $occurrence_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $location_attributes = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $defAttrOptions = array('extraParams' => $readAuth, 'lookUpListCtrl' => 'radio_group', 'validation' => array('required'), 'language' => iform_lang_iso_639_2($args['language']), 'containerClass' => 'group-control-box', 'suffixTemplate' => 'nosuffix');
        $language = iform_lang_iso_639_2($args['language']);
        global $indicia_templates;
        $indicia_templates['sref_textbox_latlong'] = '<label for="{idLat}">{labelLat}:</label>' . '<input type="text" id="{idLat}" name="{fieldnameLat}" {class} {disabled} value="{default}" />' . '<label for="{idLong}">{labelLong}:</label>' . '<input type="text" id="{idLong}" name="{fieldnameLong}" {class} {disabled} value="{default}" />';
        $r .= data_entry_helper::loading_block_start();
        // note we have to proxy the post. Every time a write transaction is carried out, the write nonce is trashed.
        // For security reasons we don't want to give the user the ability to generate their own nonce, so we use
        // the fact that the user is logged in to drupal as the main authentication/authorisation/identification
        // process for the user. The proxy packages the post into the correct format
        //
        // There are 2 types of submission:
        // When a user validates a panel using the validate button, the following panel is opened on success
        // When a user presses a modify button, the open panel gets validated, and the panel to be modified is opened.
        $r .= '
<div id="cc-1" class="poll-section">
  <div id="cc-1-title" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top poll-section-title">
  	<span id="cc-1-title-details">' . lang::get('LANG_Collection_Details') . '</span>
    <div class="right">
      <div>
        <span id="cc-1-reinit-button" class="ui-state-default ui-corner-all reinit-button">' . lang::get('LANG_Reinitialise') . '</span>
        <span id="cc-1-mod-button" class="ui-state-default ui-corner-all mod-button">' . lang::get('LANG_Modify') . '</span>
      </div>
    </div>
  </div>
  <div id="cc-1-details" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
    <span id="cc-1-protocol-details"></span>
  </div>
  <div id="cc-1-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active poll-section-body">
   <form id="cc-1-collection-details" action="' . iform_ajaxproxy_url($node, 'loc-sample') . '" method="POST">
    <input type="hidden" id="website_id"       name="website_id" value="' . $args['website_id'] . '" />
    <input type="hidden" id="imp-sref"         name="location:centroid_sref"  value="" />
    <input type="hidden" id="imp-geom"         name="location:centroid_geom" value="" />
    <input type="hidden" id="imp-sref-system"  name="location:centroid_sref_system" value="4326" />
    <input type="hidden" id="sample:survey_id" name="sample:survey_id" value="' . $args['survey_id'] . '" />
    ' . iform_pollenators::help_button($use_help, "collection-help-button", $args['help_function'], $args['help_collection_arg']) . '
    <label for="location:name">' . lang::get('LANG_Collection_Name_Label') . '</label>
 	<input type="text" id="location:name"      name="location:name" value="" class="required"/>
    <input type="hidden" id="sample:location_name" name="sample:location_name" value=""/>
 	' . data_entry_helper::outputAttribute($sample_attributes[$args['protocol_attr_id']], $defAttrOptions) . '    <input type="hidden"                       name="sample:date" value="2010-01-01"/>
    <input type="hidden" id="smpAttr:' . $args['complete_attr_id'] . '" name="smpAttr:' . $args['complete_attr_id'] . '" value="0" />
    <input type="hidden" id="smpAttr:' . $args['uid_attr_id'] . '" name="smpAttr:' . $args['uid_attr_id'] . '" value="' . $uid . '" />
    <input type="hidden" id="smpAttr:' . $args['email_attr_id'] . '" name="smpAttr:' . $args['email_attr_id'] . '" value="' . $email . '" />
    <input type="hidden" id="smpAttr:' . $args['username_attr_id'] . '" name="smpAttr:' . $args['username_attr_id'] . '" value="' . $username . '" />  
    <input type="hidden" id="locations_website:website_id" name="locations_website:website_id" value="' . $args['website_id'] . '" />
    <input type="hidden" id="location:id"      name="location:id" value="" disabled="disabled" />
    <input type="hidden" id="sample:id"        name="sample:id" value="" disabled="disabled" />
    </form>
    <div id="cc-1-valid-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate') . '</div>
  </div>  
<div style="display:none" />
    <form id="cc-1-delete-collection" action="' . iform_ajaxproxy_url($node, 'sample') . '" method="POST">
       <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
       <input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '" />
       <input type="hidden" name="sample:id" value="" />
       <input type="hidden" name="sample:date" value="2010-01-01"/>
       <input type="hidden" name="sample:location_id" value="" />
       <input type="hidden" name="sample:deleted" value="t" />
    </form>
</div>
  <div id="cc-1-main-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
';
        data_entry_helper::$javascript .= "\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";\nvar sessionCounter = 0;\n\n\$.fn.foldPanel = function(){\n\tthis.children('.poll-section-body').addClass('poll-hide');\n\tthis.children('.poll-section-footer').addClass('poll-hide');\n\tthis.children('.poll-section-title').find('.reinit-button').show();\n\tthis.children('.poll-section-title').find('.mod-button').show();\n\tthis.children('.photoReelContainer').addClass('ui-corner-all').removeClass('ui-corner-top')\n};\n\n\$.fn.unFoldPanel = function(){\n\tthis.children('.poll-section-body').removeClass('poll-hide');\n\tthis.children('.poll-section-footer').removeClass('poll-hide');\n\tthis.children('.poll-section-title').find('.mod-button').hide();\n\tthis.children('.photoReelContainer').addClass('ui-corner-top').removeClass('ui-corner-all')\n\twindow.scroll(0,0); // force the window to display the top.\n\t// any reinit button is left in place\n};\n\n// because the map has to be generated in a properly sized div, we can't use the normal hide/show functions.\n// just move the panels off to the side.\n\$.fn.showPanel = function(){\n\tthis.removeClass('poll-hide');\n\tthis.unFoldPanel();\n};\n\n\$.fn.hidePanel = function(){\n\tthis.addClass('poll-hide'); \n};\n\ninseeLayer = null;\n\ndefaultSref = '" . ((int) $args['map_centroid_lat'] > 0 ? $args['map_centroid_lat'] . 'N' : -(int) $args['map_centroid_lat'] . 'S') . ' ' . ((int) $args['map_centroid_long'] > 0 ? $args['map_centroid_long'] . 'E' : -(int) $args['map_centroid_long'] . 'W') . "';\ndefaultGeom = '';\n\$.getJSON('" . $svcUrl . "' + '/spatial/sref_to_wkt'+\n        \t\t\t'?sref=' + defaultSref +\n          \t\t\t'&system=' + jQuery('#imp-sref-system').val() +\n          \t\t\t'&callback=?', function(data) {\n            \tdefaultGeom = data.wkt;\n        \t});\n\n\$.fn.resetPanel = function(){\n\tthis.find('.poll-section-body').removeClass('poll-hide');\n\tthis.find('.poll-section-footer').removeClass('poll-hide');\n\tthis.find('.reinit-button').show();\n\tthis.find('.mod-button').show();\n\tthis.find('.poll-image').empty();\n\tthis.find('.poll-session').empty();\n\n\t// resetForm does not reset the hidden fields. record_status, imp-sref-system, website_id and survey_id are not altered so do not reset.\n\t// hidden Attributes generally hold unchanging data, but the name needs to be reset (does it for non hidden as well).\n\t// hidden location:name are set in code anyway.\n\tthis.find('form').each(function(){\n\t\tjQuery(this).resetForm();\n\t\tjQuery(this).find('[name=sample\\:location_name],[name=location_image\\:path],[name=occurrence_image\\:path]').val('');\n\t\tjQuery(this).filter('#cc-1-collection-details').find('[name=sample\\:id],[name=location\\:id]').val('').attr('disabled', 'disabled');\n\t\tjQuery(this).find('[name=location_image\\:id],[name=occurrence\\:id],[name=occurrence_image\\:id]').val('').attr('disabled', 'disabled');\n\t\tjQuery(this).find('[name=sample\\:date]:hidden').val('2010-01-01');\t\t\n        jQuery(this).find('input[name=locations_website\\:website_id]').removeAttr('disabled');\n\t\tjQuery(this).find('[name^=smpAttr\\:],[name^=locAttr\\:],[name^=occAttr\\:]').each(function(){\n\t\t\tvar name = jQuery(this).attr('name').split(':');\n\t\t\tjQuery(this).attr('name', name[0]+':'+name[1]);\n\t\t});\n\t\tjQuery(this).find('input[name=location\\:centroid_sref]').val('');\n\t\tjQuery(this).find('input[name=location\\:centroid_geom]').val('');\n    });\t\n\tthis.find('.poll-dummy-form > input').val('');\n\tthis.find('.poll-dummy-form > select').val('');\n  };\n\ncheckProtocolStatus = function(){\n\tif (jQuery('#cc-3-body').children().length === 1) {\n\t    jQuery('#cc-3').find('.delete-button').hide();\n  \t} else {\n\t\tjQuery('#cc-3').find('.delete-button').show();\n\t}\n\tif(jQuery('[name=smpAttr\\:" . $args['protocol_attr_id'] . "],[name^=smpAttr\\:" . $args['protocol_attr_id'] . "\\:]').filter(':first').filter('[checked]').length >0){\n\t    jQuery('#cc-3').find('.add-button').hide();\n\t} else {\n\t    jQuery('#cc-3').find('.add-button').show();\n  \t}\n  \tvar checkedProtocol = jQuery('[name=smpAttr\\:" . $args['protocol_attr_id'] . "],[name^=smpAttr\\:" . $args['protocol_attr_id'] . "\\:]').filter('[checked]').parent();\n    if(jQuery('[name=location\\:name]').val() != '' && checkedProtocol.length > 0) {\n        jQuery('#cc-1-title-details').empty().text(jQuery('#cc-1-collection-details input[name=location\\:name]:first').val());\n        jQuery('#cc-1-protocol-details').empty().show().text(\"" . lang::get('LANG_Protocol_Title_Label') . " : \" + checkedProtocol.find('label')[0].innerHTML;\n    } else {\n        jQuery('#cc-1-title-details').empty().text(\"" . lang::get('LANG_Collection_Details') . "\");\n        // TODO autogenerate a name\n        jQuery('#cc-1-protocol-details').empty().hide();\n    }\n};\n\nshowStationPanel = true;\n\n// The validate functionality for each panel is sufficiently different that we can't generalise a function\n// this is the one called when we don't want the panel following to be opened automatically.\nvalidateCollectionPanel = function(){\n\tif(jQuery('#cc-1-body').filter('.poll-hide').length > 0) return true; // body hidden so data already been validated successfully.\n\tif(!jQuery('#cc-1-body').find('form > input').valid()){ return false; }\n\t// no need to check protocol - if we are this far, we've already filled it in.\n  \tshowStationPanel = false;\n\tjQuery('#cc-1-collection-details').submit();\n\treturn true;\n  };\n\nvalidateRadio = function(name, formSel){\n    var controls = jQuery(formSel).find('[name='+name+'],[name^='+name+'\\:]');\n\tcontrols.parent().parent().find('p').remove(); // remove existing errors\n    if(controls.filter('[checked]').length < 1) {\n        var label = \$('<p/>')\n\t\t\t\t.attr({'for': name})\n\t\t\t\t.addClass('radio-error')\n\t\t\t\t.html(\$.validator.messages.required);\n\t\tlabel.insertBefore(controls.filter(':first').parent());\n\t\treturn false;\n    }\n    return true;\n}\n\nvalidateRequiredField = function(name, formSel){\n    var control = jQuery(formSel).find('[name='+name+']');\n\tcontrol.parent().find('.required-error').remove(); // remove existing errors\n    if(control.val() == '') {\n        var label = \$('<p/>')\n\t\t\t\t.attr({'for': name})\n\t\t\t\t.addClass('required-error')\n\t\t\t\t.html(\$.validator.messages.required);\n\t\tlabel.insertBefore(control);\n\t\treturn false;\n    }\n    return true;\n}\n\n\$('#cc-1-collection-details').ajaxForm({ \n        // dataType identifies the expected content type of the server response \n        dataType:  'json', \n        // success identifies the function to invoke when the server response \n        // has been received \n        beforeSubmit:   function(data, obj, options){\n        \tvar valid = true;\n        \tif (!jQuery('form#cc-1-collection-details > input').valid()) { valid = false; }\n        \tif (!validateRadio('smpAttr\\:" . $args['protocol_attr_id'] . "', 'form#cc-1-collection-details')) { valid = false; }\n\t       \tif ( valid == false ) return valid;\n  \t\t\t// Warning this assumes that:\n  \t\t\t// 1) the location:name is the sixth field in the form.\n  \t\t\t// 1) the sample:location_name is the seventh field in the form.\n  \t\t\tdata[6].value = data[5].value;\n  \t\t\tif(data[1].value=='') data[1].value=defaultSref;\n  \t\t\tif(data[2].value=='') data[2].value=defaultGeom;\n  \t\t\tjQuery('#cc-2-floral-station > input[name=location\\:name]').val(data[5].value);\n        \treturn true;\n  \t\t},\n        success:   function(data){\n        \tif(data.success == 'multiple records' && data.outer_table == 'location'){\n        \t    jQuery('#cc-1-collection-details > input[name=location\\:id]').removeAttr('disabled').val(data.outer_id);\n        \t    jQuery('#cc-1-collection-details > input[name=locations_website\\:website_id]').attr('disabled', 'disabled');\n        \t    jQuery('#cc-2-floral-station > input[name=location\\:id]').removeAttr('disabled').val(data.outer_id);\n        \t    \$.getJSON(\"" . $svcUrl . "\" + \"/data/sample\" +\n\t\t\t          \"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t          \"&location_id=\"+data.outer_id+\"&parent_id=NULL&callback=?\", function(data) {\n\t\t\t\t\tif (data.length>0) {\n\t\t\t       \t\t    jQuery('#cc-6-consult-collection').attr('href', '" . url('node/' . $args['gallery_node']) . "'+'?collection_id='+data[0].id);\n\t\t\t        \t    jQuery('#cc-1-collection-details > input[name=sample\\:id]').removeAttr('disabled').val(data[0].id);\n\t\t\t        \t    jQuery('#cc-2-floral-station > input[name=sample\\:id]').removeAttr('disabled').val(data[0].id);\n\t\t\t        \t    // In this case we use loadAttributes to set the names of the attributes to include the attribute_value id.\n   \t       \t\t\t\t\tloadAttributes('sample_attribute_value', 'sample_attribute_id', 'sample_id', 'sample\\:id', data[0].id, 'smpAttr');\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t   \tcheckProtocolStatus();\n        \t\t\$('#cc-1').foldPanel();\n    \t\t\tif(showStationPanel){ \$('#cc-2').showPanel(); }\n\t\t    \tshowStationPanel = true;\n        \t}  else {\n\t\t\t\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\t\t\t\tif(data.error){\n\t\t\t\t\terrorString = errorString + ' : ' + data.error;\n\t\t\t\t}\n\t\t\t\tif(data.errors){\n\t\t\t\t\tfor (var i in data.errors)\n\t\t\t\t\t{\n\t\t\t\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t\t\t\t}\t\t\t\t\n\t\t\t\t}\n\t\t\t\talert(errorString);\n\t\t\t}\n        } \n});\n\n\$('#cc-1-delete-collection').ajaxForm({ \n        dataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n  \t\t\t// Warning this assumes that the data is fixed position:\n       \t\tdata[2].value = jQuery('#cc-1-collection-details input[name=sample\\:id]').val();\n       \t\tdata[3].value = jQuery('#cc-1-collection-details input[name=sample\\:date]').val();\n       \t\tdata[4].value = jQuery('#cc-1-collection-details input[name=location\\:id]').val();\n        \tif(data[2].value == '') return false;\n        \treturn true;\n  \t\t},\n        success:   function(data){\n\t\t\tjQuery('#cc-3-body').empty();\n        \tjQuery('.poll-section').resetPanel();\n\t\t\tsessionCounter = 0;\n\t\t\taddSession();\n\t\t\tcheckProtocolStatus();\n\t\t\tjQuery('.poll-section').hidePanel();\n\t\t\tjQuery('.poll-image').empty();\n\t\t\tjQuery('#cc-1').showPanel();\n\t\t\tjQuery('.reinit-button').hide();\n\t\t\tjQuery('#map')[0].map.editLayer.destroyFeatures();\n  \t\t} \n});\n\n\$('#cc-1-valid-button').click(function() {\n\tjQuery('#cc-1-collection-details').submit();\n});\n\n\$('#cc-1-reinit-button').click(function() {\n\tif(jQuery('form#cc-1-collection-details > input[name=sample\\:id]').filter('[disabled]').length > 0) { return } // sample id is disabled, so no data has been saved - do nothing.\n    if (!jQuery('form#cc-1-collection-details > input').valid()) {\n    \talert(\"" . lang::get('LANG_Unable_To_Reinit') . "\");\n        return ;\n  \t}\n\tif(confirm(\"" . lang::get('LANG_Confirm_Reinit') . "\")){\n\t\tjQuery('#cc-1-delete-collection').submit();\n\t}\n});\n\n";
        // Flower Station section.
        $options = iform_map_get_map_options($args, $readAuth);
        $olOptions = iform_map_get_ol_options($args);
        // The maps internal projection will be left at its default of 900913.
        $options['searchLayer'] = 'true';
        $options['initialFeatureWkt'] = null;
        $options['proxy'] = '';
        // Switch to degrees, minutes, seconds for lat long.
        $options['latLongFormat'] = 'DMS';
        $options['suffixTemplate'] = 'nosuffix';
        $extraParams = $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'orderby' => 'taxon');
        $species_ctrl_args = array('label' => lang::get('LANG_Flower_Species'), 'fieldname' => 'flower:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'validation' => array('required'), 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $extraParams, 'suffixTemplate' => 'nosuffix');
        $r .= '
<div id="cc-2" class="poll-section">
  <div id="cc-2-title" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all poll-section-title"><span>' . lang::get('LANG_Flower_Station') . '</span>
    <div class="right">
      <span id="cc-2-mod-button" class="ui-state-default ui-corner-all mod-button">' . lang::get('LANG_Modify') . '</span>
    </div>
  </div>
  <div id="cc-2-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-top ui-accordion-content-active poll-section-body">
    <div id="cc-2-flower" >
	  <form id="cc-2-flower-upload" enctype="multipart/form-data" action="' . iform_ajaxproxy_url($node, 'media') . '" method="POST">
    		<input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
    		<input name="upload_file" type="file" class="required" />
     		<input type="submit" value="' . lang::get('LANG_Upload_Flower') . '" class="btn-submit" />
      </form>
 	  <div id="cc-2-flower-image" class="poll-image"></div>
 	  <div id="cc-2-flower-identify" class="poll-dummy-form">
        ' . iform_pollenators::help_button($use_help, "flower-help-button", $args['help_function'], $args['help_flower_arg']) . '
 	    <p><strong>' . lang::get('LANG_Identify_Flower') . '</strong></p>
        <label for="id-flower-later" class="follow-on">' . lang::get('LANG_ID_Flower_Later') . ' </label><input type="checkbox" id="id-flower-later" name="id-flower-later" /> 
		' . ($args['ID_tool_flower_url'] != '' && $args['ID_tool_flower_poll_dir'] ? '<label for="flower-id-button">' . lang::get('LANG_Flower_ID_Key_label') . ' :</label><span id="flower-id-button" class="ui-state-default ui-corner-all poll-id-button" >' . lang::get('LANG_Launch_ID_Key') . '</span>' : '') . '<span id="flower-id-cancel" class="ui-state-default ui-corner-all poll-id-cancel" >' . lang::get('LANG_Cancel_ID') . '</span>
    	' . data_entry_helper::select($species_ctrl_args) . '
		<input type="text" name="flower:taxon_text_description" readonly="readonly">
      </div>
 	</div>
    <div class="poll-break"></div>
 	<div id="cc-2-environment">
	  <form id="cc-2-environment-upload" enctype="multipart/form-data" action="' . iform_ajaxproxy_url($node, 'media') . '" method="POST">
    		<input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
    		<input name="upload_file" type="file" class="required" />
    		<input type="submit" value="' . lang::get('LANG_Upload_Environment') . '" class="btn-submit" />
      </form>
 	  <div id="cc-2-environment-image" class="poll-image"></div>
 	</div>
 	<form id="cc-2-floral-station" action="' . iform_ajaxproxy_url($node, 'loc-smp-occ') . '" method="POST">
      <input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
      <input type="hidden" id="location:id" name="location:id" value="" />
      <input type="hidden" id="location:name" name="location:name" value=""/>
      <input type="hidden" name="location:centroid_sref" />
      <input type="hidden" name="location:centroid_geom" />
      <input type="hidden" name="location:centroid_sref_system" value="4326" />
      <input type="hidden" id="location_image:path" name="location_image:path" value="" />
      <input type="hidden" id="sample:survey_id" name="sample:survey_id" value="' . $args['survey_id'] . '" />
      <input type="hidden" id="sample:id" name="sample:id" value=""/>
      <input type="hidden" name="sample:date" value="2010-01-01"/>
      <input type="hidden" name="determination:taxa_taxon_list_id" value=""/>  
      <input type="hidden" name="determination:taxon_text_description" value=""/>  
      <input type="hidden" name="determination:cms_ref" value="' . $uid . '" />
      <input type="hidden" name="determination:email_address" value="' . $email . '" />
      <input type="hidden" name="determination:person_name" value="' . $username . '" />  
      <input type="hidden" name="occurrence:use_determination" value="Y"/>    
      <input type="hidden" name="occurrence:record_status" value="C" />
      <input type="hidden" id="location_image:id" name="location_image:id" value="" disabled="disabled" />
      <input type="hidden" id="occurrence:id" name="occurrence:id" value="" disabled="disabled" />
      <input type="hidden" id="determination:id" name="determination:id" value="" disabled="disabled" />
      <input type="hidden" id="occurrence_image:id" name="occurrence_image:id" value="" disabled="disabled" />
      <input type="hidden" id="occurrence_image:path" name="occurrence_image:path" value="" />
      ' . data_entry_helper::outputAttribute($occurrence_attributes[$args['flower_type_attr_id']], array('extraParams' => $readAuth, 'lookUpListCtrl' => 'radio_group', 'sep' => ' &nbsp; ', 'language' => iform_lang_iso_639_2($args['language']), 'containerClass' => 'group-control-box', 'suffixTemplate' => 'nosuffix')) . data_entry_helper::outputAttribute($location_attributes[$args['distance_attr_id']], array('extraParams' => $readAuth, 'lookUpListCtrl' => 'radio_group', 'sep' => ' &nbsp; ', 'language' => iform_lang_iso_639_2($args['language']), 'containerClass' => 'group-control-box', 'suffixTemplate' => 'nosuffix')) . data_entry_helper::outputAttribute($location_attributes[$args['habitat_attr_id']], array('extraParams' => $readAuth, 'lookUpListCtrl' => 'checkbox_group', 'sep' => ' &nbsp; ', 'language' => iform_lang_iso_639_2($args['language']), 'containerClass' => 'group-control-box', 'suffixTemplate' => 'nosuffix')) . '
    </form>
    <div class="poll-break"></div>
    <div>
      ' . iform_pollenators::help_button($use_help, "location-help-button", $args['help_function'], $args['help_location_arg']) . '
      <div>' . lang::get('LANG_Location_Notes') . '</div>
 	  <div class="poll-map-container">
    ';
        $r .= data_entry_helper::map_panel($options, $olOptions);
        $r .= '
      </div>
      <div><div id="cc-2-location-entry">
        ' . data_entry_helper::georeference_lookup(array('label' => lang::get('LANG_Georef_Label'), 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'suffixTemplate' => 'nosuffix')) . '
    	<span >' . lang::get('LANG_Georef_Notes') . '</span>
 	    <label for="place:INSEE">' . lang::get('LANG_Or') . '</label>
 		<input type="text" id="place:INSEE" name="place:INSEE" value="' . lang::get('LANG_INSEE') . '"
	 		onclick="if(this.value==\'' . lang::get('LANG_INSEE') . '\'){this.value=\'\'; this.style.color=\'#000\'}"  
            onblur="if(this.value==\'\'){this.value=\'' . lang::get('LANG_INSEE') . '\'; this.style.color=\'#555\'}" />
    	<input type="button" id="search-insee-button" class="ui-corner-all ui-widget-content ui-state-default search-button" value="Search" />
        ' . data_entry_helper::sref_textbox(array('srefField' => 'place:entered_sref', 'systemfield' => 'place:entered_sref_system', 'id' => 'place-sref', 'fieldname' => 'place:name', 'splitLatLong' => true, 'labelLat' => lang::get('Latitude'), 'fieldnameLat' => 'place:lat', 'labelLong' => lang::get('Longitude'), 'fieldnameLong' => 'place:long', 'idLat' => 'imp-sref-lat', 'idLong' => 'imp-sref-long', 'suffixTemplate' => 'nosuffix')) . '
 	  </div></div>
      <div id="cc-2-loc-description"></div>
    </div>
  </div>
  <div id="cc-2-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active poll-section-footer">
    <div id="cc-2-valid-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate_Flower') . '</div>
  </div>
</div>';
        // NB the distance attribute is left blank at the moment if unknown: TODO put in a checkbox : checked if blank for nsp
        data_entry_helper::$javascript .= "\n\nshowSessionsPanel = true;\n\nvar flowerTimer1;\nvar flowerTimer2;\nvar IDcounter = 0;\n\nflowerPoller = function(){\n\tflowerTimer1 = setTimeout('flowerPoller();', " . $args['ID_tool_poll_interval'] . ");\n\t\$.get('" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['ID_tool_flower_poll_dir']) . session_id() . "_'+IDcounter.toString(), function(data){\n      var da = data.split('\\n');\n      // first count number of returned items.\n      // if > 1 put all into taxon_description.\n      // if = 1 rip out the description, remove the formatting, scan the flower select for it, and set the value. Set the taxon description.\n\t  da[1] = da[1].replace(/\\\\\\\\i\\{\\}/g, '').replace(/\\\\\\\\i0\\{\\}/g, '');\n      var items = da[1].split(':');\n\t  var count = items.length;\n\t  if(items[count-1] == '') count--;\n\t  if(count <= 0){\n\t  \t// no valid stuff so blank it all out.\n\t  \tjQuery('#cc-2-flower-identify > select[name=flower\\:taxa_taxon_list_id]').val('');\n\t  \tjQuery('#cc-2-flower-identify > select[name=flower\\:taxon_text_description]').val('');\n\t  } else if(count == 1){\n\t  \tjQuery('#cc-2-flower-identify > select[name=flower\\:taxa_taxon_list_id]').val('');\n\t  \tjQuery('#cc-2-flower-identify > select[name=flower\\:taxon_text_description]').val(items[0]);\n  \t\tvar x = jQuery('#cc-2-flower-identify').find('option').filter('[text='+items[0]+']');\n\t  \tif(x.length > 0){\n\t\t\tjQuery('#cc-2-flower-identify > select[name=flower\\:taxon_text_description]').val('');\n\t  \t\tjQuery('#cc-2-flower-identify > select[name=flower\\:taxa_taxon_list_id]').val(x[0].value);\n  \t\t}\n\t  } else {\n\t  \tjQuery('#cc-2-flower-identify > select[name=flower\\:taxa_taxon_list_id]').val('');\n\t  \tjQuery('#cc-2-flower-identify > select[name=flower\\:taxon_text_description]').val(da[1]);\n\t  }\n\t  flowerReset();\n    });\n};\nflowerReset = function(){\n\tclearTimeout(flowerTimer1);\n\tclearTimeout(flowerTimer2);\n\tjQuery('#flower-id-cancel').hide();\n};\n\njQuery('#flower-id-button').click(function(){\n\tIDcounter++;\n\tclearTimeout(flowerTimer1);\n\tclearTimeout(flowerTimer2);\n\twindow.open('" . $args['ID_tool_flower_url'] . session_id() . "_'+IDcounter.toString(),'','') \n\tflowerTimer1 = setTimeout('flowerPoller();', " . $args['ID_tool_poll_interval'] . ");\n\tflowerTimer2 = setTimeout('flowerReset();', " . $args['ID_tool_poll_timeout'] . ");\n\tjQuery('#flower-id-cancel').show();\n});\njQuery('#flower-id-cancel').click(function(){\n\tflowerReset();\n});\njQuery('#flower-id-cancel').hide();\n\njQuery('#search-insee-button').click(function(){\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroy();\n\tvar filters = [];\n  \tvar place = jQuery('input[name=place\\:INSEE]').val();\n  \tif(place == '" . lang::get('LANG_INSEE') . "') return;\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_NEW',\n    \t\tvalue: place\n  \t\t}));\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_OLD',\n    \t\tvalue: place\n  \t\t}));\n\n\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\tvar styleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Red\",\n                    strokeColor: \"Red\",\n                    fillOpacity: 0,\n                    strokeWidth: 1\n                  })\n\t});\n\tinseeLayer = new OpenLayers.Layer.Vector('INSEE Layer', {\n\t\t  styleMap: styleMap,\n          strategies: [strategy],\n          displayInLayerSwitcher: false,\n\t      protocol: new OpenLayers.Protocol.WFS({\n              url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n              featurePrefix: '" . $args['INSEE_prefix'] . "',\n              featureType: '" . $args['INSEE_type'] . "',\n              geometryName:'the_geom',\n              featureNS: '" . $args['INSEE_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0'                  \n      \t\t  ,propertyNames: ['the_geom']\n  \t\t\t})\n    });\n\tinseeLayer.events.register('featuresadded', {}, function(a1){\n\t\tvar div = jQuery('#map')[0];\n\t\tdiv.map.searchLayer.destroyFeatures();\n\t\tvar bounds=inseeLayer.getDataExtent();\n    \tvar dy = (bounds.top-bounds.bottom)/10;\n    \tvar dx = (bounds.right-bounds.left)/10;\n    \tbounds.top = bounds.top + dy;\n    \tbounds.bottom = bounds.bottom - dy;\n    \tbounds.right = bounds.right + dx;\n    \tbounds.left = bounds.left - dx;\n    \t// if showing a point, don't zoom in too far\n    \tif (dy===0 && dx===0) {\n    \t\tdiv.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n    \t} else {\n    \t\tdiv.map.zoomToExtent(bounds);\n    \t}\n    });\n\tinseeLayer.events.register('loadend', {}, function(){\n\t\tif(inseeLayer.features.length == 0){\n\t\t\talert(\"" . lang::get('LANG_NO_INSEE') . "\");\n\t\t}\n    });\n    jQuery('#map')[0].map.addLayer(inseeLayer);\n\tstrategy.load({filter: new OpenLayers.Filter.Logical({\n\t\t\t      type: OpenLayers.Filter.Logical.OR,\n\t\t\t      filters: filters\n\t\t  \t  })});\n});\n\nvalidateStationPanel = function(){\n\tvar myPanel = jQuery('#cc-2');\n\tvar valid = true;\n\tif(myPanel.filter('.poll-hide').length > 0) return true; // panel is not visible so no data to fail validation.\n\tif(myPanel.find('.poll-section-body').filter('.poll-hide').length > 0) return true; // body hidden so data already been validated successfully.\n\t// If no data entered also return true: this can only be the case when pressing the modify button on the collections panel\n\tif(jQuery('form#cc-2-floral-station > input[name=location_image\\:path]').val() == '' &&\n\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence\\:id]').val() == '' &&\n\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence_image\\:path]').val() == '' &&\n\t\t\tjQuery('#cc-2-flower-identify > select[name=flower\\:taxa_taxon_list_id]').val() == '' &&\n    \t\tjQuery('[name=occAttr\\:" . $args['flower_type_attr_id'] . "],[name^=occAttr\\:" . $args['flower_type_attr_id'] . "\\:]').filter('[checked]').length == 0 &&\n    \t\tjQuery('[name=locAttr\\:" . $args['habitat_attr_id'] . "],[name^=locAttr\\:" . $args['habitat_attr_id'] . "\\:]').filter('[checked]').length == 0 &&\n    \t\tjQuery('[name=locAttr\\:" . $args['distance_attr_id'] . "],[name^=locAttr\\:" . $args['distance_attr_id'] . "\\:]').val() == '') {\n\t\tjQuery('#cc-2').foldPanel();\n\t\treturn true;\n\t}\n    if(jQuery('form#cc-2-floral-station > input[name=location_image\\:path]').val() == '' ||\n\t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence_image\\:path]').val() == ''){\n\t\talert(\"" . lang::get('LANG_Must_Provide_Pictures') . "\");\n\t\tvalid = false;\n\t}\n    if(jQuery('#imp-geom').val() == '') {\n\t\talert(\"" . lang::get('LANG_Must_Provide_Location') . "\");\n\t\tvalid = false;\n\t}\n\tif (jQuery('#id-flower-later').attr('checked') == ''){\n\t\tif(!validateRequiredField('flower\\:taxa_taxon_list_id', '#cc-2-flower-identify')) { valid = false; }\n\t}\n\tif (!jQuery('form#cc-2-floral-station > input').valid()) { valid = false; }\n   \tif (!validateRadio('occAttr\\:" . $args['flower_type_attr_id'] . "', 'form#cc-2-floral-station')) { valid = false; }\n   \tif ( valid == false ) return valid;\n\tshowSessionsPanel = false;\n\tjQuery('form#cc-2-floral-station').submit();\n\treturn true;\n};\n\n// Flower upload picture form.\n\$('#cc-2-flower-upload').ajaxForm({ \n        dataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n         \tif (!jQuery('form#cc-2-flower-upload').valid()) { return false; }\n        \t\$('#cc-2-flower-image').empty();\n        \t\$('#cc-2-flower-image').addClass('loading')\n        },\n        success:   function(data){\n        \tif(data.success == true){\n\t        \t// There is only one file\n\t        \tjQuery('form#cc-2-floral-station input[name=occurrence_image\\:path]').val(data.files[0]);\n\t        \tvar img = new Image();\n\t        \t\$(img).load(function () {\n        \t\t\t\t\$(this).hide();\n        \t\t\t\t\$('#cc-2-flower-image').removeClass('loading').append(this);\n        \t\t\t\t\$(this).fadeIn();\n\t\t\t    \t})\n\t\t\t\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+data.files[0])\n\t\t\t\t    .css('max-width', \$('#cc-2-flower-image').width()).css('max-height', \$('#cc-2-flower-image').height())\n\t\t\t\t    .css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\t\t\t\tjQuery('#cc-2-flower-upload input[name=upload_file]').val('');\n\t\t\t} else {\n\t\t\t\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\t        \tjQuery('form#cc-2-floral-station input[name=occurrence_image\\:path]').val('');\n\t\t\t\t\$('#cc-2-flower-image').removeClass('loading');\n\t\t\t\tif(data.error){\n\t\t\t\t\terrorString = errorString + ' : ' + data.error;\n\t\t\t\t}\n\t\t\t\tif(data.errors){\n\t\t\t\t\tfor (var i in data.errors)\n\t\t\t\t\t{\n\t\t\t\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t\t\t\t}\t\t\t\t\n\t\t\t\t}\n\t\t\t\talert(errorString);\n\t\t\t}\n  \t\t} \n});\n\n// Flower upload picture form.\n\$('#cc-2-environment-upload').ajaxForm({ \n        dataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n         \tif (!jQuery('form#cc-2-environment-upload').valid()) { return false; }\n        \t\$('#cc-2-environment-image').empty();\n        \t\$('#cc-2-environment-image').addClass('loading')\n        },\n        success:   function(data){\n        \tif(data.success == true){\n\t        \t// There is only one file\n\t        \tjQuery('form#cc-2-floral-station input[name=location_image\\:path]').val(data.files[0]);\n\t        \tvar img = new Image();\n\t        \t\$(img).load(function () {\n        \t\t\t\t\$(this).hide();\n        \t\t\t\t\$('#cc-2-environment-image').removeClass('loading').append(this);\n        \t\t\t\t\$(this).fadeIn();\n\t\t\t    \t})\n\t\t\t\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+data.files[0])\n\t\t\t\t    .css('max-width', \$('#cc-2-environment-image').width()).css('max-height', \$('#cc-2-environment-image').height())\n\t\t\t\t    .css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\t\t\t\tjQuery('#cc-2-environment-upload input[name=upload_file]').val('');\n\t\t\t} else {\n\t\t\t\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\t        \tjQuery('form#cc-2-floral-station input[name=location_image\\:path]').val('');\n\t\t\t\t\$('#cc-2-environment-image').removeClass('loading');\n\t\t\t\tif(data.error){\n\t\t\t\t\terrorString = errorString + ' : ' + data.error;\n\t\t\t\t}\n\t\t\t\tif(data.errors){\n\t\t\t\t\tfor (var i in data.errors)\n\t\t\t\t\t{\n\t\t\t\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t\t\t\t}\t\t\t\t\n\t\t\t\t}\n\t\t\t\talert(errorString);\n\t\t\t}\n        } \n});\n\n\$('#cc-2-floral-station').ajaxForm({ \n    dataType:  'json', \n    beforeSubmit:   function(data, obj, options){\n\t\tvar valid = true;\n    \tif(jQuery('form#cc-2-floral-station > input[name=location_image\\:path]').val() == '' ||\n\t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence_image\\:path]').val() == '' ){\n\t\t\talert(\"" . lang::get('LANG_Must_Provide_Pictures') . "\");\n\t\t\tvalid = false;\n\t\t}\n\t\tif(jQuery('#imp-geom').val() == '') {\n\t\t\talert(\"" . lang::get('LANG_Must_Provide_Location') . "\");\n\t\t\tvalid = false;\n\t\t}\n\t\tif (!jQuery('form#cc-2-floral-station > input').valid()) { valid = false; }\n   \t\tif (!validateRadio('occAttr\\:" . $args['flower_type_attr_id'] . "', 'form#cc-2-floral-station')) { valid = false; }\n\t\t// DANGER this assumes certain positioning of the centroid sref and geom within the data array\n\t\tif(data[3].name != 'location:centroid_sref' || data[4].name != 'location:centroid_geom') {\n\t\t\talert('Internal error: imp-sref or imp-geom post location mismatch');\n\t\t\treturn false;\n\t\t}\n\t\tdata[3].value = jQuery('#imp-sref').val();\n\t\tdata[4].value = jQuery('#imp-geom').val();\n\t\tdata[10].value = jQuery('#cc-2-flower-identify > select[name=flower\\:taxa_taxon_list_id]').val();\n\t\tdata[11].value = jQuery('#cc-2-flower-identify > select[name=flower\\:taxon_text_description]').val();\n\t\tif (jQuery('#id-flower-later').attr('checked') == ''){\n\t\t\tif (!validateRequiredField('flower\\:taxa_taxon_list_id', '#cc-2-flower-identify')) { valid = false; }\n\t\t} else {\n\t\t\tdata.splice(10,5); // remove determination entries.\n\t\t}\n   \t\tif ( valid == false ) return valid;\n\t\treturn true;\n\t},\n    success:   function(data){\n       \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n       \t\t// the sample and location ids are already fixed, so just need to populate the occurrence and image IDs, and rename the location and occurrence attribute.\n       \t    \$.getJSON(\"" . $svcUrl . "\" + \"/data/occurrence\" +\n\t\t          \"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t          \"&sample_id=\"+data.outer_id+\"&callback=?\", function(occdata) {\n\t\t\t\tif (occdata.length>0) {\n\t\t        \tjQuery('#cc-2-floral-station > input[name=occurrence\\:id]').removeAttr('disabled').val(occdata[0].id);\n       \t\t\t\tloadAttributes('occurrence_attribute_value', 'occurrence_attribute_id', 'occurrence_id', 'occurrence\\:id', occdata[0].id, 'occAttr');\n\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_image/\" +\n       \t\t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n       \t\t\t\t\t\t\"&occurrence_id=\"+occdata[0].id+\"&callback=?\", function(imgdata) {\n\t\t\t\t\t    if (imgdata.length>0) {\n\t\t        \t\t\tjQuery('#cc-2-floral-station > input[name=occurrence_image\\:id]').removeAttr('disabled').val(imgdata[0].id);\n\t\t        \t\t}});\n\t\t        }});\n\t\t    var location_id = jQuery('#cc-2-floral-station > input[name=location\\:id]').val();\n       \t\tloadAttributes('location_attribute_value', 'location_attribute_id', 'location_id', 'location\\:id', location_id, 'locAttr');\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/location_image/\" +\n       \t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n       \t\t\t\t\"&location_id=\"+location_id+\"&callback=?\", function(data) {\n\t\t\t\tif (data.length>0) {\n\t\t        \tjQuery('#cc-2-floral-station > input[name=location_image\\:id]').removeAttr('disabled').val(data[0].id);\n\t\t        }});\n\t\t\tjQuery('#cc-2').foldPanel();\n\t\t\tif(showSessionsPanel) { jQuery('#cc-3').showPanel(); }\n\t\t\tshowSessionsPanel = true;\n        } \n\t}\n});\n\n\$('#cc-2-valid-button').click(function() {\n\tjQuery('#cc-2-floral-station').submit();\n});\n\n";
        // Sessions.
        $r .= '
<div id="cc-3" class="poll-section">
  <div id="cc-3-title" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all poll-section-title"><span>' . lang::get('LANG_Sessions_Title') . '</span>
    <div id="cc-3-mod-button" class="right ui-state-default ui-corner-all mod-button">' . lang::get('LANG_Modify') . '</div>
  </div>
  <div id="cc-3-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-top ui-accordion-content-active poll-section-body">
  </div>
  <div id="cc-3-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active poll-section-footer">
	<div id="cc-3-add-button" class="ui-state-default ui-corner-all add-button">' . lang::get('LANG_Add_Session') . '</div>
    <div id="cc-3-valid-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate_Session') . '</div>
  </div>
</div>
<div style="display:none" />
    <form id="cc-3-delete-session" action="' . iform_ajaxproxy_url($node, 'sample') . '" method="POST">
       <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
       <input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '" />
       <input type="hidden" name="sample:id" value="" />
       <input type="hidden" name="sample:date" value="2010-01-01"/>
       <input type="hidden" name="sample:location_id" value="" />
       <input type="hidden" name="sample:deleted" value="t" />
    </form>
</div>';
        data_entry_helper::$javascript .= "\n\$('#cc-3-delete-session').ajaxForm({ \n        dataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n  \t\t\t// Warning this assumes that the data is fixed position:\n       \t\tdata[4].value = jQuery('#cc-1-collection-details input[name=location\\:id]').val();\n        \tif(data[2].value == '') return false;\n        \treturn true;\n  \t\t},\n        success:   function(data){\n  \t\t} \n});\npopulateSessionSelect = function(){\n\tvar insectSessionSelect = jQuery('form#cc-4-main-form > select[name=occurrence\\:sample_id]');\n\tvar value = insectSessionSelect.val();\n\tinsectSessionSelect.empty();\n\t// NB at this point the attributes have been loaded so have full name.\n\t\$('.poll-session-form').each(function(i){\n\t\tjQuery('<option value=\"'+\n\t\t\t\tjQuery(this).children('input[name=sample\\:id]').val()+\n\t\t\t\t'\">'+\n\t\t\t\tjQuery(this).children('input[name=sample\\:date]').val()+\n\t\t\t\t' : '+\n\t\t\t\tjQuery(this).children('[name=smpAttr\\:" . $args['start_time_attr_id'] . "],[name^=smpAttr\\:" . $args['start_time_attr_id'] . "\\:]').val()+\n\t\t\t\t' > '+\n\t\t\t\tjQuery(this).children('[name=smpAttr\\:" . $args['end_time_attr_id'] . "],[name^=smpAttr\\:" . $args['end_time_attr_id'] . "\\:]').val()+\n\t\t\t\t'</option>')\n\t\t\t.appendTo(insectSessionSelect);\n\t});\n\tif(value)\n\t\tinsectSessionSelect.val(value);\n}\n\nvalidateAndSubmitOpenSessions = function(){\n\tvar valid = true;\n\t// only check the visible forms as rest have already been validated successfully.\n\t\$('.poll-session-form:visible').each(function(i){\n\t    if (!jQuery(this).children('input').valid()) {\n\t    \tvalid = false; }\n\t    if (!jQuery('form#cc-2-floral-station > input').valid()) { valid = false; }\n   \t\tif (!validateRadio('smpAttr\\:" . $args['sky_state_attr_id'] . "', this)) { valid = false; }\n   \t\tif (!validateRadio('smpAttr\\:" . $args['temperature_attr_id'] . "', this)) { valid = false; }\n   \t\tif (!validateRadio('smpAttr\\:" . $args['wind_attr_id'] . "', this)) { valid = false; }\n    });\n\tif(valid == false) return false;\n\t\$('.poll-session-form:visible').submit();\n\treturn true;\n}\n\naddSession = function(){\n\tsessionCounter = sessionCounter + 1;\n\t// dynamically build the contents of the session block.\n\tvar newSession = jQuery('<div id=\"cc-3-session-'+sessionCounter+'\" class=\"poll-session\"/>')\n\t\t.appendTo('#cc-3-body');\n\tvar newTitle = jQuery('<div class=\"poll-session-title\">" . lang::get('LANG_Session') . " '+sessionCounter+'</div>')\n\t\t.appendTo(newSession);\n\tvar newModButton = jQuery('<div class=\"right ui-state-default ui-corner-all mod-button\">" . lang::get('LANG_Modify') . "</div>')\n\t\t.appendTo(newTitle).hide();\n\tvar newDeleteButton = jQuery('<div class=\"right ui-state-default ui-corner-all delete-button\">" . lang::get('LANG_Delete_Session') . "</div>')\n\t\t.appendTo(newTitle);\t\n\tnewModButton.click(function() {\n\t\tif(!validateAndSubmitOpenSessions()) return false;\n\t\tvar session=\$(this).parents('.poll-session');;\n\t\tsession.show();\n\t\tsession.children().show();\n\t\tsession.children(':first').children(':first').hide(); // this is the mod button itself\n    });\n    var formContainer = jQuery('<div />').appendTo(newSession);\n    var newForm = jQuery('<form action=\"" . iform_ajaxproxy_url($node, 'sample') . "\" method=\"POST\" class=\"poll-session-form\" />').appendTo(formContainer);\n\tjQuery('<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />').appendTo(newForm);\n\tjQuery('<input type=\"hidden\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />').appendTo(newForm);\n\tjQuery('<input type=\"hidden\" name=\"sample:parent_id\" />').appendTo(newForm).val(jQuery('#cc-1-collection-details > input[name=sample\\:id]').val());\n\tjQuery('<input type=\"hidden\" name=\"sample:location_id\" />').appendTo(newForm).val(jQuery('#cc-1-collection-details > input[name=location\\:id]').val());\n\tjQuery('<input type=\"hidden\" name=\"sample:id\" value=\"\" disabled=\"disabled\" />').appendTo(newForm);\n";
        if ($use_help) {
            data_entry_helper::$javascript .= "\n\tvar helpDiv = jQuery('<div class=\"right ui-state-default ui-corner-all help-button\">" . lang::get('LANG_Help_Button') . "</div>');\n\thelpDiv.click(function(){\n\t\t" . $args['help_function'] . "(" . $args['help_session_arg'] . ");\n\t});\n\thelpDiv.appendTo(newForm);";
        }
        data_entry_helper::$javascript .= "\n\tvar dateAttr = '" . str_replace("\n", "", data_entry_helper::date_picker(array('label' => lang::get('LANG_Date'), 'id' => '<id>', 'fieldname' => 'sample:date', 'class' => 'vague-date-picker required', 'suffixTemplate' => 'nosuffix'))) . "';\n\tvar dateID = 'cc-3-session-date-'+sessionCounter;\n\tjQuery(dateAttr.replace(/<id>/g, dateID)).appendTo(newForm);\n    jQuery('#'+dateID).datepicker({\n\t\tdateFormat : 'yy-mm-dd',\n\t\tconstrainInput: false,\n\t\tmaxDate: '0'\n\t});\n    jQuery('" . data_entry_helper::outputAttribute($sample_attributes[$args['start_time_attr_id']], $defAttrOptions) . "').appendTo(newForm);\n\tjQuery('" . data_entry_helper::outputAttribute($sample_attributes[$args['end_time_attr_id']], $defAttrOptions) . "').appendTo(newForm);\n\tjQuery('" . data_entry_helper::outputAttribute($sample_attributes[$args['sky_state_attr_id']], $defAttrOptions) . "').appendTo(newForm);\n\tjQuery('" . data_entry_helper::outputAttribute($sample_attributes[$args['temperature_attr_id']], $defAttrOptions) . "').appendTo(newForm);\n\tjQuery('" . data_entry_helper::outputAttribute($sample_attributes[$args['wind_attr_id']], $defAttrOptions) . "').appendTo(newForm);\n\tjQuery('" . data_entry_helper::outputAttribute($sample_attributes[$args['shade_attr_id']], $defAttrOptions) . "').appendTo(newForm);\n\tnewDeleteButton.click(function() {\n\t\tvar container = \$(this).parent().parent();\n\t\tjQuery('#cc-3-delete-session').find('[name=sample\\:id]').val(container.find('[name=sample\\:id]').val());\n\t\tjQuery('#cc-3-delete-session').find('[name=sample\\:date]').val(container.find('[name=sample\\:date]').val());\n\t\tjQuery('#cc-3-delete-session').find('[name=sample\\:location_id]').val(container.find('[name=sample\\:location_id]').val());\n\t\tif(container.find('[name=sample\\:id]').filter('[disabled]').length == 0){\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\t\t\"&sample_id=\"+container.find('[name=sample\\:id]').val()+\"&callback=?\", function(insectData) {\n\t\t\t\tif (insectData.length>0) {\n\t\t\t\t\talert(\"" . lang::get('LANG_Cant_Delete_Session') . "\");\n\t\t\t\t} else if(confirm(\"" . lang::get('LANG_Confirm_Session_Delete') . "\")){\n\t\t\t\t\tjQuery('#cc-3-delete-session').submit();\n\t\t\t\t\tcontainer.remove();\n\t\t\t\t\tcheckProtocolStatus();\n\t\t\t\t}\n\t\t\t});\n\t\t} else if(confirm(\"" . lang::get('LANG_Confirm_Session_Delete') . "\")){\n\t\t\tcontainer.remove();\n\t\t\tcheckProtocolStatus();\n\t\t}\n    });\n    newForm.ajaxForm({ \n    \tdataType:  'json',\n    \tbeforeSubmit:   function(data, obj, options){\n    \t\tvar valid = true;\n    \t\tif (!obj.find('input').valid()) {\n    \t\t\tvalid = false; }\n    \t\tif (!validateRadio('smpAttr\\:" . $args['sky_state_attr_id'] . "', obj)) { valid = false; }\n   \t\t\tif (!validateRadio('smpAttr\\:" . $args['temperature_attr_id'] . "', obj)) { valid = false; }\n   \t\t\tif (!validateRadio('smpAttr\\:" . $args['wind_attr_id'] . "', obj)) { valid = false; }\n    \t\tdata[2].value = jQuery('#cc-1-collection-details > input[name=sample\\:id]').val();\n\t\t\tdata[3].value = jQuery('#cc-1-collection-details > input[name=location\\:id]').val();\n\t\t\treturn valid;\n\t\t},\n   \t    success:   function(data, status, form){\n   \t    // TODO: error condition handling, eg no date.\n   \t    \tvar thisSession = form.parents('.poll-session');\n    \t\tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n   \t    \t    form.children('input[name=sample\\:id]').removeAttr('disabled').val(data.outer_id);\n   \t    \t    loadAttributes('sample_attribute_value', 'sample_attribute_id', 'sample_id', 'sample\\:id', data.outer_id, 'smpAttr');\n        \t}\n\t\t\tthisSession.show();\n\t\t\tthisSession.children(':first').show().find('*').show();\n\t\t\tthisSession.children().not(':first').hide();\n  \t\t}\n\t});\n\tcheckProtocolStatus();\n    return(newSession);\n};\n\nvalidateSessionsPanel = function(){\n\tif(jQuery('#cc-3').filter('.poll-hide').length > 0) return true; // panel is not visible so no data to fail validation.\n\tif(jQuery('#cc-3').find('.poll-section-body').filter('.poll-hide').length > 0) return true; // body hidden so data already been validated successfully.\n\tvar openSession = jQuery('.poll-session-form:visible');\n\tif(openSession.length > 0){\n\t\tif(jQuery('input[name=sample\\:id]', openSession).val() == '' &&\n\t\t\t\tjQuery('input[name=sample\\:date]', openSession).val() == '" . lang::get('click here') . "' &&\n\t\t\t\tjQuery('[name=smpAttr\\:" . $args['start_time_attr_id'] . "],[name^=smpAttr\\:" . $args['start_time_attr_id'] . "\\:]', openSession).val() == '' &&\n\t\t\t\tjQuery('[name=smpAttr\\:" . $args['end_time_attr_id'] . "],[name^=smpAttr\\:" . $args['end_time_attr_id'] . "\\:]', openSession).val() == '' &&\n\t\t\t\tjQuery('[name=smpAttr\\:" . $args['sky_state_attr_id'] . "],[name^=smpAttr\\:" . $args['sky_state_attr_id'] . "\\:]', openSession).filter('[checked]').length == 0 &&\n    \t\t\tjQuery('[name=smpAttr\\:" . $args['temperature_attr_id'] . "],[name^=smpAttr\\:" . $args['temperature_attr_id'] . "\\:]', openSession).filter('[checked]').length == 0 &&\n    \t\t\tjQuery('[name=smpAttr\\:" . $args['wind_attr_id'] . "],[name^=smpAttr\\:" . $args['wind_attr_id'] . "\\:]', openSession).filter('[checked]').length == 0) {\n\t\t\t// NB shade is a boolean, and always has one set (default no)\n    \t\tjQuery('#cc-3').foldPanel();\n\t\t\treturn true;\n\t\t}\n\t}\n\t// not putting in an empty data set check here - user can delete the session if needed, and there must be at least one.\n\tif(!validateAndSubmitOpenSessions()) return false;\n\tjQuery('#cc-3').foldPanel();\n\tpopulateSessionSelect();\n\treturn true;\n};\njQuery('#cc-3-valid-button').click(function(){\n\tif(!validateAndSubmitOpenSessions()) return;\n\tjQuery('#cc-3').foldPanel();\n\tjQuery('#cc-4').showPanel();\n\tpopulateSessionSelect();\n});\njQuery('#cc-3-add-button').click(function(){\n\tif(!validateAndSubmitOpenSessions()) return;\n\taddSession();\n});\n\njQuery('.mod-button').click(function() {\n\t// first close all the other panels, ensuring any data is saved.\n\tif(!validateCollectionPanel() || !validateStationPanel() || !validateSessionsPanel() || !validateInsectPanel())\n\t\treturn;\n\tjQuery('#cc-5').hidePanel();\n\tjQuery(this).parents('.poll-section-title').parent().unFoldPanel(); //slightly complicated because cc-1 contains the rest.\n});\n\n";
        $extraParams = $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'orderby' => 'taxon');
        $species_ctrl_args = array('label' => lang::get('LANG_Insect_Species'), 'fieldname' => 'insect:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'validation' => array('required'), 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $extraParams, 'suffixTemplate' => 'nosuffix');
        $r .= '
<div id="cc-4" class="poll-section">
  <div id="cc-4-title" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all poll-section-title">' . lang::get('LANG_Photos') . '
    <div id="cc-4-mod-button" class="right ui-state-default ui-corner-all mod-button">' . lang::get('LANG_Modify') . '</div>
  </div>
  <div id="cc-4-photo-reel" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-top ui-accordion-content-active photoReelContainer" >
  </div>
  <div id="cc-4-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active poll-section-body">  
    <div id="cc-4-insect">
	  <form id="cc-4-insect-upload" enctype="multipart/form-data" action="' . iform_ajaxproxy_url($node, 'media') . '" method="POST">
    		<input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
    		<input name="upload_file" type="file" class="required" />
    		<input type="submit" value="' . lang::get('LANG_Upload_Insect') . '" class="btn-submit" />
      </form>
 	  <div id="cc-4-insect-image" class="poll-image"></div>
 	  <div id="cc-4-insect-identify" class="poll-dummy-form">
 	    ' . iform_pollenators::help_button($use_help, "insect-help-button", $args['help_function'], $args['help_insect_arg']) . '
        <p><strong>' . lang::get('LANG_Identify_Insect') . '</strong></p>
        <label for="id-insect-later" class="follow-on">' . lang::get('LANG_ID_Insect_Later') . ' </label><input type="checkbox" id="id-insect-later" name="id-insect-later" /> 
		' . ($args['ID_tool_insect_url'] != '' && $args['ID_tool_insect_poll_dir'] ? '<label for="insect-id-button">' . lang::get('LANG_Insect_ID_Key_label') . ' :</label><span id="insect-id-button" class="ui-state-default ui-corner-all poll-id-button" >' . lang::get('LANG_Launch_ID_Key') . '</span>' : '') . '<span id="insect-id-cancel" class="ui-state-default ui-corner-all poll-id-cancel" >' . lang::get('LANG_Cancel_ID') . '</span>' . data_entry_helper::select($species_ctrl_args) . '
		<input type="text" name="insect:taxon_text_description" readonly="readonly">
      </div>
    </div>
    <div class="poll-break"></div> 
 	<form id="cc-4-main-form" action="' . iform_ajaxproxy_url($node, 'occurrence') . '" method="POST" >
    	<input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" id="occurrence_image:path" name="occurrence_image:path" value="" />
    	<input type="hidden" id="occurrence:record_status" name="occurrence:record_status" value="C" />
        <input type="hidden" name="occurrence:use_determination" value="Y"/>    
    	<input type="hidden" name="determination:taxa_taxon_list_id" value=""/> 
        <input type="hidden" name="determination:taxon_text_description" value=""/>  	
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />
    	<input type="hidden" name="determination:email_address" value="' . $email . '" />
    	<input type="hidden" name="determination:person_name" value="' . $username . '" /> 
        <input type="hidden" id="occurrence:id" name="occurrence:id" value="" disabled="disabled" />
	    <input type="hidden" id="determination:id" name="determination:id" value="" disabled="disabled" />
	    <input type="hidden" id="occurrence_image:id" name="occurrence_image:id" value="" disabled="disabled" />
	    <label for="occurrence:sample_id">' . lang::get('LANG_Session') . '</label>
	    <select id="occurrence:sample_id" name="occurrence:sample_id" value="" class="required" /></select>
	    ' . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence:comment', 'suffixTemplate' => 'nosuffix')) . data_entry_helper::outputAttribute($occurrence_attributes[$args['number_attr_id']], $defAttrOptions) . data_entry_helper::outputAttribute($occurrence_attributes[$args['foraging_attr_id']], $defAttrOptions) . '
    </form>
    <span id="cc-4-valid-insect-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate_Insect') . '</span>
    <span id="cc-4-delete-insect-button" class="ui-state-default ui-corner-all delete-button">' . lang::get('LANG_Delete_Insect') . '</span>
  </div>
  <div id="cc-4-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active poll-section-footer">
    <div id="cc-4-valid-photo-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate_Photos') . '</div>
  </div>
</div>
<div style="display:none" />
    <form id="cc-4-delete-insect" action="' . iform_ajaxproxy_url($node, 'occurrence') . '" method="POST">
       <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
       <input type="hidden" name="occurrence:use_determination" value="Y"/>    
       <input type="hidden" name="occurrence:id" value="" />
       <input type="hidden" name="occurrence:sample_id" value="" />
       <input type="hidden" name="occurrence:deleted" value="t" />
    </form>
</div>';
        data_entry_helper::$javascript .= "\nloadInsectPanel = null;\n\nvar insectTimer1;\nvar insectTimer2;\n\ninsectPoller = function(){\n\tinsectTimer1 = setTimeout('insectPoller();', " . $args['ID_tool_poll_interval'] . ");\n\t\$.get('" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['ID_tool_insect_poll_dir']) . session_id() . "_'+IDcounter.toString(), function(data){\n\tvar da = data.split('\\n');\n      // first count number of returned items.\n      // if > 1 put all into taxon_description.\n      // if = 1 rip out the description, remove the formatting, scan the flower select for it, and set the value. Set the taxon description.\n\t  da[1] = da[1].replace(/\\\\\\\\i\\{\\}/g, '').replace(/\\\\\\\\i0\\{\\}/g, '');\n      var items = da[1].split(':');\n\t  var count = items.length;\n\t  if(items[count-1] == '') count--;\n\t  if(count <= 0){\n\t  \t// no valid stuff so blank it all out.\n\t  \tjQuery('#cc-4-insect-identify > select[name=insect\\:taxa_taxon_list_id]').val('');\n\t  \tjQuery('#cc-4-flower-identify > select[name=insect\\:taxon_text_description]').val('');\n\t  } else if(count == 1){\n\t  \tjQuery('#cc-4-insect-identify > select[name=insect\\:taxa_taxon_list_id]').val('');\n\t  \tjQuery('#cc-4-insect-identify > select[name=insect\\:taxon_text_description]').val(items[0]);\n\t  \tvar x = jQuery('#cc-4-insect-identify').find('option').filter('[text='+items[0]+']');\n\t  \tif(x.length > 0){\n\t\t  \tjQuery('#cc-4-insect-identify > select[name=insect\\:taxon_text_description]').val('');\n\t  \t\tjQuery('#cc-4-insect-identify > select[name=insect\\:taxa_taxon_list_id]').val(x[0].value);\n  \t\t}\n\t  } else {\n\t  \tjQuery('#cc-4-insect-identify > select[name=insect\\:taxa_taxon_list_id]').val('');\n\t  \tjQuery('#cc-4-insect-identify > select[name=insect\\:taxon_text_description]').val(da[1]);\n\t  }\n\t  insectReset();\n    });\n};\ninsectReset = function(){\n\tclearTimeout(insectTimer1);\n\tclearTimeout(insectTimer2);\n\tjQuery('#insect-id-cancel').hide();\n};\n\njQuery('#insect-id-button').click(function(){\n\tIDcounter++;\n\tclearTimeout(insectTimer1);\n\tclearTimeout(insectTimer2);\n\twindow.open('" . $args['ID_tool_insect_url'] . session_id() . "_'+IDcounter.toString(),'','') \n\tinsectTimer1 = setTimeout('insectPoller();', " . $args['ID_tool_poll_interval'] . ");\n\tinsectTimer2 = setTimeout('insectReset();', " . $args['ID_tool_poll_timeout'] . ");\n\tjQuery('#insect-id-cancel').show();\n});\njQuery('#insect-id-cancel').click(function(){\n\tinsectReset();\n});\njQuery('#insect-id-cancel').hide();\n\n    \n// Insect upload picture form.\n\$('#cc-4-insect-upload').ajaxForm({ \n        dataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n        \tif(jQuery('#cc-4-insect-upload input[name=upload_file]').val() == '')\n        \t\treturn false;\n        \t\$('#cc-4-insect-image').empty();\n        \t\$('#cc-4-insect-image').addClass('loading')\n        },\n        success:   function(data){\n        \tif(data.success == true){\n\t        \t// There is only one file\n\t        \tjQuery('form#cc-4-main-form input[name=occurrence_image\\:path]').val(data.files[0]);\n\t        \tvar img = new Image();\n\t        \t\$(img).load(function () {\n        \t\t\t\t\$(this).hide();\n        \t\t\t\t\$('#cc-4-insect-image').removeClass('loading').append(this);\n        \t\t\t\t\$(this).fadeIn();\n\t\t\t    \t})\n\t\t\t\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+data.files[0])\n\t\t\t\t    .css('max-width', \$('#cc-4-insect-image').width()).css('max-height', \$('#cc-4-insect-image').height())\n\t\t\t\t    .css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\t\t\t\tjQuery('#cc-4-insect-upload input[name=upload_file]').val('');\n\t\t\t} else {\n\t\t\t\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\t        \tjQuery('form#cc-4-main-form input[name=occurrence_image\\:path]').val('');\n\t\t\t\t\$('#cc-4-insect-image').removeClass('loading');\n\t\t\t\tif(data.error){\n\t\t\t\t\terrorString = errorString + ' : ' + data.error;\n\t\t\t\t}\n\t\t\t\tif(data.errors){\n\t\t\t\t\tfor (var i in data.errors)\n\t\t\t\t\t{\n\t\t\t\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t\t\t\t}\t\t\t\t\n\t\t\t\t}\n\t\t\t\talert(errorString);\n\t\t\t}\n        } \n});\n\n\$('#cc-4-main-form').ajaxForm({ \n    dataType:  'json', \n    beforeSubmit:   function(data, obj, options){\n    \tvar valid = true;\n\t\tif (!jQuery('form#cc-4-main-form > input').valid()) { valid = false; }\n\t\tif (!validateRequiredField('occurrence\\:sample_id', 'form#cc-4-main-form')) { valid = false; }\n\t\tif (!validateRadio('occAttr\\:" . $args['number_attr_id'] . "', obj)) { valid = false; }\n    \tif(data[1].value == '' ){\n\t\t\talert(\"" . lang::get('LANG_Must_Provide_Insect_Picture') . "\");\n\t\t\tvalid = false;\n\t\t}\n\t\tdata[4].value = jQuery('select[name=insect\\:taxa_taxon_list_id]').val();\n\t\tdata[5].value = jQuery('select[name=insect\\:taxon_text_description]').val();\n\t\tif (jQuery('#id-insect-later').attr('checked') == ''){\n\t\t\tif (!validateRequiredField('insect\\:taxa_taxon_list_id', '#cc-4-insect-identify')) { valid = false; }\n\t\t} else {\n\t\t\tdata.splice(4,5); // remove determination entries.\n\t\t}\n\t\treturn valid;\n\t},\n    success:   function(data){\n       \tif(data.success == 'multiple records' && data.outer_table == 'occurrence'){\n       \t\t// if the currently highlighted thumbnail is blank, add the new insect.\n       \t\tvar thumbnail = jQuery('[occId='+data.outer_id+']');\n       \t\tif(thumbnail.length == 0){\n       \t\t\taddToPhotoReel(data.outer_id);\n       \t\t} else {\n       \t\t\tupdatePhotoReel(thumbnail, data.outer_id);\n  \t\t\t}\n\t\t\tif(loadInsectPanel == null){\n\t\t\t\tclearInsect();\n\t\t\t} else {\n\t\t\t\tloadInsect(loadInsectPanel);\n\t\t\t}\n\t\t\tloadInsectPanel=null;\n\t\t\twindow.scroll(0,0);\n        }\n\t}\n});\n\nvalidateInsectPanel = function(){\n\tif(jQuery('#cc-4').filter('.poll-hide').length > 0) return true; // panel is not visible so no data to fail validation.\n\tif(jQuery('#cc-4-body').filter('.poll-hide').length > 0) return true; // body hidden so data already been validated successfully.\n\tif(!validateInsect()){ return false; }\n  \tjQuery('#cc-4').foldPanel();\n\treturn true;\n};\n\nclearInsect = function(){\n\tjQuery('#cc-4-main-form').resetForm();\n\tjQuery('[name=insect\\:taxa_taxon_list_id]').val('');\n\tjQuery('[name=insect\\:taxon_text_description]').val('');\n    jQuery('#id-insect-later').removeAttr('checked').removeAttr('disabled');\n    jQuery('#cc-4-main-form').find('[name=determination:cms_ref]').val('" . $uid . "');\n    jQuery('#cc-4-main-form').find('[name=determination:email_address]').val('" . $email . "');\n    jQuery('#cc-4-main-form').find('[name=determination:person_name]').val('" . $username . "'); \n    jQuery('#cc-4-main-form').find('[name=occurrence_image\\:path]').val('');\n\tjQuery('#cc-4-main-form').find('[name=occurrence\\:id],[name=occurrence_image\\:id],[name=determination\\:id]').val('').attr('disabled', 'disabled');\n    jQuery('#cc-4-main-form').find('[name=occurrence_image\\:path]').val('');\n\tjQuery('#cc-4-main-form').find('[name^=occAttr\\:]').each(function(){\n\t\tvar name = jQuery(this).attr('name').split(':');\n\t\tjQuery(this).attr('name', name[0]+':'+name[1]);\n\t});\n    jQuery('#cc-4-insect-image').empty();\n};\n\nloadInsect = function(id){\n\tclearInsect();\n\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" + id +\n          \"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&callback=?\", function(data) {\n\t    if (data.length>0) {\n\t        jQuery('form#cc-4-main-form > input[name=occurrence\\:id]').removeAttr('disabled').val(data[0].id);\n\t        jQuery('form#cc-4-main-form > [name=occurrence\\:sample_id]').val(data[0].sample_id);\n\t\t\tjQuery('form#cc-4-main-form > textarea[name=occurrence\\:comment]').val(data[0].comment);\n\t\t\tloadAttributes('occurrence_attribute_value', 'occurrence_attribute_id', 'occurrence_id', 'occurrence\\:id', data[0].id, 'occAttr');\n    \t\tloadImage('occurrence_image', 'occurrence_id', 'occurrence\\:id', data[0].id, '#cc-4-insect-image');\n  \t\t}\n\t});\n\t\$.getJSON(\"" . $svcUrl . "/data/determination?occurrence_id=\" + id +\n          \"&mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&callback=?\", function(data) {\n\t    if (data.length>0) {\n\t    \tjQuery('#id-insect-later').removeAttr('checked').attr('disabled', 'disabled');\n\t        jQuery('form#cc-4-main-form > input[name=determination\\:id]').removeAttr('disabled').val(data[0].id);\n\t        jQuery('form#cc-4-main-form > input[name=determination\\:cms_ref]').val(data[0].cms_ref);\n\t        jQuery('form#cc-4-main-form > input[name=determination\\:email_address]').val(data[0].email_address);\n\t        jQuery('form#cc-4-main-form > input[name=determination\\:person_name]').val(data[0].person_name);\n       \t\tjQuery('[name=insect\\:taxa_taxon_list_id]').val(data[0].taxa_taxon_list_id);\n       \t\tjQuery('[name=insect\\:taxon_text_description]').val(data[0].taxon_text_description);\n  \t\t} else\n  \t\t\tjQuery('#id-insect-later').attr('checked', 'checked').removeAttr('disabled');\n\t});\t\n}\n\nupdatePhotoReel = function(container, occId){\n\tcontainer.empty();\n\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_image\" +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&occurrence_id=\" + occId + \"&callback=?\", function(imageData) {\n\t\tif (imageData.length>0) {\n\t\t\tvar img = new Image();\n\t\t\tjQuery(img).attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "thumb-'+imageData[0].path)\n\t\t\t    .attr('width', container.width()).attr('height', container.height()).addClass('thumb-image').appendTo(container);\n\t\t}\n\t});\n\t\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n    \t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n    \t\t\"&occurrence_id=\" + occId + \"&deleted=f&callback=?\", function(detData) {\n\t    if (detData.length==0) {\n\t    \t// no determination records, so no attempt made at identification. Put up a question mark.\n\t\t\tjQuery('<span>?</span>').addClass('thumb-text').appendTo(container);\n\t\t}\n\t});\n}\n\naddToPhotoReel = function(occId){\n\t// last photo in list is the blank empty one. Add to just before this.\n\tvar container = jQuery('<div/>').addClass('thumb').insertBefore('.blankPhoto').attr('occId', occId.toString()).click(function () {setInsect(this, occId)});\n\tupdatePhotoReel(container, occId);\n}\n\nsetInsect = function(context, id){\n\t// first close all the other panels, ensuring any data is saved.\n\tif(!validateCollectionPanel() || !validateStationPanel() || !validateSessionsPanel())\n\t\treturn;\n\t\t\n\tif(jQuery('#cc-4-body').filter('.poll-hide').length > 0) {\n\t\tjQuery('div#cc-4').unFoldPanel();\n\t\tloadInsect(id);\n\t} else {\n\t\tloadInsectPanel=id;\n\t\tif(!validateInsect()){\n\t\t\tloadInsectPanel=null;\n\t\t\treturn;\n\t\t} \n\t}\n\tjQuery('.currentPhoto').removeClass('currentPhoto');\n\tjQuery('[occId='+id+']').addClass('currentPhoto');\n};\n\nsetNoInsect = function(){\n\t// first close all the other panels, ensuring any data is saved.\n\tif(!validateCollectionPanel() || !validateStationPanel() || !validateSessionsPanel())\n\t\treturn;\n\t\t\n\tif(jQuery('#cc-4-body').filter('.poll-hide').length > 0)\n\t\tjQuery('div#cc-4').unFoldPanel();\n\telse\n\t\tif(!validateInsect()){ return ; }\n\t// At this point the empty panel is displayed, as it is reset after a successful validate.\t\n\tjQuery('.currentPhoto').removeClass('currentPhoto');\n\tjQuery('.blankPhoto').addClass('currentPhoto');\n};\n\ncreatePhotoReel = function(div){\n\tjQuery(div).empty();\n\tjQuery('<div/>').addClass('blankPhoto thumb currentPhoto').appendTo(div).click(setNoInsect);\n}\n\ncreatePhotoReel('#cc-4-photo-reel');\n\n// TODO separate photoreel out into own js\n\nvalidateInsect = function(){\n\t// TODO will have to expand when use key.\n\tif(jQuery('form#cc-4-main-form > input[name=occurrence\\:id]').val() == '' &&\n\t\t\tjQuery('form#cc-4-main-form > input[name=occurrence_image\\:path]').val() == '' &&\n\t\t\tjQuery('[name=insect\\:taxa_taxon_list_id]').val() == '' &&\n\t\t\tjQuery('form#cc-4-main-form > textarea[name=occurrence\\:comment]').val() == '' &&\n\t\t\tjQuery('[name=occAttr\\:" . $args['number_attr_id'] . "],[name^=occAttr\\:" . $args['number_attr_id'] . "\\:]').filter('[checked]').length == 0){\n\t\tif(loadInsectPanel != null){\n\t\t\tloadInsect(loadInsectPanel);\n\t\t}\n\t\tloadInsectPanel=null;\n\t\treturn true;\n\t}\n\tvar valid = true;\n    if (!jQuery('form#cc-4-main-form > input').valid()) { return false; }\n  \tif (!validateRadio('occAttr\\:" . $args['number_attr_id'] . "', 'form#cc-4-main-form')) { valid = false; }\n\t\tif (jQuery('#id-insect-later').attr('checked') == ''){\n\t\t\tif (!validateRequiredField('insect\\:taxa_taxon_list_id', '#cc-4-insect-identify')) { valid = false; }\n\t\t}\n \tif (!validateRequiredField('occurrence\\:sample_id', 'form#cc-4-main-form')) { valid = false; }\n\tif(jQuery('form#cc-4-main-form input[name=occurrence_image\\:path]').val() == ''){\n\t\talert(\"" . lang::get('LANG_Must_Provide_Insect_Picture') . "\");\n\t\tvalid = false;;\n\t}\n\tif(valid == false) return false;\n\tjQuery('form#cc-4-main-form').submit();\n\treturn true;\n  }\n\n\$('#cc-4-valid-insect-button').click(validateInsect);\n\n\$('#cc-4-delete-insect-button').click(function() {\n\tvar container = \$(this).parent().parent();\n\tjQuery('#cc-4-delete-insect').find('[name=occurrence\\:id]').val(jQuery('#cc-4-main-form').find('[name=occurrence\\:id]').val());\n\tjQuery('#cc-4-delete-insect').find('[name=occurrence\\:sample_id]').val(jQuery('#cc-4-main-form').find('[name=occurrence\\:sample_id]').val());\n\tif(confirm(\"" . lang::get('LANG_Confirm_Insect_Delete') . "\")){\n\t\tif(jQuery('#cc-4-main-form').find('[name=occurrence\\:id]').filter('[disabled]').length == 0){\n\t\t\tjQuery('#cc-4-delete-insect').submit();\n\t\t\tjQuery('.currentPhoto').remove();\n\t\t\tjQuery('.blankPhoto').addClass('currentPhoto');\n\t\t}\n\t\tclearInsect();\n\t}\n});\n\n\$('#cc-4-delete-insect').ajaxForm({ \n        dataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n  \t\t\t// Warning this assumes that the data is fixed position:\n        \tif(data[2].value == '') return false;\n        \treturn true;\n  \t\t},\n        success:   function(data){\n  \t\t} \n});\n\n\$('#cc-4-valid-photo-button').click(function(){\n\tif(!validateInsect()) return;\n\tjQuery('#cc-4').foldPanel();\n\tjQuery('#cc-5').showPanel();\n\tvar numInsects = jQuery('#cc-4-photo-reel').find('.thumb').length - 1; // ignore blank\n\tvar numUnidentified = jQuery('#cc-4-photo-reel').find('.thumb-text').length;\n\tif(jQuery('#id-flower-later').attr('checked') != '' || numInsects==0 || (numUnidentified/numInsects > (1-(" . $args['percent_insects'] . "/100.0)))){\n\t\tjQuery('#cc-5-good').hide();\n\t\tjQuery('#cc-5-bad').show();\n\t\tjQuery('#cc-5-complete-collection').hide();\n\t\tjQuery('#cc-5-trailer').hide();\n    } else {\n    \tjQuery('#cc-5-good').show();\n\t\tjQuery('#cc-5-bad').hide();\n\t\tjQuery('#cc-5-complete-collection').show();\n\t\tjQuery('#cc-5-trailer').show();\n\t}\n});\n";
        $r .= '
<div id="cc-5" class="poll-section">
  <div id="cc-5-body" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all poll-section-body"> 
   <p id="cc-5-good">' . lang::get('LANG_Can_Complete_Msg') . '</p> 
   <p id="cc-5-bad">' . lang::get('LANG_Cant_Complete_Msg') . '</p> 
   <div style="display:none" />
    <form id="cc-5-collection" action="' . iform_ajaxproxy_url($node, 'sample') . '" method="POST">
       <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
       <input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '" />
       <input type="hidden" name="sample:id" value="" />
       <input type="hidden" name="sample:date" value="2010-01-01"/>
       <input type="hidden" name="sample:location_id" value="" />
       <input type="hidden" id="smpAttr:' . $args['complete_attr_id'] . '" name="smpAttr:' . $args['complete_attr_id'] . '" value="1" />
    </form>
   </div>
   <div id="cc-5-complete-collection" class="ui-state-default ui-corner-all complete-button">' . lang::get('LANG_Complete_Collection') . '</div>
  </div>
  <div id="cc-5-trailer" class="poll-section-trailer">
    <p>' . lang::get('LANG_Trailer_Head') . '</p>
    <ul>
      <li>' . lang::get('LANG_Trailer_Point_1') . '</li>
      <li>' . lang::get('LANG_Trailer_Point_2') . '</li>
      <li>' . lang::get('LANG_Trailer_Point_3') . '</li>
      <li>' . lang::get('LANG_Trailer_Point_4') . '</li>
    </ul>
  </div>
</div>';
        data_entry_helper::$javascript .= "\n\$('#cc-5-collection').ajaxForm({ \n        dataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n       \t\tdata[2].value = jQuery('#cc-1-collection-details input[name=sample\\:id]').val();\n       \t\tvar date_start = '';\n       \t\tvar date_end = '';\n       \t\tjQuery('.poll-session').find('[name=sample\\:date]').each(function(index, el){\n       \t\t\tvar value = \$(this).val();\n       \t\t\tif(date_start == '' || date_start > value) {\n       \t\t\t\tdate_start = value;\n       \t\t\t}\n       \t\t\tif(date_end == '' || date_end < value) {\n       \t\t\t\tdate_end = value;\n       \t\t\t}\n  \t\t\t});\n  \t\t\tif(date_start == date_end){\n\t       \t\tdata[3].value = date_start;\n\t       \t} else {\n\t       \t\tdata[3].value = date_start+' to '+date_end;\n  \t\t\t}\n\t       \tjQuery('[name=sample\\:date]:hidden').val(data[3].value);\n  \t\t\tdata[4].value = jQuery('#cc-1-collection-details input[name=location\\:id]').val();\n       \t\tdata[5].name = jQuery('#cc-1-collection-details input[name^=smpAttr\\:" . $args['complete_attr_id'] . "\\:]').attr('name');\n        \treturn true;\n  \t\t},\n        success:   function(data){\n\t\t\t\$('#cc-6').showPanel();\n  \t\t} \n});\n\$('#cc-5-complete-collection').click(function(){\n\tjQuery('#cc-2,#cc-3,#cc-4,#cc-5').hidePanel();\n\tjQuery('.reinit-button').hide();\n\tjQuery('.mod-button').hide();\n\tjQuery('#cc-5-collection').submit();\n});\n";
        $r .= '
<div id="cc-6" class="poll-section">
  <div id="cc-6-body" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top poll-section-body"> 
   <p>' . lang::get('LANG_Final_1') . '</p> 
   <p>' . lang::get('LANG_Final_2') . '</p> 
   </div>
  <div id="cc-6-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active poll-section-footer">
    <a id="cc-6-consult-collection" href="" class="ui-state-default ui-corner-all link-button">' . lang::get('LANG_Consult_Collection') . '</a>
    <a href="' . url('node/' . $node->nid) . '" class="ui-state-default ui-corner-all link-button">' . lang::get('LANG_Create_New_Collection') . '</a>
  </div>
</div>
</div></div>';
        data_entry_helper::$javascript .= "\n \t\t\t\nloadAttributes = function(attributeTable, attributeKey, key, keyName, keyValue, prefix){\n\tvar form = jQuery('input[name='+keyName+'][value='+keyValue+']').parent();\n\tvar checkboxes = jQuery('[name^='+prefix+'\\:]', form).filter(':checkbox').removeAttr('checked');\n\tcheckboxes.each(function(){\n\t\tvar name = jQuery(this).attr('name').split(':');\n\t\tif(name.length > 2)\n\t\t\tjQuery(this).attr('name', name[0]+':'+name[1]+'[]');\n\t});\n\t\n\t\$.getJSON(\"" . $svcUrl . "/data/\" + attributeTable +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\", function(attrdata) {\n\t\tif (attrdata.length>0) {\n\t\t\tvar form = jQuery('input[name='+keyName+'][value='+keyValue+']').parent();\n\t\t\tfor (var i=0;i<attrdata.length;i++){\n\t\t\t\tif (attrdata[i].id && (attrdata[i].iso == null || attrdata[i].iso == '' || attrdata[i].iso == '" . $language . "')){\n\t\t\t\t\tvar checkboxes = jQuery('[name='+prefix+'\\:'+attrdata[i][attributeKey]+'\\[\\]],[name^='+prefix+'\\:'+attrdata[i][attributeKey]+':]', form).filter(':checkbox');\n\t\t\t\t\tvar radiobuttons = jQuery('[name='+prefix+'\\:'+attrdata[i][attributeKey]+'],[name^='+prefix+'\\:'+attrdata[i][attributeKey]+':]', form).filter(':radio');\n\t\t\t\t\tif(radiobuttons.length > 0){\n\t\t\t\t\t\tradiobuttons\n\t\t\t\t\t\t\t.attr('name', prefix+':'+attrdata[i][attributeKey]+':'+attrdata[i].id)\n\t\t\t\t\t\t\t.filter('[value='+attrdata[i].raw_value+']')\n\t\t\t\t\t\t\t.attr('checked', 'checked');\n\t\t\t\t\t} else \tif(checkboxes.length > 0){\n\t\t\t\t\t\tvar checkbox = checkboxes.filter('[value='+attrdata[i].raw_value+']')\n\t\t\t\t\t\t\t.attr('name', prefix+':'+attrdata[i][attributeKey]+':'+attrdata[i].id)\n\t\t\t\t\t\t\t.attr('checked', 'checked');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tjQuery('[name='+prefix+'\\:'+attrdata[i][attributeKey]+']', form)\n\t\t\t\t\t\t\t.attr('name', prefix+':'+attrdata[i][attributeKey]+':'+attrdata[i].id)\n\t\t\t\t\t\t\t.val(attrdata[i].raw_value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcheckProtocolStatus();\n\t\tpopulateSessionSelect();\n\t});\n}\n\nloadImage = function(imageTable, key, keyName, keyValue, target){\n\t\t\t\t\t// location_image, location_id, location:id, 1, #cc-4-insect-image\n\t\$.getJSON(\"" . $svcUrl . "/data/\" + imageTable +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\", function(imageData) {\n\t\tif (imageData.length>0) {\n\t\t\tvar form = jQuery('input[name='+keyName+'][value='+keyValue+']').parent();\n\t\t\tjQuery('[name='+imageTable+'\\:id]', form).val(imageData[0].id).removeAttr('disabled');\n\t\t\tjQuery('[name='+imageTable+'\\:path]', form).val(imageData[0].path);\n\t\t\tvar img = new Image();\n\t\t\t\$(img).load(function () {\n        \t\t\t\$(target).empty().append(this);\n\t\t\t    })\n\t\t\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+imageData[0].path)\n\t\t\t\t.css('max-width', \$(target).width()).css('max-height', \$(target).height()).css('display', 'block')\n\t\t\t\t.css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto');\n\t\t}\n\t});\n}\n\n// load in any existing incomplete collection.\n// general philosophy is that you are taken back to the stage last verified.\n// Load in the first if there are more than one. Use the internal report which provides my collections.\n// Requires that there is an attribute for completeness, and one for the CMS\n// load the data in the order it is entered, so can stop when get to the point where the user finished.\n// have to reset the entire form first...\njQuery('.poll-section').resetPanel();\n// Default state: hide everything except the collection details block.\njQuery('.poll-section').hidePanel();\njQuery('#cc-1').showPanel();\njQuery('.reinit-button').hide();\naddSession();\n\njQuery.getJSON(\"" . $svcUrl . "\" + \"/report/requestReport?report=poll_my_collections.xml&reportSource=local&mode=json\" +\n\t\t\t\"&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "\" + \n\t\t\t\"&survey_id=" . $args['survey_id'] . "&userID_attr_id=" . $args['uid_attr_id'] . "&userID=" . $uid . "&complete_attr_id=" . $args['complete_attr_id'] . "&callback=?\", function(data) {\n\tif (data.length>0) {\n\t\tvar i;\n       \tfor ( i=0;i<data.length;i++) {\n       \t\tif(data[i].completed == '0'){\n       \t\t    jQuery('#cc-6-consult-collection').attr('href', '" . url('node/' . $args['gallery_node']) . "'+'?collection_id='+data[i].id);\n       \t\t\t// load up collection details: existing ID, location name and protocol\n       \t\t\tjQuery('#cc-1-collection-details,#cc-2').find('input[name=sample\\:id]').val(data[i].id).removeAttr('disabled');\n       \t\t\t// main sample date is only set when collection is completed, so leave default.\n       \t\t\tloadAttributes('sample_attribute_value', 'sample_attribute_id', 'sample_id', 'sample\\:id', data[i].id, 'smpAttr');\n  \t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/location/\" + data[i].location_id +\n          \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n          \t\t\t\t\t\"&callback=?\", function(locationdata) {\n\t\t    \t\tif (locationdata.length>0) {\n\t\t    \t\t\tjQuery('input[name=location\\:id]').val(locationdata[0].id).removeAttr('disabled');\n\t    \t\t\t\tjQuery('input[name=location\\:name]').val(locationdata[0].name);\n       \t\t\t\t\tjQuery('input[name=sample\\:location_name]').val(locationdata[0].name); // make sure the 2 coincide\n\t    \t\t\t\t// NB the location geometry is stored in centroid, due to restrictions in location model.\n\t    \t\t\t\tjQuery('input[name=location\\:centroid_sref]').val(locationdata[0].centroid_sref);\n\t    \t\t\t\tjQuery('input[name=location\\:centroid_sref_system]').val(locationdata[0].centroid_sref_system);\n\t    \t\t\t\tjQuery('input[name=location\\:centroid_geom]').val(locationdata[0].centroid_geom);\n\t    \t\t\t\tjQuery('input[name=locations_website\\:website_id]').attr('disabled', 'disabled');\n\t    \t\t\t\tloadAttributes('location_attribute_value', 'location_attribute_id', 'location_id', 'location\\:id', locationdata[0].id, 'locAttr');\n    \t   \t\t\t\tloadImage('location_image', 'location_id', 'location\\:id', locationdata[0].id, '#cc-2-environment-image');\n\t\t\t\t\t\tjQuery('#imp-sref').change();\n\t\t\t\t        var parts=locationdata[0].centroid_sref.split(' ');\n \t\t\t\t\t\tjQuery('input[name=place\\:lat]').val(parts[0]);\n\t\t\t\t\t\tjQuery('input[name=place\\:long]').val(parts[1]);\n  \t\t\t\t\t}\n  \t\t\t\t});\n  \t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n          \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n          \t\t\t\t\t\"&sample_id=\"+data[i].id+\"&callback=?\", function(flowerData) {\n          \t\t\t// there will only be an occurrence if the floral station panel has previously been displayed & validated. \n\t\t    \t\tif (flowerData.length>0) {\n  \t\t\t\t\t\t\$('#cc-1').foldPanel();\n  \t\t\t\t\t\t\$('#cc-2').showPanel();\n\t\t    \t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence\\:sample_id]').val(data[i].id);\n\t\t    \t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence\\:id]').val(flowerData[0].id).removeAttr('disabled');\n\t\t    \t\t\tloadAttributes('occurrence_attribute_value', 'occurrence_attribute_id', 'occurrence_id', 'occurrence\\:id', flowerData[0].id, 'occAttr');\n    \t   \t\t\t\tloadImage('occurrence_image', 'occurrence_id', 'occurrence\\:id', flowerData[0].id, '#cc-2-flower-image');\n\n    \t   \t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n    \t      \t\t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&occurrence_id=\"+flowerData[0].id+\"&deleted=f&callback=?\",\n    \t      \t\t\t\t\tfunction(detData) {\n\t    \t\t\t  \t\tif (detData.length>0) {\n\t\t\t\t\t\t\t\tjQuery('#id-flower-later').removeAttr('checked').attr('disabled', 'disabled');\n\t    \t\t\t  \t\t\tjQuery('form#cc-2-floral-station > input[name=determination\\:id]').val(detData[0].id).removeAttr('disabled');\n\t\t    \t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=determination\\:cms_ref]').val(detData[0].cms_ref);\n\t\t\t\t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=determination\\:email_address]').val(detData[0].email_address);\n\t\t\t\t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=determination\\:person_name]').val(detData[0].person_name);\n\t\t\t\t\t\t\t\tjQuery('select[name=flower\\:taxa_taxon_list_id]').val(detData[0].taxa_taxon_list_id);\n\t\t\t\t\t\t\t\tjQuery('select[name=flower\\:taxon_text_description]').val(detData[0].taxon_text_description);\n  \t\t\t\t\t\t\t} else {\n\t    \t\t\t  \t\t\tjQuery('form#cc-2-floral-station > input[name=determination\\:id]').val('').attr('disabled', 'disabled');\n\t\t\t\t\t\t\t\tjQuery('#id-flower-later').attr('checked', 'checked').removeAttr('disabled');\n\t\t\t\t\t\t\t}\n  \t\t\t\t\t\t});\n\n    \t   \t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/sample\" + \n    \t      \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&parent_id=\"+data[i].id+\"&callback=?\", function(sessiondata) {\n\t    \t\t\t  \t\tif (sessiondata.length>0) {\n\t\t\t\t\t\t\t\tjQuery('#cc-2').foldPanel();\n\t\t\t\t\t\t\t\tsessionCounter = 0;\n\t\t\t\t\t\t\t\tjQuery('#cc-3-body').empty();\n \t\t\t\t\t\t\t\t\$('#cc-3').showPanel();\n\t\t\t\t\t\t\t\tfor (var i=0;i<sessiondata.length;i++){\n\t\t\t\t\t\t\t\t\tvar thisSession = addSession();\n\t\t\t\t\t\t\t\t\tjQuery('input[name=sample\\:id]', thisSession).val(sessiondata[i].id).removeAttr('disabled');\n\t\t\t\t\t\t\t\t\tjQuery('input[name=sample\\:date]', thisSession).val(sessiondata[i].date_start);\n       \t\t\t\t\t\t\t\tloadAttributes('sample_attribute_value', 'sample_attribute_id', 'sample_id', 'sample\\:id', sessiondata[i].id, 'smpAttr');\n  \t\t\t\t\t\t\t\t\t// fold this session.\n  \t\t\t\t\t\t\t\t\tthisSession.show();\n\t\t\t\t\t\t\t\t\tthisSession.children(':first').show().children().show();\n\t\t\t\t\t\t\t\t\tthisSession.children().not(':first').hide();\n\t\t\t\t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n          \t\t\t\t\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&orderby=id\" +\n          \t\t\t\t\t\t\t\t\t\"&sample_id=\"+sessiondata[i].id+\"&callback=?\", function(insectData) {\n\t\t    \t\t\t\t\t\t\tif (insectData.length>0) {\n \t\t\t\t\t\t\t\t\t\t\tfor (var j=0;j<insectData.length;j++){\n\t\t\t\t\t\t\t\t\t\t\t\taddToPhotoReel(insectData[j].id);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t    \t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n \t\t\t\t\t\t\t\t\$('#cc-3').foldPanel();\n \t\t\t\t\t\t\t\t\$('#cc-4').showPanel();\n\t\t\t\t\t\t\t\tpopulateSessionSelect();\n \t\t\t\t\t  \t\t}\n \t\t\t\t\t  \t\t\$('.loading-panel').remove();\n\t\t\t\t\t\t\t\$('.loading-hide').removeClass('loading-hide');\n\t\t\t\t\t\t});\n    \t   \t\t\t} else {\n    \t   \t\t\t\t\$('.loading-panel').remove();\n\t\t\t\t\t\t\$('.loading-hide').removeClass('loading-hide');\n    \t   \t\t\t}\n  \t\t\t\t});\n\t\t\t\t// only use the first one which is not complete..\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (i >= data.length) {\n\t\t\t\$('.loading-panel').remove();\n\t\t\t\$('.loading-hide').removeClass('loading-hide');\n  \t\t}\n\t} else {\n\t\t\$('.loading-panel').remove();\n\t\t\$('.loading-hide').removeClass('loading-hide');\n\t}\n});\n  \n  ";
        // because of the use of getJson to retrieve the data - which is asynchronous, the use of the normal loading_block_end
        // is not practical - it will do its stuff before the data is loaded, defeating the purpose. Also it uses hide (display:none)
        // which is a no-no in relation to the map. This means we have to dispense with the slow fade in.
        // it is also complicated by the attibutes and images being loaded asynchronously - and non-linearly.
        // Do the best we can!
        data_entry_helper::$onload_javascript .= "jQuery('#map')[0].map.searchLayer.events.register('featuresadded', {}, function(a1){\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroyFeatures();\n});\njQuery('#map')[0].map.editLayer.events.register('featuresadded', {}, function(a1){\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroy();\n\t\t\n  \tvar filter = new OpenLayers.Filter.Spatial({\n  \t\t\ttype: OpenLayers.Filter.Spatial.CONTAINS ,\n    \t\tproperty: 'the_geom',\n    \t\tvalue: jQuery('#map')[0].map.editLayer.features[0].geometry\n  \t\t});\n\n\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\tvar styleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Red\",\n                    strokeColor: \"Red\",\n                    fillOpacity: 0,\n                    strokeWidth: 1\n                  })\n\t});\n\tinseeLayer = new OpenLayers.Layer.Vector('INSEE Layer', {\n\t\t  styleMap: styleMap,\n          strategies: [strategy],\n          displayInLayerSwitcher: false,\n\t      protocol: new OpenLayers.Protocol.WFS({\n              url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n\t          featurePrefix: '" . $args['INSEE_prefix'] . "',\n              featureType: '" . $args['INSEE_type'] . "',\n              geometryName:'the_geom',\n              featureNS: '" . $args['INSEE_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0'                  \n      \t\t  ,propertyNames: ['the_geom', 'NOM', 'INSEE_NEW', 'DEPT_NUM', 'DEPT_NOM', 'REG_NUM', 'REG_NOM']\n  \t\t\t})\n    });\n    inseeLayer.events.register('featuresadded', {}, function(a1){\n    \tjQuery('#cc-2-loc-description').empty();\n    \tjQuery('<span>'+a1.features[0].attributes.NOM+' ('+a1.features[0].attributes.INSEE_NEW+'), '+a1.features[0].attributes.DEPT_NOM+' ('+a1.features[0].attributes.DEPT_NUM+'), '+a1.features[0].attributes.REG_NOM+' ('+a1.features[0].attributes.REG_NUM+')</span>').appendTo('#cc-2-loc-description');\n    });\n\tjQuery('#map')[0].map.addLayer(inseeLayer);\n\tstrategy.load({filter: filter});\n});\n\n";
        global $indicia_templates;
        $r .= $indicia_templates['loading_block_end'];
        return $r;
    }
Exemplo n.º 8
0
 /**
  * Outputs a pair of linked selects, for picking a prebuilt form from the library. The first select is for picking a form 
  * category and the second select is populated by AJAX for picking the actual form.
  * @param array $options Options array with the following possibilities:<ul>
  * <li><b>form</b><br/>
  * Optional. The name of the form to select as a default value.</li>
  * <li><b>includeOutputDiv</b><br/>
  * Set to true to generate a div after the controls which will receive the form parameter
  * controls when a form is selected.</li>
  * <li><b>needWebsiteInputs</b><br/>
  * Defaults to false. In this state, the website ID and password controls are not displayed
  * when both the values are already specified, though hidden inputs are put into the form.
  * When set to true, the website ID and password input controls are always included in the form output.
  * </li>
  * </ul>
  */
 public static function prebuilt_form_picker($options)
 {
     require_once 'data_entry_helper.php';
     form_helper::add_resource('jquery_ui');
     $path = dirname($_SERVER['SCRIPT_FILENAME']) . '/' . self::relative_client_helper_path();
     $r = '';
     if (!($dir = opendir($path . 'prebuilt_forms/'))) {
         throw new Exception('Cannot open path to prebuilt form library.');
     }
     while (false !== ($file = readdir($dir))) {
         $parts = explode('.', $file);
         if ($file != "." && $file != ".." && strtolower($parts[count($parts) - 1]) == 'php') {
             require_once $path . 'prebuilt_forms/' . $file;
             $file_tokens = explode('.', $file);
             ob_start();
             if (is_callable(array('iform_' . $file_tokens[0], 'get_' . $file_tokens[0] . '_definition'))) {
                 $definition = call_user_func(array('iform_' . $file_tokens[0], 'get_' . $file_tokens[0] . '_definition'));
                 $definition['title'] = lang::get($definition['title']);
                 $forms[$definition['category']][$file_tokens[0]] = $definition;
                 if (isset($options['form']) && $file_tokens[0] == $options['form']) {
                     $defaultCategory = $definition['category'];
                 }
             } elseif (is_callable(array('iform_' . $file_tokens[0], 'get_title'))) {
                 $title = call_user_func(array('iform_' . $file_tokens[0], 'get_title'));
                 $forms['Miscellaneous'][$file_tokens[0]] = array('title' => $title);
                 if (isset($options['form']) && $file_tokens[0] == $options['form']) {
                     $defaultCategory = 'Miscellaneous';
                 }
             }
             ob_end_clean();
         }
     }
     if (isset($defaultCategory)) {
         $availableForms = array();
         foreach ($forms[$defaultCategory] as $form => $def) {
             $availableForms[$form] = $def['title'];
         }
     } else {
         $defaultCategory = '';
         $availableForms = array('' => '&lt;Please select a category first&gt;');
     }
     closedir($dir);
     // makes an assoc array from the categories.
     $categories = array_merge(array('' => '&lt;Please select&gt;'), array_combine(array_keys($forms), array_keys($forms)));
     // translate categories
     foreach ($categories as $key => &$value) {
         $value = lang::get($value);
     }
     asort($categories);
     if (isset($options['needWebsiteInputs']) && !$options['needWebsiteInputs'] && !empty($options['website_id']) && !empty($options['password'])) {
         $r .= '<input type="hidden" id="website_id" name="website_id" value="' . $options['website_id'] . '">';
         $r .= '<input type="hidden" id="password" name="password" value="' . $options['password'] . '">';
     } else {
         $r .= data_entry_helper::text_input(array('label' => lang::get('Website ID'), 'fieldname' => 'website_id', 'helpText' => lang::get('Enter the ID of the website record on the Warehouse you are using.'), 'default' => isset($options['website_id']) ? $options['website_id'] : ''));
         $r .= data_entry_helper::text_input(array('label' => lang::get('Password'), 'fieldname' => 'password', 'helpText' => lang::get('Enter the password for the website record on the Warehouse you are using.'), 'default' => isset($options['password']) ? $options['password'] : ''));
     }
     $r .= data_entry_helper::select(array('id' => 'form-category-picker', 'label' => lang::get('Select Form Category'), 'helpText' => lang::get('Select the form category pick a form from.'), 'lookupValues' => $categories, 'default' => $defaultCategory));
     $r .= data_entry_helper::select(array('id' => 'form-picker', 'fieldname' => 'iform', 'label' => lang::get('Select Form'), 'helpText' => lang::get('Select the Indicia form you want to use.'), 'lookupValues' => $availableForms, 'default' => isset($options['form']) ? $options['form'] : ''));
     // div for the form instructions
     $details = '';
     if (isset($options['form'])) {
         if (isset($forms[$defaultCategory][$options['form']]['description'])) {
             $details .= '<p>' . $forms[$defaultCategory][$options['form']]['description'] . '</p>';
         }
         if (isset($forms[$defaultCategory][$options['form']]['helpLink'])) {
             $details .= '<p><a href="' . $forms[$defaultCategory][$options['form']]['helpLink'] . '">Find out more...</a></p>';
         }
         if ($details !== '') {
             $details = "<div class=\"ui-state-highlight ui-corner-all page-notice\">{$details}</div>";
         }
     }
     $r .= "<div id=\"form-def\">{$details}</div>\n";
     $r .= '<input type="button" value="' . lang::get('Load Settings Form') . '" id="load-params" disabled="disabled" />';
     if (isset($options['includeOutputDivs']) && $options['includeOutputDivs']) {
         $r .= '<div id="form-params"></div>';
     }
     self::add_form_picker_js($forms);
     return $r;
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     $conn = iform_get_connection_details($node);
     data_entry_helper::$js_read_tokens = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']);
     if (!empty($_POST) && !empty($_POST['format'])) {
         self::do_data_services_download($args, $node);
     }
     $conn = iform_get_connection_details($node);
     data_entry_helper::$js_read_tokens = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']);
     $types = self::get_download_types($args);
     $formats = self::get_download_formats($args);
     if (count($types) === 0) {
         return 'This download page is configured so that no download type options are available.';
     }
     if (count($formats) === 0) {
         return 'This download page is configured so that no download format options are available.';
     }
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         $reloadPath .= '?' . helper_base::array_to_query_string($reload['params']);
     }
     $r = '<form method="POST" action="' . $reloadPath . '">';
     $r .= '<fieldset id="download-type-fieldset"><legend>' . lang::get('Records to download') . '</legend>';
     if (count($types) === 1) {
         $r .= '<input type="hidden" name="download-type" id="download-type" value="' . implode('', array_keys($types)) . '"/>';
         hostsite_set_page_title(lang::get('Download {1}', strtolower(implode('', $types))));
     } else {
         $r .= data_entry_helper::select(array('fieldname' => 'download-type', 'label' => lang::get('Download type'), 'lookupValues' => $types, 'class' => 'control-width-5', 'helpText' => 'Select the type of download you require, i.e. the purpose for the data. This defines which records are available to download.'));
     }
     $r .= data_entry_helper::select(array('fieldname' => 'download-subfilter', 'label' => lang::get('Filter to apply'), 'lookupValues' => array(), 'class' => 'control-width-5', 'helpText' => lang::get('Optionally select from the available filters. Filters you create on the Explore pages will be available here.')));
     $r .= "</fieldset>\n";
     $r .= '<fieldset><legend>' . lang::get('Limit the records') . '</legend>';
     if (empty($args['survey_id'])) {
         // put up an empty surveys drop down. AJAX will populate it.
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id', 'label' => lang::get('Survey to include'), 'helpText' => 'Choose a survey, or <all> to not filter by survey.', 'lookupValues' => array(), 'class' => 'control-width-5'));
     } else {
         $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>';
     }
     // Let the user pick the date range to download.
     $r .= data_entry_helper::select(array('label' => lang::get('Date field'), 'fieldname' => 'date_type', 'lookupValues' => array('recorded' => lang::get('Field record date'), 'input' => lang::get('Input date'), 'edited' => lang::get('Last changed date'), 'verified' => 'Verification status change date'), 'helpText' => 'If filtering on date, which date field would you like to filter on?'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_from', 'label' => lang::get('Start Date'), 'helpText' => 'Leave blank for no start date filter', 'class' => 'control-width-4'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_to', 'label' => lang::get('End Date'), 'helpText' => 'Leave blank for no end date filter', 'class' => 'control-width-4'));
     $r .= '</fieldset>';
     if (!empty($args['custom_formats'])) {
         $customFormats = json_decode($args['custom_formats'], true);
         foreach ($customFormats as $idx => $format) {
             if (empty($format['permission']) || user_access($format['permission'])) {
                 $formats["custom-{$idx}"] = lang::get(isset($format['title']) ? $format['title'] : 'Untitled format');
             }
         }
     }
     if (count($formats) > 1) {
         $r .= '<fieldset><legend>' . lang::get('Select a format to download') . '</legend>';
         $keys = array_keys($formats);
         $r .= data_entry_helper::radio_group(array('fieldname' => 'format', 'lookupValues' => $formats, 'default' => $keys[0]));
         $r .= '</fieldset>';
     } else {
         // only allowed 1 format, so no need for a selection control
         $keys = array_keys($formats);
         $r .= '<input type="hidden" name="format" value="' . array_pop($keys) . '"/>';
     }
     $r .= '<input type="submit" value="' . lang::get('Download') . '"/></form>';
     data_entry_helper::$javascript .= 'indiciaData.ajaxUrl="' . url('iform/ajax/easy_download_2') . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.nid = "' . $node->nid . "\";\n";
     data_entry_helper::$javascript .= "setAvailableDownloadFilters();\n";
     return $r;
 }
Exemplo n.º 10
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     if (empty($_GET['group_id'])) {
         return 'This page needs a group_id URL parameter.';
     }
     require_once 'includes/map.php';
     require_once 'includes/groups.php';
     global $indicia_templates;
     iform_load_helpers(array('report_helper', 'map_helper'));
     $conn = iform_get_connection_details($node);
     $readAuth = report_helper::get_read_auth($conn['website_id'], $conn['password']);
     report_helper::$javascript .= "indiciaData.website_id={$conn['website_id']};\n";
     report_helper::$javascript .= "indiciaData.nodeId={$node->nid};\n";
     group_authorise_form($args, $readAuth);
     $group = data_entry_helper::get_population_data(array('table' => 'group', 'extraParams' => $readAuth + array('id' => $_GET['group_id'], 'view' => 'detail')));
     $group = $group[0];
     hostsite_set_page_title("{$group['title']}: {$node->title}");
     $actions = array();
     if (!empty($args['edit_location_path'])) {
         $actions[] = array('caption' => 'edit', 'url' => '{rootFolder}' . $args['edit_location_path'], 'urlParams' => array('group_id' => $_GET['group_id'], 'location_id' => '{location_id}'));
     }
     $actions[] = array('caption' => 'remove', 'javascript' => "remove_location_from_group({groups_location_id});");
     $leftcol = report_helper::report_grid(array('readAuth' => $readAuth, 'dataSource' => 'library/locations/locations_for_groups', 'sendOutputToMap' => true, 'extraParams' => array('group_id' => $_GET['group_id']), 'rowId' => 'location_id', 'columns' => array(array('display' => 'Actions', 'actions' => $actions, 'caption' => 'edit', 'url' => '{rootFolder}'))));
     $leftcol .= '<fieldset><legend>' . lang::Get('Add sites to the group') . '</legend>';
     $leftcol .= '<p>' . lang::get('LANG_Add_Sites_Instruct') . '</p>';
     if (!empty($args['edit_location_path'])) {
         $leftcol .= lang::get('Either') . ' <a class="button" href="' . hostsite_get_url($args['edit_location_path'], array('group_id' => $_GET['group_id'])) . '">' . lang::get('enter details of a new site') . '</a><br/>';
     }
     $leftcol .= data_entry_helper::select(array('label' => lang::get('Or, add an existing site'), 'fieldname' => 'add_existing_location_id', 'report' => 'library/locations/locations_available_for_group', 'caching' => false, 'blankText' => lang::get('<please select>'), 'valueField' => 'location_id', 'captionField' => 'name', 'extraParams' => $readAuth + array('group_id' => $_GET['group_id'], 'user_id' => hostsite_get_user_field('indicia_user_id', 0)), 'afterControl' => '<button id="add-existing">Add</button>'));
     $leftcol .= '</fieldset>';
     // @todo Link existing My Site to group. Need a new report to list sites I created, with sites already in the group
     // removed. Show in a drop down with an add button. Adding must create the groups_locations record, plus refresh
     // the grid and refresh the drop down.
     // @todo set destination after saving added site
     $map = map_helper::map_panel(iform_map_get_map_options($args, $readAuth), iform_map_get_ol_options($args));
     $r = str_replace(array('{col-1}', '{col-2}'), array($leftcol, $map), $indicia_templates['two-col-50']);
     data_entry_helper::$javascript .= "indiciaData.group_id={$_GET['group_id']};\n";
     return $r;
 }
Exemplo n.º 11
0
 /**
  * If there are any recording groups, then add controls to the config to allow the forms to be linked to the recording group
  * functionality.
  */
 private static function link_to_group_fields($readAuth, $options)
 {
     $r = '';
     if (function_exists('db_query')) {
         $qry = db_query("SELECT count(*) as count FROM {iform} WHERE iform='group_edit'");
         if (function_exists('db_fetch_object')) {
             $row = db_fetch_object($qry);
         } else {
             $row = $qry->fetchObject();
         }
         if ($row->count > 0) {
             $r .= data_entry_helper::checkbox(array('label' => lang::get('Allow this form to be used by recording groups'), 'fieldname' => 'available_for_groups', 'helpText' => lang::get('Tick this box if the form is suitable for use by recording groups for their own record collection or reporting.'), 'default' => isset($options['available_for_groups']) ? $options['available_for_groups'] : false));
             $r .= data_entry_helper::select(array('label' => lang::get('Restrict to a recording group'), 'fieldname' => 'limit_to_group_id', 'helpText' => lang::get('If this form is being built for the private use of 1 recording group, then choose that group here. ' . 'This does not affect visibility of the actual records input using the form. Only applies if the above checkbox is ticked.'), 'blankText' => '<' . lang::get('Unrestricted') . '>', 'table' => 'group', 'valueField' => 'id', 'captionField' => 'title', 'extraParams' => $readAuth, 'default' => isset($options['limit_to_group_id']) ? $options['limit_to_group_id'] : false));
         }
     }
     return $r;
 }
Exemplo n.º 12
0
 protected static function get_control_locationtype($auth, $args, $tabalias, $options)
 {
     // To limit the terms listed add a terms option to the Form Structure as a JSON array.
     // The terms must exist in the termlist that has external key indidia:location_types
     // e.g.
     // [location type]
     // @terms=["City","Town","Village"]
     // get the list of terms
     $filter = null;
     if (array_key_exists('terms', $options)) {
         $filter = $options['terms'];
     }
     $terms = helper_base::get_termlist_terms($auth, 'indicia:location_types', $filter);
     if (count($terms) == 1) {
         //only one location type so output as hidden control
         return '<input type="hidden" id="location:location_type_id" name="location:location_type_id" value="' . $terms[0]['id'] . '" />' . PHP_EOL;
     } elseif (count($terms) > 1) {
         // convert the $terms to an array of id => term
         $lookup = array();
         foreach ($terms as $term) {
             $lookup[$term['id']] = $term['term'];
         }
         return data_entry_helper::select(array_merge(array('label' => lang::get('LANG_Location_Type'), 'fieldname' => 'location:location_type_id', 'lookupValues' => $lookup, 'blankText' => lang::get('LANG_Blank_Text')), $options));
     }
 }
 private static function location_control($args, $readAuth, $node, &$options)
 {
     // note that when in user specific mode it returns the list currently assigned to the user: it does not give
     // locations which the user previously recorded data against, but is no longer allocated to.
     global $user;
     $ctrl = '';
     $siteUrlParams = self::get_site_url_params();
     // loctools is not appropriate here as it is based on a node, for which this is a very simple one, invoking other nodes for the sample creation
     if (!isset($args['includeLocationFilter']) || !$args['includeLocationFilter']) {
         return '';
     }
     // this is user specific: when no user selection control, or all users selected then default to all locations
     // this means it does not get a list of all locations if no user is selected: to be added later?
     $options['location_id'] = $siteUrlParams[self::$locationKey]['value'];
     $options['extraParams']['location_id'] = $siteUrlParams[self::$locationKey]['value'];
     $options['extraParams']['location_list'] = '';
     // Set up common data.
     $locationListArgs = array('extraParams' => array_merge(array('website_id' => $args['website_id'], 'location_type_id' => '', 'sensattr' => '', 'exclude_sensitive' => 0), $readAuth), 'readAuth' => $readAuth, 'caching' => true, 'dataSource' => 'library/locations/locations_list_exclude_sensitive');
     $allowSensitive = empty($args['sensitivityLocAttrId']) || function_exists('user_access') && !empty($args['sensitivityAccessPermission']) && user_access($args['sensitivityAccessPermission']);
     if (!empty($args['sensitivityLocAttrId'])) {
         $locationListArgs['extraParams']['locattrs'] = $args['sensitivityLocAttrId'];
     }
     $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $readAuth, 'survey_id' => self::$siteUrlParams[self::$SurveyKey]);
     if (isset($args['locationTypesFilter']) && $args['locationTypesFilter'] != "") {
         $types = explode(',', $args['locationTypesFilter']);
         $types1 = array();
         $types2 = array();
         foreach ($types as $type) {
             $parts = explode(':', $type);
             $types1[] = $parts[0];
             $types2[] = $parts;
         }
         $terms = self::get_sorted_termlist_terms(array('read' => $readAuth), 'indicia:location_types', $types1);
         $attrArgs['location_type_id'] = $siteUrlParams[self::$locationTypeKey]['value'];
         $locationListArgs['extraParams']['location_type_id'] = $siteUrlParams[self::$locationTypeKey]['value'];
         if (count($types) > 1) {
             $lookUpValues = array();
             foreach ($terms as $termDetails) {
                 $lookUpValues[$termDetails['id']] = $termDetails['term'];
             }
             // if location is predefined, can not change unless a 'manager_permission'
             $ctrlid = 'calendar-location-type-' . $node->nid;
             $ctrl .= data_entry_helper::select(array('label' => lang::get('Site Type'), 'id' => $ctrlid, 'fieldname' => 'location_type_id', 'lookupValues' => $lookUpValues, 'default' => $siteUrlParams[self::$locationTypeKey]['value'])) . '</th><th>';
             self::set_up_control_change($ctrlid, self::$locationTypeKey, array());
             $options['downloadFilePrefix'] .= preg_replace('/[^A-Za-z0-9]/i', '', $lookUpValues[$siteUrlParams[self::$locationTypeKey]['value']]) . '_';
         }
     }
     $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
     $locationList = array();
     // If we are looking a user, then we display all that users sites. If I am that user, or if I am a person with sensitive access, then I can see all the sites, even sensitive.
     if (isset($args['includeUserFilter']) && $args['includeUserFilter'] && isset($args['userSpecificLocationLookUp']) && $args['userSpecificLocationLookUp'] && isset($options['user_id']) && $options['user_id'] != "" && $siteUrlParams[self::$userKey]['value'] != "branch") {
         if (!$allowSensitive && $options['user_id'] != $user->uid) {
             // ensure can see sensitive sites for my sites only, unless manager who can see all
             $locationListArgs['extraParams']['sensattr'] = $args['sensitivityLocAttrId'];
             $locationListArgs['extraParams']['exclude_sensitive'] = 1;
         }
         $cmsAttr = extract_cms_user_attr($locationAttributes, false);
         if (!$cmsAttr) {
             return lang::get('Location control: CMS User ID Attribute missing from locations.');
         }
         $attrListArgs = array('extraParams' => array_merge(array('view' => 'list', 'website_id' => $args['website_id'], 'location_attribute_id' => $cmsAttr['attributeId'], 'raw_value' => $options['user_id']), $readAuth), 'table' => 'location_attribute_value');
         $description = "All " . ($user->uid == $options['user_id'] ? 'my' : 'user') . " sites";
         $attrList = data_entry_helper::get_population_data($attrListArgs);
         if (isset($attrList['error'])) {
             return $attrList['error'];
         }
         if (count($attrList) === 0) {
             $options['downloadFilePrefix'] .= 'NS_';
             return $ctrl . lang::get('[No sites allocated.]');
         }
         $locationIDList = array();
         foreach ($attrList as $attr) {
             $locationIDList[] = $attr['location_id'];
         }
         $locationListArgs['extraParams']['idlist'] = implode(',', $locationIDList);
         $locationList = report_helper::get_report_data($locationListArgs);
         if (isset($locationList['error'])) {
             return $locationList['error'];
         }
     } else {
         // If we are looking at a branch, we can see all the sites allocated to me even sensitive.
         if (isset($args['includeUserFilter']) && $args['includeUserFilter'] && isset($args['userSpecificLocationLookUp']) && $args['userSpecificLocationLookUp'] && $siteUrlParams[self::$userKey]['value'] == "branch") {
             $description = "All branch sites";
             if (count(self::$branchLocationList) === 0) {
                 $options['downloadFilePrefix'] .= 'NS_';
                 return $ctrl . lang::get('[No branch sites allocated.]');
             }
             $locationListArgs['extraParams']['idlist'] = implode(',', self::$branchLocationList);
             $locationList = report_helper::get_report_data($locationListArgs);
             if (isset($locationList['error'])) {
                 return $locationList['error'];
             }
             $options['extraParams']['location_list'] = implode(',', self::$branchLocationList);
             $options['branch_location_list'] = self::$branchLocationList;
         } else {
             // If we are looking at all sites, we can see all non sensitive sites, plus sensitive sites if they are allocated to me as a site or as a branch, or if I have access to sensitive.
             $description = "All sites";
             $locationListArgs['extraParams']['idlist'] = '';
             // get my sites, including sensitive sites.
             $cmsAttr = extract_cms_user_attr($locationAttributes, false);
             if ($cmsAttr) {
                 $attrListArgs = array('extraParams' => array_merge(array('view' => 'list', 'website_id' => $args['website_id'], 'location_attribute_id' => $cmsAttr['attributeId'], 'raw_value' => $user->uid), $readAuth), 'table' => 'location_attribute_value');
                 $attrList = data_entry_helper::get_population_data($attrListArgs);
                 if (isset($attrList['error'])) {
                     return $attrList['error'];
                 }
                 if (count($attrList) > 0) {
                     $locationIDList = array();
                     foreach ($attrList as $attr) {
                         $locationIDList[] = $attr['location_id'];
                     }
                     $locationListArgs['extraParams']['idlist'] = implode(',', $locationIDList);
                 }
             }
             // Next add Branch Sites, sensitive or not
             if (count(self::$branchLocationList) > 0) {
                 $locationListArgs['extraParams']['idlist'] .= ($locationListArgs['extraParams']['idlist'] == '' ? '' : ',') . implode(',', self::$branchLocationList);
             }
             $userLocationList = array();
             if ($locationListArgs['extraParams']['idlist'] != '') {
                 $userLocationList = report_helper::get_report_data($locationListArgs);
                 if (isset($userLocationList['error'])) {
                     return $userLocationList['error'];
                 }
             }
             // Next get all other non sensitive sites
             if (!$allowSensitive) {
                 $locationListArgs['extraParams']['sensattr'] = $args['sensitivityLocAttrId'];
                 $locationListArgs['extraParams']['exclude_sensitive'] = 1;
             }
             $locationListArgs['extraParams']['idlist'] = "";
             $allLocationList = report_helper::get_report_data($locationListArgs);
             if (isset($allLocationList['error'])) {
                 return $allLocationList['error'];
             }
             foreach ($userLocationList as $loc) {
                 $locationList[$loc['id']] = $loc;
             }
             foreach ($allLocationList as $loc) {
                 if (!isset($locationList[$loc['id']])) {
                     $locationList[$loc['id']] = $loc;
                 }
             }
         }
     }
     // we want to sort by name, but also keep details of sensitivity.
     $sort = array();
     $locs = array();
     foreach ($locationList as $location) {
         $sort[$location['id']] = $location['name'];
         $locs[$location['id']] = $location;
     }
     natcasesort($sort);
     $ctrlid = 'calendar-location-select-' . $node->nid;
     $ctrl .= '<label for="' . $ctrlid . '" class="location-select-label">' . lang::get('Filter by site') . ': </label><select id="' . $ctrlid . '" class="location-select">' . '<option value="" class="location-select-option" ' . ($siteUrlParams[self::$locationKey]['value'] == '' ? 'selected="selected" ' : '') . '>' . $description . '</option>';
     if ($siteUrlParams[self::$locationKey]['value'] == '') {
         $options['downloadFilePrefix'] .= preg_replace('/[^A-Za-z0-9]/i', '', $description) . '_';
     }
     foreach ($sort as $id => $name) {
         $ctrl .= '<option value=' . $id . ' class="location-select-option ' . (!empty($args['sensitivityLocAttrId']) && $locs[$id]['attr_location_' . $args['sensitivityLocAttrId']] === "1" ? 'sensitive' : '') . '" ' . ($siteUrlParams[self::$locationKey]['value'] == $id ? 'selected="selected" ' : '') . '>' . $name . (isset($args['includeSrefInLocationFilter']) && $args['includeSrefInLocationFilter'] ? ' (' . $locs[$id]['centroid_sref'] . ')' : '') . '</option>' . "\n";
         if ($siteUrlParams[self::$locationKey]['value'] == $id) {
             $options['downloadFilePrefix'] .= preg_replace('/[^A-Za-z0-9]/i', '', $name) . '_';
         }
     }
     $ctrl .= '</select>';
     self::set_up_control_change($ctrlid, self::$locationKey, array());
     return $ctrl;
 }
Exemplo n.º 14
0
 /**
  * Helper function to output a set of controls for handling the sensitivity of a record. Includes
  * a checkbox plus a control for setting the amount to blur the record by for public viewing.
  * The output of this control can be configured using the following templates: 
  * <ul>
  * <li><b>hidden_text</b></br>
  * HTML template used to generate the hidden input element.
  * </li>
  * </ul>
  *
  * @param array $options Options array with the following possibilities:<ul>
  * <li><b>fieldname</b><br/>
  * Required. The name of the database field this control is bound to. Defaults to occurrence:sensitivity_precision.</li>
  * <li><b>defaultBlur</b><br/>
  * Optional. The initial value to blur a record by when assigning sensitivity. Defaults to 10000.</li>
  * <li><b>additionalControls</b><br/>
  * Optional. Any additional controls to include in the div which is disabled when a record is not sensitive. An example use of this
  * might be a Reason for sensitivity custom attribute. Provide the controls as an HTML string.</li>
  * </ul>
  *
  * @return string HTML to insert into the page for the hidden text control.
  */
 public static function sensitivity_input($options)
 {
     $options = array_merge(array('fieldname' => 'occurrence:sensitivity_precision', 'defaultBlur' => 10000, 'additionalControls' => ''), $options);
     $r = '<fieldset><legend>' . lang::get('Sensitivity') . '</legend>';
     $r .= data_entry_helper::checkbox(array('id' => 'sensitive-checkbox', 'fieldname' => 'sensitive', 'label' => lang::get('Is the record sensitive?')));
     // Put a hidden input out, so that when the select control is disabled we get an empty value posted to clear the sensitivity
     $r .= '<input type="hidden" name="' . $options['fieldname'] . '">';
     $r .= '<div id="sensitivity-controls">';
     $r .= data_entry_helper::select(array('fieldname' => $options['fieldname'], 'id' => 'sensitive-blur', 'label' => lang::get('Blur record to'), 'lookupValues' => array('100' => lang::get('Blur to 100m'), '1000' => lang::get('Blur to 1km'), '2000' => lang::get('Blur to 2km'), '10000' => lang::get('Blur to 10km'), '100000' => lang::get('Blur to 100km')), 'blankText' => 'none', 'helpText' => 'This is the precision that the record will be shown at for public viewing'));
     // output any extra controls which should get disabled when the record is not sensitive.
     $r .= $options['additionalControls'];
     $r .= '</div></fieldset>';
     self::$javascript .= "\nvar doSensitivityChange = function(evt) {\n  if (\$('#sensitive-checkbox').attr('checked')) {\n    \$('#sensitivity-controls input, #sensitivity-controls select').removeAttr('disabled');\n  } else {\n    \$('#sensitivity-controls input, #sensitivity-controls select').attr('disabled', true);\n  }\n  \$('#sensitivity-controls').css('opacity', \$('#sensitive-checkbox').attr('checked') ? 1 : .5);\n  if (\$('#sensitive-checkbox').attr('checked')=== true && typeof evt!=='undefined' && \$('#sensitive-blur').val()==='') {\n    // set a default\n    \$('#sensitive-blur').val('" . $options['defaultBlur'] . "');\n  } \n  else if (typeof evt!=='undefined') {\n    \$('#sensitive-blur').val('');\n  }\n};\n\$('#sensitive-checkbox').change(doSensitivityChange);\n\$('#sensitive-checkbox').attr('checked', \$('#sensitive-blur').val()==='' ? false : true);\ndoSensitivityChange();\n\$('#sensitive-blur').change(function() {\n  if (\$('#sensitive-blur').val()==='') {\n    \$('#sensitive-checkbox').attr('checked', false);\n    doSensitivityChange();\n  }\n});\n\n";
     return $r;
 }
Exemplo n.º 15
0
function iform_mnhnl_lux5kgridControl($auth, $args, $node, $options)
{
    global $indicia_templates, $user;
    $options = array_merge(array('initLoadArgs' => '{}', 'Instructions1' => lang::get('LANG_CommonInstructions1'), 'Instructions2' => lang::get('LANG_DE_Instructions2'), 'MainFieldLabel' => lang::get('LANG_DE_LocationIDLabel'), 'ChooseParentLabel' => lang::get('LANG_CommonParentLabel'), 'ParentLabel' => lang::get('LANG_CommonParentLabel'), 'NameLabel' => lang::get('LANG_CommonLocationNameLabel'), 'FilterNameLabel' => lang::get('LANG_CommonFilterNameLabel'), 'CodeLabel' => lang::get('LANG_CommonLocationCodeLabel'), 'AdminMode' => false, 'disabled' => false), $options);
    switch ($args['locationMode']) {
        case 'multi':
            $options = array_merge(array('ChooseParentFieldID' => 'sample-location-id', 'ChooseParentFieldName' => 'sample:location_id', 'MainFieldID' => 'dummy-location-id', 'MainFieldName' => 'dummy:location_id'), $options);
            break;
        default:
            // parent, single, filtered
            $options = array_merge(array('ChooseParentFieldID' => 'dummy-parent-id', 'ChooseParentFieldName' => 'dummy:parent_id', 'ParentFieldID' => 'location-parent-id', 'ParentFieldName' => 'location:parent_id', 'MainFieldID' => 'location-id', 'MainFieldName' => 'location:id'), $options);
            break;
    }
    // we are using meaning_ids: for the location attributes we need to convert the id to the term for the templates. Can't just output value - convert raw value
    $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
    $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
    // this does not get values
    $termlists = array();
    $requiresConv = array();
    foreach ($locationAttributes as $locAttr) {
        if (!is_null($locAttr["termlist_id"])) {
            $termlists[] = $locAttr["termlist_id"];
            $requiresConv[] = $locAttr["attributeId"];
        }
    }
    data_entry_helper::$javascript .= "\nvar requiresConv = " . json_encode($requiresConv) . ";\n";
    if (count($termlists) > 0) {
        data_entry_helper::$javascript .= "var terms = {";
        $extraParams = $auth['read'] + array('view' => 'detail', 'preferred' => 't', 'orderby' => 'meaning_id', 'termlist_id' => $termlists);
        $terms_data_def = array('table' => 'termlists_term', 'extraParams' => $extraParams);
        $terms = data_entry_helper::get_population_data($terms_data_def);
        $first = true;
        foreach ($terms as $term) {
            data_entry_helper::$javascript .= ($first ? '' : ',') . $term['meaning_id'] . ": \"" . htmlSpecialChars($term['term']) . "\"\n";
            $first = false;
        }
        data_entry_helper::$javascript .= "};\nconvertTerm=function(id){\n\tif(typeof terms[id] == 'undefined') return id;\n\treturn terms[id];\n}\n";
    }
    $precisionAttrID = iform_mnhnl_getAttrID($auth, $args, 'location', 'Precision');
    if ($precisionAttrID && isset($args['movePrecision']) && $args['movePrecision']) {
        data_entry_helper::$javascript .= "\nvar precisionAttr = jQuery('[name=locAttr\\:" . $precisionAttrID . "],[name^=locAttr\\:" . $precisionAttrID . "\\:]');\nvar precisionLabel = precisionAttr.prev();\nprecisionAttr.next().filter('br').remove();\nprecisionLabel.addClass('auto-width prepad').insertAfter('#imp-srefY');\nprecisionAttr.insertAfter(precisionLabel).addClass('precision');\n";
    }
    $creatorAttr = iform_mnhnl_getAttrID($auth, $args, 'location', 'Creator');
    if (isset(data_entry_helper::$entity_to_load["sample:updated_by_id"])) {
        // only set if data loaded from db, not error condition
        data_entry_helper::load_existing_record($auth['read'], 'location', data_entry_helper::$entity_to_load["sample:location_id"]);
    }
    $retVal = '<div id="clickableLayersOutputDiv" style="display:none;"></div>';
    if ($args['LocationTypeTerm'] == '' && isset($args['loctoolsLocTypeID'])) {
        $args['LocationTypeTerm'] = $args['loctoolsLocTypeID'];
    }
    $primary = iform_mnhnl_getTermID($auth, 'indicia:location_types', $args['LocationTypeTerm']);
    if ($args['SecondaryLocationTypeTerm'] != '') {
        $secondary = iform_mnhnl_getTermID($auth, 'indicia:location_types', $args['SecondaryLocationTypeTerm']);
        $loctypequery = "\"&query=\"+escape(JSON.stringify({'in': ['location_type_id', [{$primary}, {$secondary}]]}))";
        $loctypeParam = array($primary, $secondary);
    } else {
        $loctypequery = "\"&location_type_id=" . $primary . "\"";
        $loctypeParam = $primary;
    }
    // $retVal .= "<p>".print_r($options,true)."</p>";
    data_entry_helper::$javascript .= "\n// Create vector layers: one to display the Parent Square onto, and another for the site locations list\n// the default edit layer is used for this sample\nParentLocStyleMap = new OpenLayers.StyleMap({\"default\": new OpenLayers.Style({strokeColor: \"Yellow\",fillOpacity: 0,strokeWidth: 4})});\nParentLocationLayer = new OpenLayers.Layer.Vector('Parents',{styleMap: ParentLocStyleMap,displayInLayerSwitcher: false});\n\ndefaultPointStyle = new OpenLayers.Style({pointRadius: 6,fillColor: \"Red\",fillOpacity: 0.3,strokeColor: \"Yellow\",strokeWidth: 1});\nselectPointStyle = new OpenLayers.Style({pointRadius: 6,fillColor: \"Blue\",fillOpacity: 0.3,strokeColor: \"Yellow\",strokeWidth: 2});\ndefaultStyle = new OpenLayers.Style({pointRadius: 6, fillColor: \"Red\",fillOpacity: 0.3,strokeColor: \"Red\",strokeWidth: 1});\nselectStyle = new OpenLayers.Style({fillColor: \"Blue\",fillOpacity: 0.3,strokeColor: \"Blue\",strokeWidth: 2});\n//defaultLabelStyle = new OpenLayers.Style({fontColor: \"Yellow\", labelAlign: \"" . $args['labelAlign'] . "\", labelXOffset: " . $args['labelXOffset'] . ", labelSelect: true});\ndragPointStyleHash={pointRadius: 6,fillColor: \"Fuchsia\",fillOpacity: 0.3,strokeColor: \"Fuchsia\",strokeWidth: 1};\n// Interesting behaviour of the Points: when any mod control is active it creates a set of vertices which can be \n// dragged, allowing the existing geometry to be modified. All fine for Lines and polygons, but for points\n// the vertices are generated in the default style, and appear over the top of our existing geometry, so\n// effectively making it appear unselected! \n// We want consistent colouring, so\n// 1) normal=red, yellow surrounds points\n// 2) highlighted=blue, yellow surrounds points\n// 3) Drag points=purple.\n\nSitePointStyleMap = new OpenLayers.StyleMap({\"default\": defaultPointStyle, \"select\": selectPointStyle});\nSiteStyleMap = new OpenLayers.StyleMap({\"default\": defaultStyle, \"select\": selectStyle});\n//SiteLabelStyleMap = new OpenLayers.StyleMap({\"default\": defaultLabelStyle});\n\n" . ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode'] ? "SiteListPrimaryLabelStyleHash={fontColor: \"Red\", labelAlign: \"" . $args['labelAlign'] . "\", labelXOffset: " . $args['labelXOffset'] . ", labelSelect: true, fontSize: \"1.2em\", fontWeight: \"bold\"};\nSiteListSecondaryLabelStyleHash" : "\nSiteListPrimaryLabelStyleHash") . "={fontColor: \"Yellow\", labelAlign: \"" . $args['labelAlign'] . "\", labelXOffset: " . $args['labelXOffset'] . ", labelSelect: true};\n\nSitePointLayer = new OpenLayers.Layer.Vector('Site Points',{styleMap: SitePointStyleMap, displayInLayerSwitcher: false});\n//SitePointLayer = new OpenLayers.Layer.Vector('Site Points',{styleMap: SitePointStyleMap});\nSitePathLayer = new OpenLayers.Layer.Vector('Site Paths',{styleMap: SiteStyleMap, displayInLayerSwitcher: false});\nSiteAreaLayer = new OpenLayers.Layer.Vector('Site Areas',{styleMap: SiteStyleMap, displayInLayerSwitcher: false});\nSiteLabelLayer = new OpenLayers.Layer.Vector('Site Labels',{//styleMap: SiteLabelStyleMap, \ndisplayInLayerSwitcher: false});\nvar SiteNum = 0;\n";
    if (isset($args['locationLayerWMS']) && $args['locationLayerWMS'] != '') {
        // define Parent WMS Layer
        $WMSoptions = explode(',', $args['locationLayerWMS']);
        if ($args['includeLocTools'] && function_exists('iform_loctools_listlocations')) {
            $squares = iform_loctools_listlocations($node);
            if (is_array($squares) && count($squares) == 0) {
                $squares = array("-1");
            }
            // put in dummy value (all ids are > 0) to allow CQL filter to work on a blank list.
        } else {
            $squares = 'all';
        }
        // can't use the column name id in the cql_filter as this has a special (fid) meaning.
        data_entry_helper::$javascript .= "\nWMSoptions = {SERVICE: 'WMS', VERSION: '1.1.0', STYLES: '', SRS: '" . $WMSoptions[2] . "', FORMAT: 'image/png', TRANSPARENT: 'true', LAYERS: '" . $WMSoptions[1] . "',\n  CQL_FILTER: \"location_type_id=" . $args['loctoolsLocTypeID'] . " AND website_id=" . $args['website_id'] . ($squares != 'all' ? " AND location_id IN (" . implode(',', $squares) . ")" : '') . "\"\n    };\nParentWMSLayer = new OpenLayers.Layer.WMS('Parent Grid',\n  '" . (function_exists(iform_proxy_url) ? iform_proxy_url($WMSoptions[0]) : $WMSoptions[0]) . "',\n  WMSoptions, {\n    minScale: " . $WMSoptions[3] . ",\n    maxScale: " . $WMSoptions[4] . ",\n    units: '" . $WMSoptions[5] . "',\n    isBaseLayer: false,\n    singleTile: true\n  });\n";
        if ($args['locationMode'] == 'multi' && isset(data_entry_helper::$entity_to_load["sample:location_id"])) {
            data_entry_helper::$javascript .= "setClickedParent = function(features, div){ return ''; };\n";
        } else {
            data_entry_helper::$javascript .= "setClickedParent = function(features, div){\n  jQuery('[name=" . str_replace(':', '\\:', $options['ChooseParentFieldName']) . "]').val(features[0].data.id).change();\n  return '';\n};\n";
        }
    }
    data_entry_helper::$javascript .= "\n// not happy about centroid calculations: lines and multipoints seem to take first vertex\n_getCentroid = function(geometry){\n  var retVal;\n  retVal = {sumx: 0, sumy: 0, count: 0};\n  switch(geometry.CLASS_NAME){\n    case \"OpenLayers.Geometry.Point\":\n      retVal = {sumx: geometry.x, sumy: geometry.y, count: 1};\n      break;\n    case \"OpenLayers.Geometry.MultiPoint\":\n    case \"OpenLayers.Geometry.MultiLineString\":\n    case \"OpenLayers.Geometry.LineString\":\n    case \"OpenLayers.Geometry.MultiPolygon\":\n    case \"OpenLayers.Geometry.Collection\":\n      var retVal = {sumx: 0, sumy: 0, count: 0};\n      for(var i=0; i< geometry.components.length; i++){\n        var point=_getCentroid(geometry.components[i]);\n        retVal = {sumx: retVal.sumx+point.sumx, sumy: retVal.sumy+point.sumy, count: retVal.count+point.count};\n      }\n      break;\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\n      var point=geometry.getCentroid();\n      retVal = {sumx: point.x*geometry.components[0].components.length, sumy: point.y*geometry.components[0].components.length, count: geometry.components[0].components.length};\n      break;\n  }\n  return retVal;\n}\ngetCentroid=function(geometry){\n  var oddball=_getCentroid(geometry);\n  return new OpenLayers.Geometry.Point(oddball.sumx/oddball.count, oddball.sumy/oddball.count);\n}\nrecalcNumSites = function(){\n  var sitearray = {};\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  // don't need to consider Label layer...\n  for(var i=0; i< allFeatures.length; i++){\n    if(typeof allFeatures[i].attributes.SiteNum != 'undefined')\n      sitearray['x'+allFeatures[i].attributes.SiteNum.toString()] = true;\n  }\n  var count = 0;\n  for (x in sitearray) count++;\n  jQuery('#dummy-num-sites').val(count);\n};\nrecalcNumSites();\nclearLocation = function(hookArg, clearName){ // clears all the data in the fields.\n  if(clearName === true || (clearName == 'maybe' && jQuery('#" . $options['MainFieldID'] . "').val() != ''))\n    jQuery('" . ($args['locationMode'] != 'multi' ? "#sample-location-name" : "") . ",#location-name').val('');\n  jQuery('#" . $options['MainFieldID'] . ($args['locationMode'] != 'multi' ? ",#sample-location-id" : "") . ",#centroid_sref,#imp-srefX,#imp-srefY,#centroid_geom,#boundary_geom,[name=location\\:comment],[name=location\\:parent_id],#location-code').val('');\n  jQuery('#location-code').attr('dbCode','');\n" . ($args['locationMode'] != 'multi' && $args['siteNameTermListID'] != "" && isset($args['duplicateNameCheck']) && $args['duplicateNameCheck'] == 'enforce' ? "  jQuery('#location-name option').removeAttr('disabled');\n  var nameVal = jQuery('#location-name').val();\n  for(var i=0; i< SiteLabelLayer.features.length; i++){\n    if(typeof SiteLabelLayer.features[i].attributes.SiteNum != 'undefined'){\n      // At the moment the allowable options are integers: if the old data is dodgy it may not hold an integer\n      if(SiteLabelLayer.features[i].style.label == parseInt(SiteLabelLayer.features[i].style.label)){\n\t\tif(SiteLabelLayer.features[i].style.label == nameVal) jQuery('#location-name').val('');\n\t\tjQuery('#location-name').find('option').filter('[value='+SiteLabelLayer.features[i].style.label+']').attr('disabled','disabled');\n      }\n    }\n  }\n" : "") . "  jQuery('#location_location_type_id').val('{$primary}');\n  // first  to remove any hidden multiselect checkbox unclick fields\n  var fullAttrList=jQuery('[name^=locAttr\\:]').not('[name\$=\\:term]');\n  var attrList=jQuery('[name^=locAttr\\:]').not('[name\$=\\:term]').not('.filterFields');\n  fullAttrList.filter('.multiselect').remove();\n  fullAttrList.filter(':checkbox').removeAttr('checked').each(function(idx,elem){\n    var name = jQuery(elem).attr('name').split(':');\n    var value = jQuery(elem).val().split(':');\n    jQuery('[name^=locAttr\\:'+name[1]+'\\:]').filter(':hidden').remove();\n    jQuery(elem).val(value[0]);\n  });\n  // rename\n  fullAttrList.each(function(){\n    var name = jQuery(this).attr('name').split(':');\n    if(name[1].indexOf('[]') > 0) name[1] = name[1].substr(0, name[1].indexOf('[]'));\n    jQuery(this).attr('name', name[0]+':'+name[1]);\n  });\n  // reset values (checkboxes done above).\n  attrList.filter(':radio').removeAttr('checked');\n  attrList.filter(':text').val('');\n  attrList.filter('select').val('');\n  // rename checkboxes to add square brackets\n  attrList.filter(':checkbox').each(function(idx,elem){\n\tvar name = jQuery(elem).attr('name').split(':');\n\tvar similar = jQuery('[name=locAttr\\:'+name[1]+'],[name=locAttr\\:'+name[1]+'\\[\\]]').filter(':checkbox');\n\tif(similar.length > 1) // only do this for checkbox groups.\n\t\tjQuery(this).attr('name', name[0]+':'+name[1]+'[]');\n  });\n  if(typeof hook_set_defaults != 'undefined') hook_set_defaults(hookArg);\n}\nsetPermissions = function(enableItems, disableItems){\n  if(disableItems.length > 0) jQuery(disableItems.join(',')).attr('disabled',true);\n  if(enableItems.length > 0) jQuery(enableItems.join(',')).removeAttr('disabled');\n}\n// sets the permissions when there is nothing selected, and no parent is provided\nsetPermissionsNoParent = function(){\n  setPermissions([],\n                 ['[name=locations_website\\:website_id]',\n                  '#" . $options['MainFieldID'] . "',\n                  '[name=location\\:code]',\n                  '[name=location\\:name]',\n                  '[name=location\\:comment]',\n                  '[name=location\\:location_type_id]',\n                  '[name=location\\:deleted]',\n                  '[name=location\\:parent_id]',\n                  '[name^=locAttr\\:]',\n                  '#dummy-name',\n                  '#imp-sref',\n                  '#imp-geom',\n                  '#imp-boundary-geom']);\n}\nsetPermissionsNoSite = function(){\n  // In filter mode, if parent is in filter options, need it available. Also in that case will need to enter filter options before the main ID becomes available\n  // else when creating a new site, it is possible to select an old site from the drop down, provided there are some to select.\n  var disable = ['[name=locations_website\\:website_id]',\n                  '[name=location\\:code]',\n                  '[name=location\\:name]',\n                  '[name=location\\:comment]',\n                  '[name=location\\:location_type_id]',\n                  '[name=location\\:deleted]',\n                  '[name^=locAttr\\:]',\n                  '#dummy-name',\n                  '#imp-sref',\n                  '#imp-geom',\n                  '#imp-boundary-geom'];\n  if(typeof indiciaData.filterMode == 'undefined'){\n    var enable = ['#" . $options['MainFieldID'] . "']; // can choose site from drop down.\n    disable.push('[name=location\\:parent_id]');\n  } else {\n    disable.push('#" . $options['MainFieldID'] . "');\n    var enable = ['[name=location\\:parent_id]'];\n  }\n  setPermissions(enable,disable);\n}\nsetPermissionsOldEditableSite = function(){\n  setPermissions(['#" . $options['MainFieldID'] . "',\n                  '[name=location\\:code]',\n                  '[name=location\\:name]',\n                  '[name=location\\:comment]',\n                  '[name=location\\:location_type_id]',\n                  '[name=location\\:deleted]',\n                  '[name=location\\:parent_id]',\n                  '[name^=locAttr\\:]',\n                  '#dummy-name',\n                  '#imp-sref',\n                  '#imp-geom',\n                  '#imp-boundary-geom'],\n                 ['[name=locations_website\\:website_id]']);\n}\nsetPermissionsOldReadOnlySite = function(){\n  setPermissions(['#" . $options['MainFieldID'] . "'],\n                 ['[name=locations_website\\:website_id]',\n                  '[name=location\\:code]',\n                  '[name=location\\:name]',\n                  '[name=location\\:comment]',\n                  '[name=location\\:location_type_id]',\n                  '[name=location\\:deleted]',\n                  '[name=location\\:parent_id]',\n                  '[name^=locAttr\\:]',\n                  '#dummy-name',\n                  '#imp-sref',\n                  '#imp-geom',\n                  '#imp-boundary-geom']);\n}\nsetPermissionsNewSite = function(){\n  // when creating a new site, it is possible to select an old site from the drop down, provided there are some to select.\n  var enable = ['[name=locations_website\\:website_id]',\n                '[name=location\\:code]',\n                '[name=location\\:name]',\n                '[name=location\\:comment]',\n                '[name=location\\:location_type_id]',\n                '[name=location\\:parent_id]',\n                '[name^=locAttr\\:]',\n                '#dummy-name',\n                '#imp-sref',\n                '#imp-geom',\n                '#imp-boundary-geom'];\n  var disable = ['[name=location\\:deleted]'];\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  var haveOld=false;\n  for(var i=0; i<allFeatures.length; i++){\n    if(allFeatures[i].attributes['new']==false){\n      haveOld=true;\n    }}\n  if(haveOld){\n    enable.push('#" . $options['MainFieldID'] . "');  // in case we want to change to an existing site.\n  } else {\n    disable.push('#" . $options['MainFieldID'] . "');\n  }\n  setPermissions(enable,disable);\n}\nloadLocation = function(feature){ // loads all the data into the location fields from a feature.\n  if(feature.attributes['new'])\n    setPermissionsNewSite();\n  else if (feature.attributes.canEdit)\n    setPermissionsOldEditableSite();\n  else\n    setPermissionsOldReadOnlySite();\n" . ($args['locationMode'] == 'multi' ? "  var mySelector = '#dummy-name';\n" : "  var mySelector = '#location-name';\n  clearLocation(false, true);\n") . "\n" . ($args['siteNameTermListID'] != "" ? "  jQuery(mySelector).find('option').removeAttr('disabled');\n" : "") . "  // the label is stored in the SiteLabelLayer. For new locations this is the only place the name is stored in the generic module.\n  for(var i=0; i< SiteLabelLayer.features.length; i++){\n    if(typeof SiteLabelLayer.features[i].attributes.SiteNum != 'undefined'){\n      if(feature.attributes.SiteNum == SiteLabelLayer.features[i].attributes.SiteNum){\n        jQuery('#dummy-name').val(SiteLabelLayer.features[i].style.label);\n      }\n" . ($args['siteNameTermListID'] != "" ? "      else {\n        // At the moment the allowable options are integers: if the old data is dodgy it may not hold an integer\n        if(SiteLabelLayer.features[i].style.label == parseInt(SiteLabelLayer.features[i].style.label))\n          jQuery(mySelector).find('option').filter('[value='+SiteLabelLayer.features[i].style.label+']').attr('disabled','disabled');\n      }\n" : "") . "    }\n  }\n" . ($args['locationMode'] == 'multi' ? "" : ";  // main field ID could be a select without an entry for me (in case of a filter) so add one if needed.\n  var amIaSelect = jQuery('#" . $options['MainFieldID'] . "').filter('select');\n  if(amIaSelect.length>0 && amIaSelect.find('[value='+feature.attributes.data.id+']').length==0){\n    amIaSelect.append('<option value=\"'+feature.attributes.data.id+'\">'+feature.attributes.data.name+'</option>');\n  }\n  jQuery(\"#" . $options['MainFieldID'] . ",#sample-location-id\").val(feature.attributes.data.id);\n  // parent_id is left as is in drop down if present. Not multi so must be an existing site.\n  jQuery('#location-name,#sample-location-name').val(feature.attributes.data.name);\n  jQuery('#location_location_type_id').val(feature.attributes.data.location_type_id);\n  if(feature.attributes.data.comment == null) feature.attributes.data.comment='';\n  jQuery('[name=location\\:comment]').val(feature.attributes.data.comment);\n  jQuery('[name=location\\:parent_id],[name=dummy\\:parent_id]').val(feature.attributes.data.parent_id);\n  jQuery('#location-code').val(feature.attributes.data.code).attr('dbCode',feature.attributes.data.code);\n  jQuery('#imp-geom').val(feature.attributes.data.centroid_geom); // this is as stored in the database i.e. 3857/900913 projection, not necessarily the map projection\n  jQuery('#imp-boundary-geom').val(feature.attributes.data.boundary_geom); // this is as stored in the database i.e. 3857/900913 projection, not necessarily the map projection\n  setSref(feature.geometry, feature.attributes.data.centroid_sref);\n  // reset attributes is done by clearLocation above. this clears the values of checkboxes.\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/location_attribute_value' +\n            '?mode=json&view=list&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&location_id='+feature.attributes.data.id+'&callback=?', function(data) {\n    if(data instanceof Array && data.length>0){\n      for (var i=0;i<data.length;i++){\n        if (data[i].id) {\n          // no multiselect or boolean checkboxes at the moment so don't code\n          var radiobuttons = jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'],[name^=locAttr\\:'+data[i]['location_attribute_id']+'\\:]').filter(':radio');\n          var checkbuttons = jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'\\[\\]],[name^=locAttr\\:'+data[i]['location_attribute_id']+'\\:]').filter(':checkbox');\n          if(radiobuttons.length > 0){ // radio buttons all share the same name, only one checked.\n            radiobuttons.attr('name', 'locAttr:'+data[i]['location_attribute_id']+':'+data[i].id)\n                  .filter('[value='+data[i].raw_value+']').attr('checked', 'checked');\n          } else if(checkbuttons.length > 0){ // checkbuttons buttons have different name if selected, any number selected.\n\t\t\tcheckbuttons = checkbuttons.filter('[value='+data[i].raw_value+']')\n\t\t\t\t.attr('name', 'locAttr:'+data[i]['location_attribute_id']+':'+data[i].id).attr('checked', 'checked');\n\t\t\tcheckbuttons.each(function(){\n\t\t\t\tjQuery('<input type=\"hidden\" value=\"\" class=\"multiselect\">').attr('name', jQuery(this).attr('name')).insertBefore(this);\n\t\t\t});\n          } else {\n            jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+']')\n                      .attr('name', 'locAttr:'+data[i]['location_attribute_id']+':'+data[i].id).val(data[i].raw_value);\n            if(jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'\\:term]').length>0){ // autocomplete entries: force a lookup, we are using meaning_id\n              jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'\\:term]').val('');\n              jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/termlists_term' +\n                '?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&preferred=t&meaning_id='+data[i].raw_value+'&callback=?', function(tdata) {\n                if(tdata.length>0){\n                  jQuery('[name^=locAttr]').filter('[value='+tdata[0].meaning_id+']').each(function(idx,elem){\n                    var name = jQuery(elem).attr('name').split(':');\n                    jQuery('[name=locAttr\\:'+name[1]+'\\:term]').val(tdata[0].term);\n                  });\n                }\n              });\n            }\n          }\n        }\n      }\n      if(typeof hook_loadFilters != 'undefined')\n        hook_loadFilters(); // can only be done after attributes loaded\n     }});\n") . "\n  if(typeof hook_loadLocation != 'undefined')\n    hook_loadLocation(feature);\n}\ncheckEditable = function(isNew, id){\n  if(isNew) return true; // if I have created a new Site in this session, I can edit it.\n  if(typeof canEditExistingSites != 'undefined') return canEditExistingSites;\n  return(SiteEditable[id]);\n}\nconvertFeature = function(feature, projection){\n  if(feature instanceof Array){\n    if(feature.length == 0) return geom;\n    var newfeatures = [];\n    \$.each(feature, function(idx, featureElem){\n      newfeatures.push(convertFeature(featureElem, projection));\n    });\n    return newfeatures;\n  }\n  feature.geometry = convertGeom(feature.geometry, projection);\n  return feature;\n}\nconvertGeom = function(geom, projection){\n  if (projection.projcode!='EPSG:900913' && projection.projcode!='EPSG:3857') { \n    var cloned = geom.clone();\n    return cloned.transform(new OpenLayers.Projection('EPSG:900913'), projection);\n  }\n  return geom;\n}\nreverseConvertGeom = function(geom, projection){\n  if (projection.projcode!='EPSG:900913' && projection.projcode!='EPSG:3857') {\n    var cloned = geom.clone();\n    return cloned.transform(projection, new OpenLayers.Projection('EPSG:900913'));\n  }\n  return geom;\n}\nzoomToLayerExtent = function(layer){\n  var layerBounds = layer.getDataExtent().clone(); // use a clone\n  var mapBounds = layer.map.getMaxExtent();\n  if(layerBounds.left   < mapBounds.left)   layerBounds.left = mapBounds.left;\n  if(layerBounds.right  > mapBounds.right)  layerBounds.right = mapBounds.right;\n  if(layerBounds.bottom < mapBounds.bottom) layerBounds.bottom = mapBounds.bottom;\n  if(layerBounds.top    > mapBounds.top)    layerBounds.top = mapBounds.top;\n  layer.map.zoomToExtent(layerBounds);\n}\n\nloadFeatures = function(parent_id, child_id, childArgs, loadParent, setSelectOptions, zoomParent, clearLocationFlag, setPermissionState){\n  ParentLocationLayer.destroyFeatures();\n  SiteLabelLayer.destroyFeatures();\n  SiteAreaLayer.destroyFeatures();\n  SitePathLayer.destroyFeatures();\n  SitePointLayer.destroyFeatures();\n  if(setSelectOptions)\n    jQuery('#" . $options['MainFieldID'] . "').find('option').remove();\n" . ($args['locationMode'] != 'multi' && $args['siteNameTermListID'] != "" ? "  jQuery('#location-name').find('option').removeAttr('disabled');\n" : "") . "  if(clearLocationFlag){\n    clearLocation(false, true);\n  }\n  deactivateControls();\n  recalcNumSites();\n  SiteNum=0;\n  if(parent_id != '' && loadParent){\n    jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location/\"+parent_id+\"?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?\",\n      function(data) {\n       if (data.length>0) {\n         var parser = new OpenLayers.Format.WKT();\n         if(data[0].boundary_geom){ // only one location if any\n           var feature = parser.read(data[0].boundary_geom)\n           feature=convertFeature(feature, \$('#map')[0].map.projection);\n           ParentLocationLayer.addFeatures([feature]);\n           if(zoomParent) {\n             // Parent squares may overlap the edges of the map.\n             zoomToLayerExtent(ParentLocationLayer);\n           }\n         }\n         selectFeature.activate();\n" . ($args['locationMode'] == 'multi' ? "  jQuery('#sample-location-name').val(data[0].name);" : "") . "       }});\n  }\n  if(!loadParent) selectFeature.activate();\n  if(parent_id != '' || loadParent==false){\n    jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?&orderby=name\"+" . $loctypequery . "+(loadParent ? '&parent_id='+parent_id : ''),\n      function(data) {\n        if (data.length>0) {\n          if(setPermissionState) setPermissionsNoSite();\n          if(child_id=='') selectFeature.activate(); // we have things we can select\n          if(setSelectOptions)\n            jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"\">" . lang::get("LANG_CommonEmptyLocationID") . "</option>');\n          var parser = new OpenLayers.Format.WKT();\n          var locationList = [];\n          for (var i=0;i<data.length;i++){\n            var centreFeature = false;\n            var feature;\n            SiteNum++;\n            if(data[i].boundary_geom){\n              feature = parser.read(data[i].boundary_geom); // assume map projection=900913, if GEOMETRYCOLLECTION this will be an array or its children!\n              var centre = false;\n              if(data[i].centroid_geom) {\n                centreFeature = parser.read(data[i].centroid_geom); // assume map projection=900913\n                centreFeature=convertFeature(centreFeature, \$('#map')[0].map.projection);\n              }\n              var pointFeature = false;\n              var lineFeature = false;\n              var areaFeature = false;\n              if(typeof(feature)=='object'&&(feature instanceof Array)){\n                for(var j=0; j< feature.length; j++){\n                  switch(feature[j].geometry.CLASS_NAME){\n                    case \"OpenLayers.Geometry.Point\":\n                    case \"OpenLayers.Geometry.MultiPoint\":\n                      pointFeature = feature[j];\n                      break;\n                    case \"OpenLayers.Geometry.LineString\":\n                    case \"OpenLayers.Geometry.MultiLineString\":\n                      lineFeature = feature[j];\n                      break;\n                    default:\n                      areaFeature = feature[j];\n                      break;\n                  }\n                }\n              } else {\n                switch(feature.geometry.CLASS_NAME){\n                  case \"OpenLayers.Geometry.Point\":\n                  case \"OpenLayers.Geometry.MultiPoint\":\n                    pointFeature = feature;\n                    break;\n                  case \"OpenLayers.Geometry.LineString\":\n                  case \"OpenLayers.Geometry.MultiLineString\":\n                    lineFeature = feature;\n                    break;\n                  default:\n                    areaFeature = feature;\n                    break;\n                }\n              }\n              if(areaFeature) {\n                areaFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                areaFeature=convertFeature(areaFeature, \$('#map')[0].map.projection);\n                SiteAreaLayer.addFeatures([areaFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(areaFeature.geometry));\n              }\n              if(lineFeature) {\n                lineFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                lineFeature=convertFeature(lineFeature, \$('#map')[0].map.projection);\n                SitePathLayer.addFeatures([lineFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(lineFeature.geometry));\n              }\n              if(pointFeature) {\n                pointFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                pointFeature=convertFeature(pointFeature, \$('#map')[0].map.projection);\n                SitePointLayer.addFeatures([pointFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(pointFeature.geometry));\n              }\n            } else {\n              // no boundary, only a centre point.\n              feature = parser.read(data[i].centroid_geom); // assume map projection=900913\n              feature=convertFeature(feature, \$('#map')[0].map.projection);\n              centreFeature = feature.clone();\n              feature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n              SitePointLayer.addFeatures([feature]);\n            }\n            centreFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n" . ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode'] ? "            if(data[i].location_type_id == {$secondary}){\n              centreFeature.style = jQuery.extend({}, SiteListSecondaryLabelStyleHash);\n            } else \n  " : "") . "            centreFeature.style = jQuery.extend({}, SiteListPrimaryLabelStyleHash);\n            centreFeature.style.label = data[i].name;\n            SiteLabelLayer.addFeatures([centreFeature]);\n            locationList.push({id : data[i].id, feature : centreFeature});\n            if(setSelectOptions){\n              if(child_id != '' && data[i].id == child_id){\n                jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"'+data[i].id+'\" selected=\"selected\">'+data[i].name+'</option>');\n              } else {\n                jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"'+data[i].id+'\">'+data[i].name+'</option>');\n              }\n            }\n            if(child_id==data[i].id && setPermissionState){\n              if(centreFeature.attributes.canEdit){\n                setPermissionsOldEditableSite();\n              } else {\n                setPermissionsOldReadOnlySite()\n              }\n            }\n            if(typeof hook_ChildFeatureLoad != 'undefined') hook_ChildFeatureLoad(feature, data[i], child_id, childArgs);\n          }\n          recalcNumSites();\n          " . ($args['locationMode'] == 'single' || $args['locationMode'] == 'filtered' ? "" : "if(setSelectOptions) ") . "populateExtensions(locationList);\n        } else if(setSelectOptions){\n          if(setPermissionState) setPermissionsNoParent();\n          jQuery('#" . $options['MainFieldID'] . "').append('<option value=\"\">" . lang::get("LANG_NoSitesInSquare") . "</option>');\n        }\n    });\n  } else {\n    if(setPermissionState) setPermissionsNoParent();\n    if(setSelectOptions)\n      jQuery('#" . $options['MainFieldID'] . "').append('<option value=\"\">" . lang::get("LANG_CommonChooseParentFirst") . "</option>');\n  }\n};\nloadChildFeatures = function(parent_id, setSelectOptions){\n// this is only used when changing the parent: need to keep current highlighted features.\n  SiteNum=1;\n  for(var i=SiteLabelLayer.features.length-1; i >= 0; i--) {\n    if(SiteLabelLayer.features[i].attributes.highlighted == false) {\n      SiteLabelLayer.destroyFeatures([SiteLabelLayer.features[i]]);\n    } else {\n      SiteLabelLayer.features[i].attributes.SiteNum == SiteNum;\n    }\n  }\n  for(var i=SiteAreaLayer.features.length-1; i >= 0; i--) {\n    if(SiteAreaLayer.features[i].attributes.highlighted == false) {\n      SiteAreaLayer.destroyFeatures([SiteAreaLayer.features[i]]);\n    } else {\n      SiteAreaLayer.features[i].attributes.SiteNum == SiteNum;\n    }\n  }\n  for(var i=SitePathLayer.features.length-1; i >= 0; i--) {\n    if(SitePathLayer.features[i].attributes.highlighted == false) {\n      SitePathLayer.destroyFeatures([SitePathLayer.features[i]]);\n    } else {\n      SitePathLayer.features[i].attributes.SiteNum == SiteNum;\n    }\n  }\n  for(var i=SitePointLayer.features.length-1; i >= 0; i--) {\n    if(SitePointLayer.features[i].attributes.highlighted == false) {\n      SitePointLayer.destroyFeatures([SitePointLayer.features[i]]);\n      } else {\n      SitePointLayer.features[i].attributes.SiteNum == SiteNum;\n    }\n  }\n  if(setSelectOptions)\n    jQuery('#" . $options['MainFieldID'] . "').find('option').not(':selected').remove();\n" . ($args['locationMode'] != 'multi' && $args['siteNameTermListID'] != "" ? "  jQuery('#location-name').find('option').removeAttr('disabled');\n" : "") . "  recalcNumSites();\n  jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?&orderby=name\"+" . $loctypequery . "+'&parent_id='+parent_id,\n      function(data) {\n        if (data.length>0) {\n          if(setSelectOptions)\n            jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"\">" . lang::get("LANG_CommonEmptyLocationID") . "</option>');\n          var parser = new OpenLayers.Format.WKT();\n          var locationList = [];\n          for (var i=0;i<data.length;i++){\n            var centreFeature = false;\n            var feature;\n            SiteNum++;\n            if(data[i].boundary_geom){\n              feature = parser.read(data[i].boundary_geom); // assume map projection=900913, if GEOMETRYCOLLECTION this will be an array or its children!\n              var centre = false;\n              if(data[i].centroid_geom) {\n                centreFeature = parser.read(data[i].centroid_geom); // assume map projection=900913\n                centreFeature=convertFeature(centreFeature, \$('#map')[0].map.projection);\n              }\n              var pointFeature = false;\n              var lineFeature = false;\n              var areaFeature = false;\n              if(typeof(feature)=='object'&&(feature instanceof Array)){\n                for(var j=0; j< feature.length; j++){\n                  switch(feature[j].geometry.CLASS_NAME){\n                    case \"OpenLayers.Geometry.Point\":\n                    case \"OpenLayers.Geometry.MultiPoint\":\n                      pointFeature = feature[j];\n                      break;\n                    case \"OpenLayers.Geometry.LineString\":\n                    case \"OpenLayers.Geometry.MultiLineString\":\n                      lineFeature = feature[j];\n                      break;\n                    default:\n                      areaFeature = feature[j];\n                      break;\n                  }\n                }\n              } else {\n                switch(feature.geometry.CLASS_NAME){\n                  case \"OpenLayers.Geometry.Point\":\n                  case \"OpenLayers.Geometry.MultiPoint\":\n                    pointFeature = feature;\n                    break;\n                  case \"OpenLayers.Geometry.LineString\":\n                  case \"OpenLayers.Geometry.MultiLineString\":\n                    lineFeature = feature;\n                    break;\n                  default:\n                    areaFeature = feature;\n                    break;\n                }\n              }\n              if(areaFeature) {\n                areaFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                areaFeature=convertFeature(areaFeature, \$('#map')[0].map.projection);\n                SiteAreaLayer.addFeatures([areaFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(areaFeature.geometry));\n              }\n              if(lineFeature) {\n                lineFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                lineFeature=convertFeature(lineFeature, \$('#map')[0].map.projection);\n                SitePathLayer.addFeatures([lineFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(lineFeature.geometry));\n              }\n              if(pointFeature) {\n                pointFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                pointFeature=convertFeature(pointFeature, \$('#map')[0].map.projection);\n                SitePointLayer.addFeatures([pointFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(pointFeature.geometry));\n              }\n            } else {\n              // no boundary, only a centre point.\n              feature = parser.read(data[i].centroid_geom); // assume map projection=900913\n              feature=convertFeature(feature, \$('#map')[0].map.projection);\n              centreFeature = feature.clone();\n              feature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n              SitePointLayer.addFeatures([feature]);\n            }\n            centreFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n" . ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode'] ? "            if(data[i].location_type_id == {$secondary}){\n              centreFeature.style = jQuery.extend({}, SiteListSecondaryLabelStyleHash);\n            } else \n  " : "") . "            centreFeature.style = jQuery.extend({}, SiteListPrimaryLabelStyleHash);\n            centreFeature.style.label = data[i].name;\n            SiteLabelLayer.addFeatures([centreFeature]);\n            locationList.push({id : data[i].id, feature : centreFeature});\n            if(setSelectOptions){\n              jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"'+data[i].id+'\">'+data[i].name+'</option>');\n            }\n            if(typeof hook_ChildFeatureLoad != 'undefined') hook_ChildFeatureLoad(feature, data[i], '', {});\n          }\n          recalcNumSites();\n          " . ($args['locationMode'] == 'single' || $args['locationMode'] == 'filtered' ? "" : "if(setSelectOptions) ") . "populateExtensions(locationList);\n        }\n  });\n};\npopulateExtensions = function(locids){\n// first get the list of attributes, sorted by location_id. Locations are in name order not ID order.\n// rip out the list of attribute captions.\n// loop through list of locations,\n// Binary search attribute list for my locations\n// Run through its attributes and do translate\n";
    if ($args['extendLocationNameTemplate'] != "") {
        data_entry_helper::$javascript .= "  locList = [];\n  for(var i=0;i<locids.length;i++){\n    var template = \"" . $args['extendLocationNameTemplate'] . "\".replace('{name}',locids[i].feature.attributes.data.name);\n    template = template.replace('{code}',locids[i].feature.attributes.data.code==null?'-':locids[i].feature.attributes.data.code);\n    locList.push({id : locids[i].id,\n        feature : locids[i].feature,\n        template : template});\n  }\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/location_attribute_value' +\n            '?mode=json&view=list&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&orderby=location_id'+" . $loctypequery . "+'&callback=?', function(data) {\n    if(data instanceof Array && data.length>0){\n      function locBinarySearch(attList, location_id){ // this makes assumptions about the location attribute list contents and order.\n        var startIndex = 0,\n            stopIndex = attList.length - 1;\n        while(startIndex <= stopIndex){\n          var middle = Math.floor((stopIndex + startIndex)/2);\n          if (attList[middle].location_id == location_id) {\n            // there will be more than one attribute per location. Scan back.\n            while(middle > 0 && attList[middle-1].location_id == location_id) middle--;\n            return middle;\n          }\n          //adjust search area\n          if (parseInt(location_id) < parseInt(attList[middle].location_id)){\n            stopIndex = middle - 1;\n          } else {\n            startIndex = middle + 1;\n          }\n        }\n        return -1;\n      }\n      templateReplace = function(template, location_id, attList){\n        var attrid = locBinarySearch(attList, location_id);\n        if(attrid >= 0) {\n          while(attrid < attList.length && attList[attrid].location_id == location_id) {\n            if (attList[attrid].id){\n              template = template.replace('{'+attList[attrid].caption+'}',(attList[attrid].termlist_id != null ? convertTerm(parseInt(attList[attrid].raw_value)) : attList[attrid].value));\n            }\n            attrid++;\n          }\n        }";
        $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
        $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
        foreach ($locationAttributes as $locAttr) {
            data_entry_helper::$javascript .= "\n        template = template.replace('{" . $locAttr["untranslatedCaption"] . "}','-');";
        }
        data_entry_helper::$javascript .= "\n        return template;\n      };\n      for (var j=0;j<locList.length;j++){\n        locList[j].template = templateReplace(locList[j].template, locList[j].id, data);\n        SiteLabelLayer.removeFeatures([locList[j].feature]);\n        locList[j].feature.style.label = locList[j].template;\n        SiteLabelLayer.addFeatures([locList[j].feature]);\n" . ($args['locationMode'] != 'filtered' ? "        var myOption = jQuery(\"#" . $options['MainFieldID'] . "\").find('option').filter('[value='+locList[j].id+']').empty();\n" . ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode'] ? "        if(locList[j].feature.attributes.data.location_type_id == {$primary})\n          myOption.css('color','red');\n" : "") . "        myOption.append(locList[j].template);" : "") . "\n      }\n    }});\n";
    }
    data_entry_helper::$javascript .= "\n}\ngetwkt = function(geometry, incFront, incBrackets){\n  var retVal;\n  retVal = '';\n  switch(geometry.CLASS_NAME){\n    case \"OpenLayers.Geometry.Point\":\n      return((incFront!=false ? 'POINT' : '')+(incBrackets!=false ? '(' : '')+geometry.x+' '+geometry.y+(incBrackets!=false ? ')' : ''));\n      break;\n    case \"OpenLayers.Geometry.MultiPoint\":\n      retVal = 'MULTIPOINT(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\n      retVal += ')';\n      break;\n    case \"OpenLayers.Geometry.LineString\":\n      retVal = (incFront!=false ? 'LINESTRING' : '')+'(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, false);\n      retVal += ')';\n      break;\n    case \"OpenLayers.Geometry.MultiLineString\":\n      retVal = 'MULTILINESTRING(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\n      retVal += ')';\n      break;\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\n      retVal = (incFront!=false ? 'POLYGON' : '')+'((';\n      for(var i=0; i< geometry.components[0].components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[0].components[i], false, false);\n      retVal += '))';\n      break;\n    case \"OpenLayers.Geometry.MultiPolygon\":\n      retVal = 'MULTIPOLYGON(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\n      retVal += ')';\n      break;\n    case \"OpenLayers.Geometry.Collection\":\n      retVal = 'GEOMETRYCOLLECTION(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], true, true);\n      retVal += ')';\n      break;\n  }\n  return retVal;\n}\nsetGeomFields = function(){\n  // use centre of Area as centroid\n  // Build the combined Geometry, ignore label\n  var geomstack = [];\n  var completeGeom;\n  var centreGeom;\n  var centreSrefGeom;\n  var mySiteNum;\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  for(var i=allFeatures.length-1; i>=0; i--){\n    if(allFeatures[i].attributes.highlighted == true){\n      geomstack.push(allFeatures[i].geometry.clone()); // needs to be a clone as we don't want to transform the original geoms.\n      mySiteNum = allFeatures[i].attributes.SiteNum;\n    }\n  }\n  if(geomstack.length == 0){\n" . ($args['locationMode'] != 'multi' ? "    jQuery(\"#imp-boundary-geom\").val('');\n    jQuery(\"#imp-geom\").val('');\n    jQuery('#imp-sref').val('');\n    jQuery('#imp-srefX').val('');\n    jQuery('#imp-srefY').val('');\n" : "") . "    return;\n  } else if (geomstack.length == 1){\n    completeGeom = geomstack[0];\n  } else {\n    completeGeom = new OpenLayers.Geometry.Collection(geomstack);\n  }\n  centreSrefGeom=getCentroid(completeGeom);\n  // the geometry is in the map projection: if this doesn't match indicia's internal one, then must convert.\n  if (SiteAreaLayer.map.projection.projcode!='EPSG:900913' && SiteAreaLayer.map.projection.projcode!='EPSG:3857') { \n    completeGeom.transform(SiteAreaLayer.map.projection,  new OpenLayers.Projection('EPSG:900913'));\n  }\n  var boundaryWKT = getwkt(completeGeom, true, true);\n  centreGeom=getCentroid(completeGeom);\n  var centreWKT = getwkt(centreGeom, true, true);\n" . ($args['locationMode'] == 'multi' ? "  var highlighted = gethighlight();\n  hook_multisite_setGeomFields(highlighted[0], boundaryWKT, centreWKT);\n" : "  jQuery(\"#imp-boundary-geom\").val(boundaryWKT);\n  jQuery(\"#imp-geom\").val(centreWKT);\n  setSref(centreSrefGeom, 'TBC');  // forces the sref to be generated.\n") . "}\nsetDrawnGeom = function() {\n  // need to leave the location parent id enabled. Don't need to set geometries as we are using an existing location.\n  setPermissionsNewSite();\n  clearLocation(true, 'maybe');\n  if(jQuery('#dummy-parent-id').length>0 && jQuery('[name=location\\:parent_id]').length>0 &&\n      jQuery('#dummy-parent-id').val() != jQuery('[name=location\\:parent_id]').val())\n    jQuery('[name=location\\:parent_id]').val(jQuery('#dummy-parent-id').val()).change();\n" . ($creatorAttr ? "  jQuery('[name=locAttr:" . $creatorAttr . "],[name^=locAttr:" . $creatorAttr . ":]').val('" . $user->name . "');\n" : "") . "};\nremoveDrawnGeom = function(SiteNum){\n  var highlighted=gethighlight();\n  if(highlighted.length > 0 && highlighted[0].attributes.SiteNum == SiteNum) {\n    unhighlightAll();\n  }\n  for(var i=SiteLabelLayer.features.length-1; i>=0; i--)\n    if(SiteLabelLayer.features[i].attributes['new'] == true && SiteLabelLayer.features[i].attributes.SiteNum == SiteNum)\n      SiteLabelLayer.destroyFeatures([SiteLabelLayer.features[i]]);\n  for(var i=SiteAreaLayer.features.length-1; i>=0; i--)\n    if(SiteAreaLayer.features[i].attributes['new'] == true && SiteAreaLayer.features[i].attributes.SiteNum == SiteNum)\n      SiteAreaLayer.destroyFeatures([SiteAreaLayer.features[i]]);\n  for(var i=SitePathLayer.features.length-1; i>=0; i--)\n    if(SitePathLayer.features[i].attributes['new'] == true && SitePathLayer.features[i].attributes.SiteNum == SiteNum)\n      SitePathLayer.destroyFeatures([SitePathLayer.features[i]]);\n  for(var i=SitePointLayer.features.length-1; i>=0; i--)\n    if(SitePointLayer.features[i].attributes['new'] == true && SitePointLayer.features[i].attributes.SiteNum == SiteNum)\n      SitePointLayer.destroyFeatures([SitePointLayer.features[i]]);\n  recalcNumSites();\n}\nresetVertices = function(){\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  for(var i=allFeatures.length-1; i>=0; i--){\n    if(typeof allFeatures[i].attributes['new'] == 'undefined'){ // not one of ours, so must be a vertex\n      var layer= allFeatures[i].layer;\n      layer.removeFeatures([allFeatures[i]]);\n      allFeatures[i].style=dragPointStyleHash;\n      layer.addFeatures([allFeatures[i]]);\n    }\n  }\n  // Oddball case is single points: in this case they use the actual point to drag not a proxy vertex.\n  if(modPointFeature.feature){\n    if(modPointFeature.feature.geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n      var layer= modPointFeature.feature.layer;\n      layer.removeFeatures([modPointFeature.feature]);\n      modPointFeature.feature.style=dragPointStyleHash;\n      layer.addFeatures([modPointFeature.feature]);\n    }\n  } else {\n    for(var i=SitePointLayer.features.length-1; i>=0; i--){\n      if(SitePointLayer.features[i].style != null){\n        var feature = SitePointLayer.features[i];\n        var layer = feature.layer;\n        layer.removeFeatures([feature]);\n        feature.style=null;\n        layer.addFeatures([feature]);\n      }\n    }\n  }\n  SitePointLayer.redraw();\n}\nreplaceGeom = function(feature, layer, modControl, geom, highlight, setFields){\n  if(modControl.feature)\n    modControl.unselectFeature(modControl.feature);\n  var newfeature = new OpenLayers.Feature.Vector(geom, {});\n  newfeature.attributes = feature.attributes;\n  layer.destroyFeatures([feature]);\n  layer.addFeatures([newfeature]);\n  modControl.selectFeature(newfeature);\n  selectFeature.highlight(newfeature);\n  newfeature.attributes.highlighted=true;\n  resetVertices();\n  if(setFields) setGeomFields();\n}\naddAndSelectNewGeom = function(layer, modControl, geom, highlight){\n  SiteNum++;\n  var feature = new OpenLayers.Feature.Vector(geom, {highlighted: false, 'new': true, canEdit: true, SiteNum: SiteNum});\n  layer.addFeatures([feature]);\n  modControl.selectFeature(feature);\n  feature.attributes.highlighted=true;\n  selectFeature.highlight(feature);\n  resetVertices();\n  setGeomFields();\n  recalcNumSites();\n  return feature;\n}\naddToExistingFeatureSet = function(existingFeatures, layer, modControl, geom, highlight){\n  var feature = new OpenLayers.Feature.Vector(geom, {});\n  feature.attributes = existingFeatures[0].attributes;\n  layer.addFeatures([feature]);\n  modControl.selectFeature(feature);\n  selectFeature.highlight(feature);\n  feature.attributes.highlighted=true;\n  resetVertices();\n  setGeomFields();\n}\nunhighlightAll = function(){\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  var highlighted = gethighlight();\n  for(var i=0; i<highlighted.length; i++) {\n    highlighted[i].attributes.highlighted = false;\n    selectFeature.unhighlight(highlighted[i]);\n  }\n  resetVertices();\n}\nhighlightMe = function(id, SiteNum){\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features,SiteLabelLayer.features);\n  for(var i=0; i<allFeatures.length; i++){\n    if((typeof allFeatures[i].attributes.data != 'undefined' &&\n          typeof allFeatures[i].attributes.data.id != 'undefined' &&\n          allFeatures[i].attributes.data.id == id) || \n        (typeof allFeatures[i].attributes.SiteNum != 'undefined' &&\n          allFeatures[i].attributes.SiteNum == SiteNum)){\n      allFeatures[i].attributes.highlighted = true;\n      selectFeature.highlight(allFeatures[i]);\n    }\n  }\n}\ngethighlight = function(){\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features,SiteLabelLayer.features);\n  var features=[];\n  for(var i=0; i<allFeatures.length; i++){\n    if(allFeatures[i].attributes.highlighted==true){\n      features.push(allFeatures[i]);\n    }}\n  return features;\n}\n// default is to add a dummy new empty label\nif (typeof hook_new_site_added == 'undefined')\n hook_new_site_added = function(feature, SiteNum) {\n  var centreGeom;\n  var centrefeature;\n  if(!feature){\n    var div = jQuery('#map')[0];\n    var mapCentre = div.map.getCenter();\n    centreGeom = new OpenLayers.Geometry.Point(mapCentre.lon, mapCentre.lat);\n  } else {\n    centreGeom = getCentroid(feature.geometry);\n  }\n  centrefeature = new OpenLayers.Feature.Vector(centreGeom);\n  centrefeature.attributes['new']=true;\n  centrefeature.attributes.highlighted=true;\n  centrefeature.attributes.SiteNum=SiteNum;\n  centrefeature.style = jQuery.extend({}, SiteListPrimaryLabelStyleHash);\n  SiteLabelLayer.addFeatures([centrefeature]);\n  SitePointLayer.redraw();\n};\naddDrawnPointToSelection = function(geometry) {\n  // we assume that we have a point geometry.\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(ParentLocationLayer.features.length == 0) return;\n  if(!ParentLocationLayer.features[0].geometry.intersects(geometry))\n    alert(\"" . lang::get('LANG_PointOutsideParent') . "\");\n" : "") . (isset($args['oneTypeAtATime']) && $args['oneTypeAtATime'] ? "  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  SitePathLayer.destroyFeatures();\n  SiteAreaLayer.destroyFeatures();\n" : "") . "  var highlightedFeatures = gethighlight();\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "  if(highlightedFeatures.length == 0){\n    setDrawnGeom();\n    // No currently selected feature. Create a new one.\n    feature = addAndSelectNewGeom(SitePointLayer, modPointFeature, geometry, false);\n    hook_new_site_added(feature, feature.attributes.SiteNum);\n    if(typeof addPGPoint != 'undefined') addPGPoint(geometry);\n    return true;\n  }\n" : "  if(highlightedFeatures.length == 0) return true;\n") . "  var selectedFeature = false;\n  // a site is already selected so the Drawn/Specified state stays unaltered\n  for(var i=0; i<SitePointLayer.features.length; i++){\n    if(SitePointLayer.features[i].attributes.highlighted == true){\n      selectedFeature = SitePointLayer.features[i];\n      break;\n    }}\n  if(highlightedFeatures[0].attributes['new'] == true){\n    if(!selectedFeature) {\n      addToExistingFeatureSet(highlightedFeatures, SitePointLayer, modPointFeature, geometry, false);\n      if(typeof addPGPoint != 'undefined') addPGPoint(geometry);\n      return true;\n    }\n  } else { // highlighted is existing\n    if(highlightedFeatures[0].attributes.canEdit){\n      if(!selectedFeature) {\n        addToExistingFeatureSet(highlightedFeatures, SitePointLayer, modPointFeature, geometry, false);\n        if(typeof addPGPoint != 'undefined') addPGPoint(geometry);\n        return true;\n      }\n    } else {\n      return true;\n    }\n  }\n" . ($args['usePoints'] == 'single' ? "\n  if(typeof clearPGrid != 'undefined') clearPGrid(geometry);\n  replaceGeom(selectedFeature, SitePointLayer, modPointFeature, geometry, false, true);" : "\n  if(typeof addPGPoint != 'undefined') addPGPoint(geometry);\n  if(selectedFeature.geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPoint\") {\n    modPointFeature.unselectFeature(selectedFeature);\n    selectedFeature.geometry.addPoint(geometry);\n    modPointFeature.selectFeature(selectedFeature);\n    selectFeature.highlight(selectedFeature);\n    selectedFeature.attributes.highlighted = true;\n    resetVertices();\n    setGeomFields();\n  } else { // is OpenLayers.Geometry.Point\n    var CompoundGeom = new OpenLayers.Geometry.MultiPoint([selectedFeature.geometry, geometry]);\n    replaceGeom(selectedFeature, SitePointLayer, modPointFeature, CompoundGeom, false, true);\n  }") . "\n  return true;\n}\naddDrawnLineToSelection = function(geometry) {\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(ParentLocationLayer.features.length == 0) return;\n" : "") . "  var points = geometry.getVertices();\n  if(points.length < 2){\n    alert(\"" . lang::get('LANG_TooFewLinePoints') . "\");\n    return false;\n  }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  var centre = getCentroid(geometry);\n  if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n    alert(\"" . lang::get('LANG_LineOutsideParent') . "\");\n" : "") . (isset($args['oneTypeAtATime']) && $args['oneTypeAtATime'] ? "  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  SitePointLayer.destroyFeatures();\n  SiteAreaLayer.destroyFeatures();\n" : "") . "  var highlightedFeatures = gethighlight();\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "  if(highlightedFeatures.length == 0){\n    setDrawnGeom();\n    // No currently selected feature. Create a new one.\n    feature = addAndSelectNewGeom(SitePathLayer, modPathFeature, geometry, true);\n    hook_new_site_added(feature, feature.attributes.SiteNum);\n    return true;\n  }\n" : "  if(highlightedFeatures.length == 0) return true;\n") . "\n  var selectedFeature = false;\n  for(var i=0; i<highlightedFeatures.length; i++){\n    if(highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.LineString\" ||\n        highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiLineString\") {\n      selectedFeature = highlightedFeatures[i];\n      break;\n    }}\n  // a site is already selected so the Drawn/Specified state stays unaltered\n  if(highlightedFeatures[0].attributes['new'] == true){\n    if(!selectedFeature) {\n      addToExistingFeatureSet(highlightedFeatures, SitePathLayer, modPathFeature, geometry, true);\n      return true;\n    }\n  } else { // highlighted is existing\n    if(highlightedFeatures[0].attributes.canEdit){\n      if(!selectedFeature) {\n        addToExistingFeatureSet(highlightedFeatures, SitePathLayer, modPathFeature, geometry, true);\n        return true;\n      }\n    } else {\n      return true;\n    }\n  }\n  " . ($args['useLines'] == 'single' ? "\n  replaceGeom(selectedFeature, SitePathLayer, modPathFeature, geometry, true, true);" : "\n  if(selectedFeature.geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiLineString\") {\n    modPathFeature.unselectFeature(selectedFeature);\n    selectedFeature.geometry.addComponents([geometry]);\n    modPathFeature.selectFeature(selectedFeature);\n    selectFeature.highlight(selectedFeature);\n    selectedFeature.attributes.highlighted = true;\n    resetVertices();\n    setGeomFields();\n  } else { // is OpenLayers.Geometry.LineString\n    var CompoundGeom = new OpenLayers.Geometry.MultiLineString([selectedFeature.geometry, geometry]);\n    replaceGeom(selectedFeature, SitePathLayer, modPathFeature, CompoundGeom, true, true);\n  }") . "\n  return true;\n}\naddDrawnPolygonToSelection = function(geometry) {\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(ParentLocationLayer.features.length == 0) return;\n" : "") . "  var points = geometry.components[0].getVertices();\n  if(points.length < 3){\n    alert(\"" . lang::get('LANG_TooFewPoints') . "\");\n    return false;\n  }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  var centre = getCentroid(geometry);\n  if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n    alert(\"" . lang::get('LANG_PolygonOutsideParent') . "\");\n" : "") . (isset($args['oneTypeAtATime']) && $args['oneTypeAtATime'] ? "  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  SitePointLayer.destroyFeatures();\n  SitePathLayer.destroyFeatures();\n" : "") . "  var highlightedFeatures = gethighlight();\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "  if(highlightedFeatures.length == 0){\n    setDrawnGeom();\n    // No currently selected feature. Create a new one.\n    feature = addAndSelectNewGeom(SiteAreaLayer, modAreaFeature, geometry, true);\n    hook_new_site_added(feature, feature.attributes.SiteNum);\n    return true;\n  }\n" : "  if(highlightedFeatures.length == 0) return true;\n") . "\n  var selectedFeature = false;\n  for(var i=0; i<highlightedFeatures.length; i++){\n    if(highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.Polygon\" ||\n        highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPolygon\") {\n      selectedFeature = highlightedFeatures[i];\n      break;\n    }}\n  // a site is already selected so the Drawn/Specified state stays unaltered\n  if(highlightedFeatures[0].attributes['new'] == true){\n    if(!selectedFeature) {\n      addToExistingFeatureSet(highlightedFeatures, SiteAreaLayer, modAreaFeature, geometry, true);\n      return true;\n    }\n  } else { // highlighted is existing\n    if(highlightedFeatures[0].attributes.canEdit){\n      if(!selectedFeature) {\n        addToExistingFeatureSet(highlightedFeatures, SiteAreaLayer, modAreaFeature, geometry, true);\n        return true;\n      }\n    } else {\n      return true;\n    }\n  }\n  " . ($args['usePolygons'] == 'single' ? "\n  replaceGeom(selectedFeature, SiteAreaLayer, modAreaFeature, geometry, true, true);" : "\n  if(selectedFeature.geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPolygon\") {\n    modAreaFeature.unselectFeature(selectedFeature);\n    selectedFeature.geometry.addComponents([geometry]);\n    modAreaFeature.selectFeature(selectedFeature);\n    selectFeature.highlight(selectedFeature);\n    selectedFeature.attributes.highlighted = true;\n    resetVertices();\n    setGeomFields();\n  } else { // is OpenLayers.Geometry.Polygon\n    var CompoundGeom = new OpenLayers.Geometry.MultiPolygon([selectedFeature.geometry, geometry]);\n    replaceGeom(selectedFeature, SiteAreaLayer, modAreaFeature, CompoundGeom, true, true);\n  }") . "\n  return true;\n}\nonFeatureModified = function(evt) {\n  var feature = evt.feature;\n  switch(feature.geometry.CLASS_NAME){\n    case \"OpenLayers.Geometry.Point\":\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      if(!ParentLocationLayer.features[0].geometry.intersects(feature.geometry))\n        alert(\"" . lang::get('LANG_PointOutsideParent') . "\");\n" : "") . "      if(typeof modPGPoint != 'undefined') modPGPoint(feature.geometry);\n      break;\n    case \"OpenLayers.Geometry.MultiPoint\":\n      if(feature.geometry.components.length == 0){\n        modPointFeature.unselectFeature(feature);\n        SitePointLayer.destroyFeatures([feature]);\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "     } else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_PointOutsideParent') . "\");\n" : "") . "      }\n      if(typeof modPGPoint != 'undefined') modPGPoint(feature.geometry);\n      break;\n    case \"OpenLayers.Geometry.LineString\":\n      points = feature.geometry.getVertices();\n      if(points.length < 2){\n        alert(\"" . lang::get('LANG_TooFewLinePoints') . "\");\n        modPathFeature.unselectFeature(feature);\n        SitePathLayer.destroyFeatures([feature]);\n      }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_LineOutsideParent') . "\");\n      }\n" : "") . "      break;\n    case \"OpenLayers.Geometry.MultiLineString\":\n      for(i=feature.geometry.components.length-1; i>=0; i--) {\n        points = feature.geometry.components[i].getVertices();\n        if(points.length < 2){\n          alert(\"" . lang::get('LANG_TooFewLinePoints') . "\");\n          var selectedFeature = modPathFeature.feature;\n          modPathFeature.unselectFeature(selectedFeature);\n          selectFeature.unhighlight(selectedFeature);\n          SitePathLayer.removeFeatures([selectedFeature]);\n          selectedFeature.geometry.removeComponents([feature.geometry.components[i]]);\n          SitePathLayer.addFeatures([selectedFeature]);\n          modPathFeature.selectFeature(selectedFeature);\n          selectFeature.highlight(selectedFeature);\n          selectedFeature.attributes.highlighted = true;\n        }\n      }\n      if(feature.geometry.components.length == 0){\n        modPathFeature.unselectFeature(feature);\n        SitePathLayer.destroyFeatures([feature]);\n      }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_LineOutsideParent') . "\");\n      }\n" : "") . "      break;\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\n      points = feature.geometry.components[0].getVertices();\n      if(points.length < 3){\n        alert(\"" . lang::get('LANG_TooFewPoints') . "\");\n        modAreaFeature.unselectFeature(feature);\n        SiteAreaLayer.destroyFeatures([feature]);\n      }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_CentreOutsideParent') . "\");\n      }\n" : "") . "      break;\n    case \"OpenLayers.Geometry.MultiPolygon\":\n      for(i=feature.geometry.components.length-1; i>=0; i--) {\n        points = feature.geometry.components[i].components[0].getVertices();\n        if(points.length < 3){\n          alert(\"" . lang::get('LANG_TooFewPoints') . "\");\n          var selectedFeature = modAreaFeature.feature;\n          modAreaFeature.unselectFeature(selectedFeature);\n          selectFeature.unhighlight(selectedFeature);\n          SiteAreaLayer.removeFeatures([selectedFeature]);\n          selectedFeature.geometry.removeComponents([feature.geometry.components[i]]);\n          SiteAreaLayer.addFeatures([selectedFeature]);\n          modAreaFeature.selectFeature(selectedFeature);\n          selectFeature.highlight(selectedFeature);\n          selectedFeature.attributes.highlighted = true;\n        }\n      }\n      if(feature.geometry.components.length == 0){\n        modAreaFeature.unselectFeature(feature);\n        SiteAreaLayer.destroyFeatures([feature]);\n      }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_CentreOutsideParent') . "\");\n      }\n" : "") . "      break;\n  }\n  resetVertices();\n  setGeomFields();\n}\n// TBD should only include next when siteNameTermListID set\nsetNameDropDowns = function(disable, value){\n  jQuery('#dummy-name').find('*').removeAttr('disabled');\n  if(disable === true){\n  \tjQuery('#dummy-name').val('').attr('disabled','disabled');\n  \treturn;\n  }\n  if(disable === false)\n  \tjQuery('#dummy-name').removeAttr('disabled');\n  if(value===false && jQuery('#dummy-name').val() !== '') value=jQuery('#dummy-name').val()\n  if(value !== '')\n    jQuery('#dummy-name').find('option').filter('[value=]').attr('disabled','disabled');\n  jQuery('#dummy-name').find('option').each(function (index, option){\n  // TBD convert this to look at the features.\n      if((value == false || jQuery(option).val() != value) &&\n          jQuery('.cggrid-row,.cgAddedRow').find('.cggrid-name').filter('[value='+jQuery(option).val()+']').length > 0)\n        jQuery(option).attr('disabled','disabled');\n  });\n  if(value!==false) jQuery('#dummy-name').val(value);\n};\n/********************************/\n/* Define Map Control callbacks */\n/********************************/\nCancelSketch = function(layer){\n  for(var i = editControl.controls.length-1; i>=0; i--)\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\" && editControl.controls[i].active)\n      editControl.controls[i].cancel();\n};\nUndoSketchPoint = function(layer){\n  for(var i = editControl.controls.length-1; i>=0; i--)\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\" && editControl.controls[i].active)\n      editControl.controls[i].undo();\n};\nRemoveNewSite = function(){\n  // can only remove the site if highlighted,\n  var highlighted = gethighlight();\n  if(highlighted.length == 0 || !highlighted[0].attributes['new']) return;\n  if(confirm('" . lang::get('LANG_ConfirmRemoveDrawnSite') . "')){\n    if(typeof hook_RemoveNewSite != 'undefined')\n      hook_RemoveNewSite();\n    clearLocation(true, true);\n    removeDrawnGeom(highlighted[0].attributes.SiteNum);\n    recalcNumSites();\n    setGeomFields();\n    if(typeof setNameDropDowns != 'undefined')\n      setNameDropDowns(true, false);\n  }\n};\nStartNewSite = function(){\n  var keepName=false;\n" . ($args['locationMode'] == 'parent' ? "  if(jQuery('#" . $options['ChooseParentFieldID'] . "').val()==''){\n    alert('" . lang::get('LANG_MustSelectParentFirst') . "');\n    return;\n  };" : "") . "\n" . ($args['locationMode'] == 'multi' ? "  unhighlightAll();\n" . (isset($args['siteNameTermListID']) && $args['siteNameTermListID'] != '' ? "  setNameDropDowns(false, '');\n" : "  jQuery('#dummy-name').val('');\n") : "  keepName = jQuery('#" . $options['MainFieldID'] . "').val() == '';\n  // first remove any existing new location.\n  var highlighted = gethighlight();\n  var found=false;\n  // only confirm if have something drawn on map: ie ignore label\n  for(i=0; i<highlighted.length; i++) found = found || (highlighted[i].layer != SiteLabelLayer && highlighted[i].attributes['new']==true)\n  if(found && !confirm('" . lang::get('LANG_ConfirmRemoveDrawnSite') . "')) return false;\n  if(highlighted.length>0 && highlighted[0].attributes['new']==true) removeDrawnGeom(highlighted[0].attributes.SiteNum); // remove label here\n  unhighlightAll();\n  jQuery('#" . $options['MainFieldID'] . ",#sample-location-id').val(''); // reset id field.\n") . "  setPermissionsNewSite(); // need to leave the location parent id enabled.\n  clearLocation(true, !keepName);\n  if(jQuery('#dummy-parent-id').length>0 && jQuery('[name=location\\:parent_id]').length>0 &&\n      jQuery('#dummy-parent-id').val() != jQuery('[name=location\\:parent_id]').val())\n    jQuery('[name=location\\:parent_id]').val(jQuery('#dummy-parent-id').val()).change();\n" . ($creatorAttr ? "  jQuery('[name=locAttr:" . $creatorAttr . "],[name^=locAttr:" . $creatorAttr . ":]').val('" . $user->name . "');\n" : "") . "  // No currently selected feature. Create a dummy label new one.\n  SiteNum++;\n  hook_new_site_added(false, SiteNum);\n  // Programatic activation does not rippleout to deactivate other draw features, so deactivate all first.\n  for(var i=0; i<editControl.controls.length; i++)\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\")\n      editControl.controls[i].deactivate();\n  // we assume there is at least one drawing control: activate the first one.\n  selectFeature.activate();\n  for(var i=0; i<editControl.controls.length; i++){\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\"){\n      selectFeature.deactivate();\n      editControl.controls[i].activate();\n      // new site will have no vertices yet...\n      return;\n    }}\n}\nZoomToFeature = function(feature){\n  var div = jQuery('#map')[0];\n  var bounds=feature.geometry.bounds.clone();\n  // extend the boundary to include a buffer, so the map does not zoom too tight.\n  var dy = (bounds.top-bounds.bottom) * div.settings.maxZoomBuffer;\n  var dx = (bounds.right-bounds.left) * div.settings.maxZoomBuffer;\n  bounds.top = bounds.top + dy;\n  bounds.bottom = bounds.bottom - dy;\n  bounds.right = bounds.right + dx;\n  bounds.left = bounds.left - dx;\n  if (div.map.getZoomForExtent(bounds) > div.settings.maxZoom) {\n    // if showing something small, don't zoom in too far\n    div.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n  } else {\n    // Set the default view to show something triple the size of the grid square\n    // Assume this is within the map extent\n    div.map.zoomToExtent(bounds);\n  }\n};\nZoomToSite = function(){\n  var div = jQuery('#map')[0];\n  if(modPointFeature.feature){\n    return ZoomToFeature(modPointFeature.feature);}\n  if(modPathFeature.feature){\n    return ZoomToFeature(modPathFeature.feature);}\n  if(modAreaFeature.feature){\n    return ZoomToFeature(modAreaFeature.feature);}\n  var highlighted = gethighlight();\n  if(highlighted.length>0){\n    var div = jQuery('#map')[0];\n    var bounds=highlighted[0].geometry.bounds.clone();\n    \$.each(highlighted, function(idx, feat){\n      bounds.extend(feat.geometry.bounds);\n    });\n    // extend the boundary to include a buffer, so the map does not zoom too tight.\n    var dy = (bounds.top-bounds.bottom) * div.settings.maxZoomBuffer;\n    var dx = (bounds.right-bounds.left) * div.settings.maxZoomBuffer;\n    bounds.top = bounds.top + dy;\n    bounds.bottom = bounds.bottom - dy;\n    bounds.right = bounds.right + dx;\n    bounds.left = bounds.left - dx;\n    if (div.map.getZoomForExtent(bounds) > div.settings.maxZoom) {\n      // if showing something small, don't zoom in too far\n      div.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n    } else {\n      // Set the default view to show something triple the size of the grid square\n      // Assume this is within the map extent\n      div.map.zoomToExtent(bounds);\n    }\n  }\n};\nZoomToParent = function(){\n  if(ParentLocationLayer.features.length > 0)\n    zoomToLayerExtent(ParentLocationLayer);\n};\nZoomToCountry = function(){\n\tvar div = jQuery('#map')[0];\n\tvar center = new OpenLayers.LonLat(" . $args['map_centroid_long'] . "," . $args['map_centroid_lat'] . ");\n\tcenter.transform(div.map.displayProjection, div.map.projection);\n\tdiv.map.setCenter(center, " . (int) $args['map_zoom'] . ");\n}\n/***********************************/\n/* Define Controls for use on Map. */\n/***********************************/\nselectFeatureActivate = function(){\n    if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n    if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n    if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n    modAreaFeature.deactivate();\n    modPathFeature.deactivate();\n    modPointFeature.deactivate();\n    resetVertices();\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "    if(!ParentLocationLayer.features.length) {\n      selectFeature.deactivate();\n      return false;\n    }\n" : "") . "    return true;\n};\npolygonDrawActivate = function(){\n  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  selectFeature.deactivate();\n  modPointFeature.deactivate();\n  modPathFeature.deactivate();\n  resetVertices();\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(!ParentLocationLayer.features.length) {\n    polygonDraw.deactivate();\n    return false;\n  }\n" : "") . "  highlighted = gethighlight();\n  if(highlighted.length == 0){\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "    modAreaFeature.activate();\n    return true;\n  }\n  if(highlighted[0].attributes['new'] == true){\n    modAreaFeature.activate();\n    for(var i=0; i<SiteAreaLayer.features.length; i++){\n      if(SiteAreaLayer.features[i].attributes.highlighted == true){\n        modAreaFeature.selectFeature(SiteAreaLayer.features[i]);}}\n    resetVertices();\n    return true;\n" : "    polygonDraw.deactivate();\n    selectFeature.activate();\n    return false;\n") . "  }\n  // highlight feature is an existing one.\n  if(highlighted[0].attributes.canEdit){\n    modAreaFeature.activate();\n    for(var i=0; i<SiteAreaLayer.features.length; i++){\n      if(SiteAreaLayer.features[i].attributes.highlighted == true){\n        modAreaFeature.selectFeature(SiteAreaLayer.features[i]);}}\n    resetVertices();\n    return true;\n  }\n  polygonDraw.deactivate();\n  selectFeature.activate();\n  return false;\n};\nlineDrawActivate = function(){\n  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  selectFeature.deactivate();\n  modPointFeature.deactivate();\n  modAreaFeature.deactivate();\n  resetVertices();\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(!ParentLocationLayer.features.length) {\n    lineDraw.deactivate();\n    return false;\n  }\n" : "") . "  highlighted = gethighlight();\n  if(highlighted.length == 0){\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "    modPathFeature.activate();\n    return true;\n  }\n  if(highlighted[0].attributes['new'] == true){\n    modPathFeature.activate();\n    for(var i=0; i<SitePathLayer.features.length; i++){\n      if(SitePathLayer.features[i].attributes.highlighted == true){\n        modPathFeature.selectFeature(SitePathLayer.features[i]);}}\n    resetVertices();\n    return true;\n" : "    lineDraw.deactivate();\n    selectFeature.activate();\n    return false;\n") . "  }\n  // highlight feature is an existing one.\n  if(highlighted[0].attributes.canEdit){\n    modPathFeature.activate();\n    for(var i=0; i<SitePathLayer.features.length; i++){\n      if(SitePathLayer.features[i].attributes.highlighted == true){\n        modPathFeature.selectFeature(SitePathLayer.features[i]);}}\n    resetVertices();\n    return true;\n  }\n  lineDraw.deactivate();\n  selectFeature.activate();\n  return false;\n};\npointDrawDeactivate = function(){\n  if(typeof removePopups != 'undefined') removePopups();\n  jQuery(\"#pointgrid\").hide();\n};\npointDrawActivate = function(){\n  jQuery(\"#pointgrid\").show();\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  selectFeature.deactivate();\n  modAreaFeature.deactivate();\n  modPathFeature.deactivate();\n  resetVertices();\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(!ParentLocationLayer.features.length) {\n    pointDraw.deactivate();\n    return false;\n  }\n" : "") . "  highlighted = gethighlight();\n  if(highlighted.length == 0){\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "    modPointFeature.activate();\n    return true;\n  }\n  if(highlighted[0].attributes['new'] == true){\n    modPointFeature.activate();\n    for(var i=0; i<SitePointLayer.features.length; i++){\n      if(SitePointLayer.features[i].attributes.highlighted == true){\n        modPointFeature.selectFeature(SitePointLayer.features[i]);\n        resetVertices();}}\n    if(typeof populatePGrid != 'undefined') populatePGrid();\n    return true;\n" : "    pointDraw.deactivate();\n    selectFeature.activate();\n    return false;\n") . "  }\n  // highlight feature is an existing one.\n  if(highlighted[0].attributes.canEdit){\n    modPointFeature.activate();\n    for(var i=0; i<SitePointLayer.features.length; i++){\n      if(SitePointLayer.features[i].attributes.highlighted == true){\n        modPointFeature.selectFeature(SitePointLayer.features[i]);\n        resetVertices();}}\n    if(typeof populatePGrid != 'undefined') populatePGrid();\n    return true;\n  }\n  pointDraw.deactivate();\n  selectFeature.activate();\n  return false;\n};\nMyEditingToolbar=OpenLayers.Class(\n\t\tOpenLayers.Control.Panel,{\n\t\t\tinitialize:function(layer,options){\n\t\t\t\tOpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);\n\t\t\t\tthis.addControls([selectFeature\n" . ($args['usePolygons'] != 'none' ? "\t\t\t\t         ,polygonDraw\n" : '') . ($args['useLines'] != 'none' ? "\t\t\t\t         ,lineDraw\n" : '') . ($args['usePoints'] != 'none' ? "\t\t\t\t         ,pointDraw\n" : '') . ($args['usePolygons'] != 'none' || $args['useLines'] != 'none' ? "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlCancelSketch\", trigger: CancelSketch, title: '" . lang::get('LANG_CancelSketchTooltip') . "'})\n\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlUndoSketchPoint\", trigger: UndoSketchPoint, title: '" . lang::get('LANG_UndoSketchPointTooltip') . "'})\n" : '') . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlRemoveNewSite\", trigger: RemoveNewSite, title: '" . lang::get('LANG_RemoveNewSite') . "'})\n\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlStartNewSite\", trigger: StartNewSite, title: '" . lang::get('LANG_StartNewSite') . "'})\n" : '') . "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlZoomToSite\", trigger: ZoomToSite, title: '" . lang::get('LANG_ZoomToSite') . "'})\n" . ($args['locationMode'] != 'single' ? "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlZoomToSquare\", trigger: ZoomToParent, title: '" . lang::get('LANG_ZoomToParent') . "'})\n" : '') . "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlZoomToCountry\", trigger: ZoomToCountry, title: '" . lang::get('LANG_ZoomToCountry') . "'})\n\t\t\t\t         ]);\n\t},\n\tCLASS_NAME:\"MyEditingToolbar\"});\ndeactivateControls = function(){\n  if(typeof editControl != 'undefined'){\n    for(var i = editControl.controls.length-1; i>=0; i--){\n      if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\" ||\n         editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.SelectFeature\") {\n        editControl.controls[i].deactivate();\n    }}}\n};\nsetSpecifiedLocation = function() {\n  var highlighted = gethighlight();\n  if(highlighted[0].attributes.canEdit){\n    setPermissionsOldEditableSite(false);\n  } else {\n    // need to leave the location parent id enabled. Don't need to set geometries as we are using an existing location.\n    setPermissionsOldReadOnlySite();\n  }\n}\nonFeatureSelect = function(evt) {\n  var feature = evt.feature;\n  if(feature.attributes.highlighted==true) return false;\n" . ($args['locationMode'] == 'multi' ? "  unhighlightAll();\n" : "  var willRemove = false;\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  for(var i=0; i<allFeatures.length; i++)\n    willRemove = willRemove || (allFeatures[i].attributes['new']==true);\n  if(willRemove && !confirm('" . lang::get('LANG_ConfirmRemoveDrawnSite') . "')) return false;\n  var highlighted = gethighlight();\n  if(highlighted.length > 0 && highlighted[0].attributes['new'])\n    removeDrawnGeom(highlighted[0].attributes.SiteNum);\n  else\n    // Any highlighted existing features should be unhighlighted.\n    unhighlightAll();\n  jQuery(\"#" . $options['MainFieldID'] . ",#sample-location-id\").val(feature.attributes.data.id);\n") . "  ZoomToFeature(feature);\n  // now highlight the new ones\n  highlightMe(false, feature.attributes.SiteNum); // need to fetch SiteNum in case highlight new.\n  loadLocation(feature);\n  return false;\n}\nmodAreaFeature = new OpenLayers.Control.ModifyFeature(SiteAreaLayer,{standalone: true});\nmodPathFeature = new OpenLayers.Control.ModifyFeature(SitePathLayer,{standalone: true});\nmodPointFeature = new OpenLayers.Control.ModifyFeature(SitePointLayer,{standalone: true});\nselectFeature = new OpenLayers.Control.SelectFeature([SiteAreaLayer,SitePathLayer,SitePointLayer,SiteLabelLayer],{'displayClass':'olControlSelectFeature', title: '" . lang::get('LANG_SelectTooltip') . "'});\nselectFeature.events.on({'activate': selectFeatureActivate});\npolygonDraw = new OpenLayers.Control.DrawFeature(SiteAreaLayer,OpenLayers.Handler.Polygon,{'displayClass':'olControlDrawFeaturePolygon', drawFeature: addDrawnPolygonToSelection, title: '" . lang::get('LANG_PolygonTooltip') . "'});\npolygonDraw.events.on({'activate': polygonDrawActivate});\nlineDraw = new OpenLayers.Control.DrawFeature(SitePathLayer,OpenLayers.Handler.Path,{'displayClass':'olControlDrawFeaturePath', drawFeature: addDrawnLineToSelection, title: '" . lang::get('LANG_LineTooltip') . "'});\nlineDraw.events.on({'activate': lineDrawActivate});\npointDraw = new OpenLayers.Control.DrawFeature(SitePointLayer,OpenLayers.Handler.Point,{'displayClass':'olControlDrawFeaturePoint', drawFeature: addDrawnPointToSelection, title: '" . lang::get('LANG_PointTooltip') . "'});\npointDraw.events.on({'activate': pointDrawActivate, 'deactivate': pointDrawDeactivate});\neditControl = new MyEditingToolbar(SiteAreaLayer, {allowDepress: false, 'displayClass':'olControlEditingToolbar'});\n\nmapInitialisationHooks.push(function(mapdiv) {\n\t// try to identify if this map is the main one\n\tif(mapdiv.id=='map'){\n\t\tmapdiv.map.addControl(modAreaFeature);\n\t\tmapdiv.map.addControl(modPathFeature);\n\t\tmapdiv.map.addControl(modPointFeature);\n\t\tmodAreaFeature.deactivate();\n\t\tmodPathFeature.deactivate();\n\t\tmodPointFeature.deactivate();\n\t\tmapdiv.map.addControl(editControl);\n" . (isset($args['mousePosControl']) && $args['mousePosControl'] ? "\t\tjQuery('.olControlEditingToolbar').append('<span id=\"mousePos\"></span>');\n\t\tvar mousePosCtrl = new OpenLayers.Control.MousePosition({\n\t\t  div: document.getElementById('mousePos'),\n\t\t  prefix: 'LUREF:',\n\t\t  displayProjection: new OpenLayers.Projection('EPSG:2169'),\n\t\t  emptyString: '',\n\t\t  numDigits: 0 \n\t\t});\n\t\tmapdiv.map.addControl(mousePosCtrl);\n" : "") . "\t\teditControl.activate();\n\t\tif(SiteAreaLayer.map.editLayer){\n\t\t\tSiteAreaLayer.map.editLayer.clickControl.deactivate();\n\t\t\tSiteAreaLayer.map.editLayer.destroyFeatures();\n\t\t}\n\t\tmapdiv.map.events.on({'zoomend': function(){\n\t\t  if(jQuery('#map')[0].map.zoom >= " . $args['labelZoomLevel'] . "){\n\t\t    if(!SiteLabelLayer.getVisibility())\n\t\t      SiteLabelLayer.setVisibility(true);\n\t\t  } else {\n\t \t   if(SiteLabelLayer.getVisibility())\n\t \t     SiteLabelLayer.setVisibility(false);\n\t \t }\n\t\t}});\n\t\tmapdiv.map.events.triggerEvent('zoomend');\n";
    // If entity to load is set, then we are highlighting an existing location, can't modify, but can start drawing another site.
    if (isset(data_entry_helper::$entity_to_load['location:id'])) {
        switch ($args['locationMode']) {
            // TBD fieldname should be ParentFieldName
            case 'multi':
                data_entry_helper::$javascript .= "\t\tloadFeatures(" . data_entry_helper::$entity_to_load['sample:location_id'] . ",'',{initial: true}, true, true, true, true, true);\n";
                break;
            case 'single':
                data_entry_helper::$javascript .= "\t\tloadFeatures(''," . data_entry_helper::$entity_to_load['location:id'] . ",{initial: true}, false, false, false, false, true);\n";
                break;
            case 'filtered':
                $activeParent = false;
                $filterAttrs = explode(',', $args['filterAttrs']);
                foreach ($filterAttrs as $idx => $filterAttr) {
                    $filterAttr = explode(':', $filterAttr);
                    if ($filterAttr[0] == 'Parent' && $filterAttr[1] == "true") {
                        $activeParent = true;
                    }
                }
                if ($activeParent) {
                    data_entry_helper::$javascript .= "\t\tloadFeatures(" . data_entry_helper::$entity_to_load['location:parent_id'] . "," . data_entry_helper::$entity_to_load['location:id'] . ",{initial: true}, true, false, false, false, true);\n";
                } else {
                    data_entry_helper::$javascript .= "\t\tloadFeatures(''," . data_entry_helper::$entity_to_load['location:id'] . ",{initial: true}, false, false, false, false, true);\n";
                }
                break;
            default:
                // mode = parent
                data_entry_helper::$javascript .= "\t\tloadFeatures(" . data_entry_helper::$entity_to_load['location:parent_id'] . "," . data_entry_helper::$entity_to_load['location:id'] . ",{initial: true}, true, true, false, false, true);\n";
        }
    } else {
        if ($args['locationMode'] == 'single') {
            data_entry_helper::$javascript .= "\t\tloadFeatures('','',{initial: true}, false, false, false, true, true);\n";
        } else {
            if ($args['locationMode'] == 'filtered') {
                $activeParent = false;
                $filterAttrs = explode(',', $args['filterAttrs']);
                foreach ($filterAttrs as $idx => $filterAttr) {
                    $filterAttr = explode(':', $filterAttr);
                    if ($filterAttr[0] == 'Parent' && $filterAttr[1] == "true") {
                        $activeParent = true;
                    }
                }
                if (!$activeParent) {
                    data_entry_helper::$javascript .= "\t\tloadFeatures('','',{initial: true}, false, false, false, true, false);\n";
                }
            } else {
                // either multi, parent with none specified at the moment.
                data_entry_helper::$javascript .= "\t\tsetPermissionsNoParent();\n";
            }
        }
    }
    data_entry_helper::$javascript .= "}});\nSiteLabelLayer.events.on({\n    'beforefeatureselected': onFeatureSelect\n  });\nSiteAreaLayer.events.on({\n    'beforefeatureselected': onFeatureSelect\n    ,'featuremodified': onFeatureModified\n  });\nSitePathLayer.events.on({\n    'beforefeatureselected': onFeatureSelect\n    ,'featuremodified': onFeatureModified\n  });\nSitePointLayer.events.on({\n    'beforefeatureselected': onFeatureSelect\n    ,'featuremodified': onFeatureModified\n  });\n";
    if ($args['locationMode'] != 'multi') {
        data_entry_helper::$javascript .= "\nhook_ChildFeatureLoad = function(feature, data, child_id, childArgs){\n  if(child_id == '' || data.id != child_id){\n";
        if ($args['locationMode'] != 'filtered' && isset($args['duplicateNameCheck']) && $args['duplicateNameCheck'] == 'enforce') {
            data_entry_helper::$javascript .= "    var clearVal = jQuery('#location-name').val() == data.name;\n";
            if ($args['siteNameTermListID'] != "") {
                data_entry_helper::$javascript .= "    jQuery('#location-name').find('option').filter('[value='+data.name+']').attr('disabled','disabled');\n";
            }
            data_entry_helper::$javascript .= "    if(clearVal) jQuery('#location-name').val('');\n";
        }
        data_entry_helper::$javascript .= "    return;\n  }\n  var pointFeature = false;\n  var lineFeature = false;\n  var areaFeature = false;\n  if(typeof(feature)=='object'&&(feature instanceof Array)){\n    for(var j=0; j< feature.length; j++){\n      switch(feature[j].geometry.CLASS_NAME){\n        case \"OpenLayers.Geometry.Point\":\n        case \"OpenLayers.Geometry.MultiPoint\":\n          pointFeature = feature[j];\n          break;\n        case \"OpenLayers.Geometry.LineString\":\n        case \"OpenLayers.Geometry.MultiLineString\":\n          lineFeature = feature[j];\n          break;\n        default:\n          areaFeature = feature[j];\n          break;\n      }\n    }\n  } else {\n    switch(feature.geometry.CLASS_NAME){\n      case \"OpenLayers.Geometry.Point\":\n      case \"OpenLayers.Geometry.MultiPoint\":\n        pointFeature = feature;\n        break;\n      case \"OpenLayers.Geometry.LineString\":\n      case \"OpenLayers.Geometry.MultiLineString\":\n        lineFeature = feature;\n        break;\n      default:\n        areaFeature = feature;\n      break;\n    }\n  }\n  var Zoomed=false;\n  if(areaFeature) {\n    areaFeature.attributes.highlighted=true;\n    selectFeature.highlight(areaFeature);\n    ZoomToFeature(areaFeature);\n    Zoomed=true;\n  }\n  if(lineFeature) {\n    lineFeature.attributes.highlighted=true;\n    selectFeature.highlight(lineFeature);\n    if(!Zoomed) ZoomToFeature(lineFeature);\n    Zoomed=true;\n  }\n  if(pointFeature) {\n    pointFeature.attributes.highlighted=true;\n    selectFeature.highlight(pointFeature);\n    if(!Zoomed) ZoomToFeature(pointFeature);\n  }\n//  setGeomFields();\n};\njQuery('#location-name').change(function(){";
        if ($args['locationMode'] != 'filtered' && isset($args['duplicateNameCheck']) && ($args['duplicateNameCheck'] == true || $args['duplicateNameCheck'] == 'check' || $args['duplicateNameCheck'] == 'enforce')) {
            data_entry_helper::$javascript .= "\n  for(var i=0; i< SiteLabelLayer.features.length; i++){\n    if(SiteLabelLayer.features[i].attributes['new'] == false){\n      if(jQuery(this).val() == SiteLabelLayer.features[i].attributes.data.name){\n        alert(\"" . lang::get('LANG_DuplicateName') . "\");\n" . ($args['duplicateNameCheck'] == 'enforce' ? "\t\t jQuery(this).val('');\n" : "") . "      }\n    }\n  }";
        }
        data_entry_helper::$javascript .= "\n  jQuery('#sample-location-name').val(jQuery(this).val());\n});\njQuery('#location-id').change(function(){\n  jQuery('#sample-location-id').val(jQuery(this).val());\n  });\n//  jQuery(\"#location-name\").val('');\n// In order to change this value, there must be a list of values: therefore the parent has been filled in\n// With a parent filled in, there are 3 states\n// If nothing is selected, then the mod control allows selection of an existing feature, or the draw controls allow the creation of a new site.\n// With a new site in progress, then the mod control allows modification of the new site or selection of an existing feature, or the draw controls allow the additional of elements to the new site.\n// With a existing site selected, then the mod control allows selection of a different existing feature, or the draw controls allow the creation of a new site.\n// the state of the mod and draw controls re enabling stays the same before and afterwards.\nmainFieldChange = function(resetName){\n  // this is only used when not multisite.\n  var highlighted = gethighlight();\n  var found=false;\n  var myVal = jQuery('#" . $options['MainFieldID'] . "').val();\n  // only confirm if have something drawn on map: ie ignore label\n  for(i=0; i<highlighted.length; i++){\n    if(highlighted[i].layer != SiteLabelLayer && highlighted[i].attributes['new']==true)\n      found=true;\n  }\n  if(found){\n    if(!confirm('" . lang::get('LANG_ConfirmRemoveDrawnSite') . "')) return false;\n  }\n  if(highlighted.length>0 && highlighted[0].attributes['new']==true){\n    removeDrawnGeom(highlighted[0].attributes.SiteNum);\n  }\n  jQuery('#sample-location-id').val(myVal);\n  unhighlightAll();\n  pointDraw.deactivate();\n  lineDraw.deactivate();\n  polygonDraw.deactivate();\n  selectFeature.activate();\n  setPermissionsNoSite();\n  if(myVal=='') {\n    clearLocation(true, resetName);\n    return;\n  }\n  // at this point we have selected an existing site.\n  highlightMe(myVal, false);\n  ZoomToSite();\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  for(var i=0; i<allFeatures.length; i++){\n    if(typeof allFeatures[i].attributes.data != 'undefined' &&\n        typeof allFeatures[i].attributes.data.id != 'undefined' &&\n        allFeatures[i].attributes.data.id == myVal){\n      loadLocation(allFeatures[i]); // sets permissions.\n      return;\n    }\n  }\n  clearLocation(true, true);\n}\njQuery('#" . $options['MainFieldID'] . "').change(function(){mainFieldChange(true)});\n";
    }
    if ($args['locationMode'] == 'multi' && isset(data_entry_helper::$entity_to_load["sample:updated_by_id"])) {
        // only set if data loaded from db, not error condition
        iform_mnhnl_set_editable($auth, $args, $node, array(), $options['AdminMode'], $loctypeParam);
        // TBD sort 2169 hardcode
        // this required when adding sites when editting existing samples
        $retVal .= "<input type=\"hidden\" id=\"imp-sref-system\" name=\"location:centroid_sref_system\" value=\"2169\" >";
        // multiple site: parent sample points to parent location in location_id, not parent_id. Each site has own subsample.
        // can not change the (parent) location of the main sample, as this will reset all the attached samples and sites, so rendering entered data useless. Just delete.
        return $retVal . "\n<input type=\"hidden\" name =\"sample:location_id\" value=\"" . data_entry_helper::$entity_to_load["sample:location_id"] . "\" >\n  <p>" . $options['ParentLabel'] . ' : ' . data_entry_helper::$entity_to_load["location:name"] . '</p>
' . ($args['includeNumSites'] ? "<label for=\"dummy-num-sites\" class=\"auto-width\">" . lang::get('LANG_NumSites') . ":</label> <input id=\"dummy-num-sites\" name=\"dummy:num-sites\" class=\"checkNumSites narrow\" readonly=\"readonly\"><br />\n" : '') . "<p>" . $options['Instructions2'] . "</p>\n" . ($options['AdminMode'] && (!isset($args['adminsCanCreate']) || !$args['adminsCanCreate']) ? '<p>' . lang::get('LANG_LocModTool_CantCreate') . '</p>' : '') . ($args['siteNameTermListID'] == '' ? "<label for=\"dummy-name\">" . $options['NameLabel'] . ":</label> <input id=\"dummy-name\" name=\"dummy:name\" class='wide required'><br />\n" : data_entry_helper::select(array('label' => $options['NameLabel'], 'id' => 'dummy-name', 'fieldname' => 'dummy:name', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'term', 'blankText' => '', 'class' => 'checkGrid', 'extraParams' => $auth['read'] + array('termlist_id' => $args['siteNameTermListID'], 'orderby' => 'id'))));
    }
    $retVal .= "<input type='hidden' id=\"sample-location-name\" name=\"sample:location_name\" value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['sample:location_name']) . "\" />";
    if ($args['includeLocTools'] && function_exists('iform_loctools_listlocations')) {
        $locations = iform_loctools_listlocations($node);
    } else {
        $locations = 'all';
    }
    if ($args['locationMode'] == 'parent' || $args['locationMode'] == 'multi') {
        if (!isset($args['loctoolsLocTypeID'])) {
            return "locationMode == parent, loctoolsLocTypeID not set.";
        }
        iform_mnhnl_set_editable($auth, $args, $node, array(), $args['locationMode'] == 'parent' ? "conditional" : $options['AdminMode'], $loctypeParam);
        $locOptions = array('validation' => array('required'), 'label' => $options['ChooseParentLabel'], 'id' => $options['ChooseParentFieldID'], 'table' => 'location', 'fieldname' => $options['ChooseParentFieldName'], 'valueField' => 'id', 'captionField' => 'name', 'template' => 'select', 'itemTemplate' => 'select_item', 'columns' => 'id,name', 'extraParams' => array_merge($auth['read'], array('parent_id' => 'NULL', 'view' => 'detail', 'orderby' => 'name', 'location_type_id' => $args['loctoolsLocTypeID'], 'deleted' => 'f')));
        $locResponse = data_entry_helper::get_population_data($locOptions);
        if (isset($locResponse['error'])) {
            return "PARENT LOOKUP ERROR:  " . $locResponse['error'];
        }
        $opts = "";
        if (!isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']])) {
            $opts = str_replace(array('{value}', '{caption}', '{selected}'), array('', htmlentities(lang::get('LANG_CommonParentBlank')), ''), $indicia_templates[$locOptions['itemTemplate']]);
        }
        foreach ($locResponse as $record) {
            $include = false;
            if ($locations == 'all') {
                $include = true;
            } else {
                if (in_array($record["id"], $locations)) {
                    $include = true;
                }
            }
            if ($include == true) {
                $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array($record[$locOptions['valueField']], htmlentities($record[$locOptions['captionField']]), isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] == $record[$locOptions['valueField']] ? 'selected=selected' : '' : ''), $indicia_templates[$locOptions['itemTemplate']]);
            }
        }
        $locOptions['items'] = $opts;
        $retVal .= '<p>' . $options['Instructions1'] . '</p>' . data_entry_helper::apply_template($locOptions['template'], $locOptions) . ($args['includeNumSites'] ? '<label for="dummy-num-sites" class="auto-width">' . lang::get('LANG_NumSites') . ':</label> <input id="dummy-num-sites" name="dummy:num-sites" class="checkNumSites narrow" readonly="readonly"><br />
' : '') . '<p>' . $options['Instructions2'] . '</p>' . ($options['AdminMode'] && (!isset($args['adminsCanCreate']) || !$args['adminsCanCreate']) ? '<p>' . lang::get('LANG_LocModTool_CantCreate') . '</p>' : '');
    }
    if ($args['locationMode'] == 'parent') {
        $retVal .= "<input type='hidden' id=\"sample-location-id\" name=\"sample:location_id\" value='" . data_entry_helper::$entity_to_load['sample:location_id'] . "' />";
        data_entry_helper::$javascript .= "\njQuery(\"#" . $options['ChooseParentFieldID'] . "\").change(function(){\n  jQuery(\"#imp-geom,#imp-boundary-geom,#imp-sref,#imp-srefX,#imp-srefY,#" . $options['MainFieldID'] . ",#" . $options['ParentFieldID'] . ",#sample-location-id,#location-name,#sample-location-name\").val('');\n  jQuery(\"#location_location_type_id\").val('{$primary}');\n  loadFeatures(this.value, '', {initial: false}, true, true, true, true, true);\n  if(typeof hook_mnhnl_parent_changed != 'undefined')\n    hook_mnhnl_parent_changed();\n});\njQuery(\"#" . $options['ParentFieldID'] . "\").change(function(){\n  if(jQuery(this).val() != '') {\n    // we have a new parent location, so draw boundary\n    jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location/\"+jQuery(this).val()+\"?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?\",\n      function(data) {\n       if (data.length>0) {\n         var parser = new OpenLayers.Format.WKT();\n         if(data[0].boundary_geom){ // only one location if any\n           var feature = parser.read(data[0].boundary_geom)\n           feature=convertFeature(feature, \$('#map')[0].map.projection);\n           ParentLocationLayer.destroyFeatures();\n           ParentLocationLayer.addFeatures([feature]);\n           zoomToLayerExtent(ParentLocationLayer);\n         }\n       }});\n" . ($options['AdminMode'] ? "    // in admin mode we have to reset the location name drop downs.\n    jQuery('#location-name').find('option').removeAttr('disabled');\n" . (isset($args['duplicateNameCheck']) && ($args['duplicateNameCheck'] == true || $args['duplicateNameCheck'] == 'check' || $args['duplicateNameCheck'] == 'enforce') ? "    jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location?parent_id=\"+jQuery(this).val()+\"&location_type_id" . $primary . "&mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?\",\n      function(data) {\n        if (data.length>0) {\n          var currentName = jQuery('#location-name').val();\n          var currentID = jQuery('#" . $options['MainFieldID'] . "').val();\n          // first check if there is a clash and give a warning\n          for(var di=0; di<data.length; di++){\n            if(currentName == data[di].name && currentID != data[di].id && currentID != ''){\n              alert(\"" . lang::get('This site name is already in use in the new square. Please choose another.') . "\");\n              break; // only display one message\n            }\n          }\n" . ($args['duplicateNameCheck'] == 'enforce' ? "          // if enforce, disable all options for existing and reset the name value if needed.\n          for(var di=0; di<data.length; di++){\n            if(data[di].name == parseInt(data[di].name) && currentID != data[di].id)\n              // only disable fields for existing locations for numeric names and which are not me. \n              jQuery('#location-name').find('option').filter('[value='+data[di].name+']').attr('disabled','disabled');\n          }\n          // finally if enforce and there is a clash, reset the value. This will then automatically take first available.\n          for(var di=0; di<data.length; di++){\n            if(currentName == data[di].name && currentID != data[di].id)\n              jQuery('#location-name').val('');\n          }\n" : "") . "\n       }});\n" : "") : "") . "  } else\n    ParentLocationLayer.destroyFeatures();\n});\n";
        // choose a single site from a parent, so built site selector drop down.
        // parent uses ID locModTool
        $opts = "";
        $locOptions = array('label' => $options['MainFieldLabel'], 'id' => $options['MainFieldID'], 'table' => 'location', 'fieldname' => $options['MainFieldName'], 'valueField' => 'id', 'captionField' => 'name', 'template' => 'select', 'itemTemplate' => 'select_item', 'nocache' => true, 'extraParams' => array_merge($auth['read'], array('parent_id' => data_entry_helper::$entity_to_load["location:parent_id"], 'view' => 'detail', 'orderby' => 'name', 'location_type_id' => $loctypeParam, 'deleted' => 'f')));
        if (isset(data_entry_helper::$entity_to_load["sample:id"])) {
            // if preloaded, then drop down is dependant on value in parent field: if not then get user to enter parent first
            $response = data_entry_helper::get_population_data($locOptions);
            // OK as parent_id filled in: not likely to be large number.
            if (isset($response['error'])) {
                return "CHILD LOOKUP ERROR:  " . $response['error'];
            }
            $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array('', htmlentities(lang::get('LANG_CommonEmptyLocationID')), ''), $indicia_templates[$locOptions['itemTemplate']]);
            foreach ($response as $record) {
                $caption = htmlspecialchars($record[$locOptions['captionField']]);
                // it will be extended using a attribute template by JS
                $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array($record[$locOptions['valueField']], htmlentities($caption), isset(data_entry_helper::$entity_to_load['location:id']) ? data_entry_helper::$entity_to_load['sample:location_id'] == $record[$locOptions['valueField']] ? 'selected=selected' : '' : ''), $indicia_templates[$locOptions['itemTemplate']]);
            }
        } else {
            $opts = "<option >" . lang::get("LANG_CommonChooseParentFirst") . "</option>";
        }
        $locOptions['items'] = $opts;
        // single site requires all location data in main form. Mult site must have array: depends on implementation so left to actual form.
        $retVal .= data_entry_helper::apply_template($locOptions['template'], $locOptions) . "<br />";
        if ($options['AdminMode']) {
            $locOptions = array('validation' => array('required'), 'label' => $options['ParentLabel'], 'id' => $options['ParentFieldID'], 'fieldname' => $options['ParentFieldName'], 'valueField' => 'id', 'captionField' => 'name', 'template' => 'select', 'itemTemplate' => 'select_item');
            $opts = str_replace(array('{value}', '{caption}', '{selected}'), array('', '', ''), $indicia_templates[$locOptions['itemTemplate']]);
            foreach ($locResponse as $record) {
                $include = false;
                if ($locations == 'all') {
                    $include = true;
                } else {
                    if (in_array($record["id"], $locations)) {
                        $include = true;
                    }
                }
                if ($include == true) {
                    $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array($record[$locOptions['valueField']], htmlentities($record[$locOptions['captionField']]), isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] == $record[$locOptions['valueField']] ? 'selected=selected' : '' : ''), $indicia_templates[$locOptions['itemTemplate']]);
                }
            }
            $locOptions['items'] = $opts;
            $retVal .= data_entry_helper::apply_template($locOptions['template'], $locOptions);
        } else {
            $retVal .= "<input type='hidden' id=\"" . $options['ParentFieldID'] . "\" name=\"" . $options['ParentFieldName'] . "\" value=\"" . (isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] : "") . "\" />";
        }
        if ($args['siteNameTermListID'] == '') {
            $retVal .= "<label for=\"location-name\">" . $options['NameLabel'] . ":</label> <input type='text' id=\"location-name\" name=\"location:name\" class='required wide' value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\" /><span class='deh-required'>*</span><br/>";
        } else {
            $retVal .= data_entry_helper::select(array('label' => $options['NameLabel'], 'id' => 'location-name', 'fieldname' => 'location:name', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'term', 'extraParams' => $auth['read'] + array('termlist_id' => $args['siteNameTermListID'], 'orderby' => 'id')));
        }
    } else {
        if ($args['locationMode'] == 'multi') {
            //TBD sort 2169 hardcode
            $retVal .= "<input type=\"hidden\" id=\"imp-sref-system\" name=\"location:centroid_sref_system\" value=\"2169\" >";
            // multiSite needs the location name.
            if ($args['siteNameTermListID'] == '') {
                $retVal .= "<label for=\"dummy-name\">" . $options['NameLabel'] . ":</label> <input type='text' id=\"dummy-name\" name=\"dummy:name\" class='wide' value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\" /><span class='deh-required'>*</span><br/>";
            } else {
                $retVal .= data_entry_helper::select(array('label' => $options['NameLabel'], 'id' => 'dummy-name', 'fieldname' => 'dummy:name', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'term', 'blankText' => '', 'class' => 'checkGrid', 'extraParams' => $auth['read'] + array('termlist_id' => $args['siteNameTermListID'], 'orderby' => 'id')));
            }
            data_entry_helper::$javascript .= "\njQuery(\"#" . $options['ChooseParentFieldID'] . "\").change(function(){\n  if(typeof hook_mnhnl_parent_changed != 'undefined')\n    hook_mnhnl_parent_changed();\n  loadFeatures(this.value, '', {initial : false}, true, true, true, true, true);\n});\n";
        } else {
            if ($args['locationMode'] == 'single') {
                // no parent look up: actual name is a text entry field.
                $location_list_args = array('nocache' => true, 'includeCodeField' => true, 'label' => lang::get('LANG_CommonLocationNameLabel'), 'NameBlankText' => lang::get('LANG_Location_Name_Blank_Text'), 'fieldname' => 'location:id', 'id' => $options['MainFieldID'], 'columns' => 'id,name,code,location_type_id', 'extraParams' => array_merge(array('view' => 'detail', 'orderby' => 'name', 'website_id' => $args['website_id'], 'location_type_id' => $loctypeParam), $auth['read']), 'table' => 'location', 'template' => 'select', 'itemTemplate' => 'select_item', 'filterField' => 'parent_id', 'size' => 3);
                // Idea here is to get a list of all locations in order to build drop downs.
                $responseRecords = data_entry_helper::get_population_data($location_list_args);
                if (isset($responseRecords['error'])) {
                    return $responseRecords['error'];
                }
                iform_mnhnl_set_editable($auth, $args, $node, $responseRecords, 'conditional', $loctypeParam);
                $usedCodes = array();
                $maxCode = 0;
                $NameOpts = '';
                foreach ($responseRecords as $record) {
                    if ($record['name'] != '') {
                        $item = array('selected' => data_entry_helper::$entity_to_load['location:id'] == $record['id'] ? 'selected=\\"selected\\"' : '', 'value' => $record['id'], 'caption' => htmlspecialchars(utf8_decode($record['name'])));
                        $NameOpts .= data_entry_helper::mergeParamsIntoTemplate($item, $location_list_args['itemTemplate']);
                        if ($record['code'] != '') {
                            $usedCodes[] = "\"" . $record['code'] . "\"";
                            if ($maxCode < $record['code']) {
                                $maxCode = $record['code'];
                            }
                        }
                    }
                }
                data_entry_helper::$javascript .= "\nvar usedCodes = [" . implode(',', $usedCodes) . "];\nvar defaultCode = " . ($maxCode + 1) . ";\n";
                $retVal .= '<p>' . $options['Instructions2'] . '</p>' . ($options['AdminMode'] && (!isset($args['adminsCanCreate']) || !$args['adminsCanCreate']) ? '<p>' . lang::get('LANG_LocModTool_CantCreate') . '</p>' : '') . '<fieldset><legend>' . lang::get('Existing locations') . '</legend>';
                if ($NameOpts != '') {
                    $location_list_args['items'] = str_replace(array('{value}', '{caption}', '{selected}'), array('', htmlentities($location_list_args['NameBlankText']), ''), $indicia_templates[$location_list_args['itemTemplate']]) . $NameOpts;
                    $retVal .= data_entry_helper::apply_template($location_list_args['template'], $location_list_args);
                    if ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode']) {
                        $retVal .= '<p>' . lang::get("LANG_Multiple_Location_Types") . '</p>';
                    }
                } else {
                    $retVal .= '<p>' . lang::get("LANG_NoSites") . '</p>';
                }
                $retVal .= "</fieldset><label for=\"location-name\">" . $options['NameLabel'] . ":</label> <input id=\"location-name\" name=\"location:name\" class='wide required' value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\"><span class=\"deh-required\">*</span><br />\n      <input type='hidden' id=\"sample-location-id\" name=\"sample:location_id\" value='" . data_entry_helper::$entity_to_load['sample:location_id'] . "' />";
            } else {
                // single location, filtered.
                data_entry_helper::$javascript .= "indiciaData.filterMode=true;\n";
                iform_mnhnl_set_editable($auth, $args, $node, array(), 'conditional', $loctypeParam);
                $retVal .= '<p>' . $options['Instructions2'] . '</p>' . ($options['AdminMode'] && (!isset($args['adminsCanCreate']) || !$args['adminsCanCreate']) ? '<p>' . lang::get('LANG_LocModTool_CantCreate') . '</p>' : '');
                $filterAttrs = explode(',', $args['filterAttrs']);
                // filter attributes are assumed to be text (could extend later)
                $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
                if (array_key_exists('location:id', data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load['location:id'] != "") {
                    // if we have location Id to load, use it to get attribute values
                    $attrArgs['id'] = data_entry_helper::$entity_to_load['location:id'];
                }
                $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
                if ($args['LocationTypeTerm'] == '' && isset($args['loctoolsLocTypeID'])) {
                    $args['LocationTypeTerm'] = $args['loctoolsLocTypeID'];
                }
                $primary = iform_mnhnl_getTermID($auth, 'indicia:location_types', $args['LocationTypeTerm']);
                $filterAttrs[] = "Name";
                // always add the location name special case to the filter list.
                $defaultsFunction = "";
                $loadFunction = "hook_loadFilters = function(){\n";
                $initFunctions = "";
                $prevAttr = null;
                $prevFilterAttr = null;
                $prevIdx = null;
                $attrList = array();
                $includeCommune = true;
                $location_list_args = array('nocache' => true, 'extraParams' => array_merge(array('orderby' => 'id', 'view' => 'detail', 'website_id' => $args['website_id'], 'location_type_id' => $primary), $auth['read']), 'columns' => 'id,name,parent_id', 'table' => 'location');
                $locList = data_entry_helper::get_population_data($location_list_args);
                if (isset($locList['error'])) {
                    return $locList['error'];
                }
                $location_attr_list_args = array('nocache' => true, 'extraParams' => array_merge(array('orderby' => 'location_id', 'view' => 'list', 'website_id' => $args['website_id'], 'location_type_id' => $primary), $auth['read']), 'table' => 'location_attribute_value');
                $locAttrList = data_entry_helper::get_population_data($location_attr_list_args);
                if (isset($locAttrList['error'])) {
                    return $locAttrList['error'];
                }
                $locTextList = array();
                $locListCount = count($locList);
                $locAttrListCount = count($locAttrList);
                for ($i = 0, $j = 0; $i < $locListCount; $i++) {
                    while ($j < $locAttrListCount && $locAttrList[$j]['location_id'] < $locList[$i]['id']) {
                        $j++;
                    }
                    $locAttrTextList = array();
                    while ($j < $locAttrListCount && $locAttrList[$j]['location_id'] == $locList[$i]['id']) {
                        $locAttrTextList[] = '"' . $locAttrList[$j]['location_attribute_id'] . '":"' . $locAttrList[$j]['raw_value'] . '"';
                        $j++;
                    }
                    $locTextList[] = "{'id':" . $locList[$i]['id'] . ", 'name':\"" . $locList[$i]['name'] . "\", 'parent_id':\"" . $locList[$i]['parent_id'] . "\", 'attrs': {" . implode(",", $locAttrTextList) . "}}";
                }
                data_entry_helper::$javascript .= "\nvar locations = [\n" . implode(",\n", $locTextList) . "];\n";
                foreach ($filterAttrs as $idx => $filterAttr) {
                    $filterAttr = explode(':', $filterAttr);
                    $attr = "";
                    if ($filterAttr[0] != "Name" && $filterAttr[0] != "Parent") {
                        foreach ($locationAttributes as $locationAttribute) {
                            if ($locationAttribute['untranslatedCaption'] == $filterAttr[0] || $filterAttr[0] == "Shape" && $locationAttribute['untranslatedCaption'] == $filterAttr[1]) {
                                $attr = $locationAttribute;
                            }
                        }
                        if ($attr == "") {
                            return '<p>' . lang::get("Location Module: Could not find attribute ") . $filterAttr[$filterAttr[0] == "Shape" ? 1 : 0] . '</p>';
                        }
                    }
                    $nextIdx = $idx + 1;
                    while ($nextIdx < count($filterAttrs)) {
                        $fparts = explode(':', $filterAttrs[$nextIdx]);
                        if ($fparts[0] != 'Parent' || $fparts[1] == "true") {
                            break;
                        }
                        $nextIdx++;
                    }
                    // need to add functionality to tie locations to a square, even if not in use (for sites form)
                    // also this form must fill in a hidden commune field.
                    switch ($filterAttr[0]) {
                        case "Parent":
                            //special case, assume only one of these in a form. Not required
                            // field 1: editable true or false
                            // field 2: display warning if outside true or false
                            // field 3: location_type term
                            $parentLocTypeID = iform_mnhnl_getTermID($auth, 'indicia:location_types', $filterAttr[3]);
                            // proxiedurl,featurePrefix,featureType,[geometryName],featureNS,srsName[,propertyNames]
                            $protocol = explode(',', $args['locationLayerLookup']);
                            data_entry_helper::$javascript .= "\nhook_setSref_" . $idx . " = function(geom){ // map projection\n  // srsName should be in map projection.\n  var protocol = new OpenLayers.Protocol.WFS({\n      url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName:'boundary_geom',featureNS: '" . $protocol[3] . "',srsName: '" . $protocol[4] . "',version: '1.1.0',propertyNames: ['boundary_geom','name']\n     ,callback: function(a1){\n        if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n          alert(\"" . lang::get('LANG_ParentLookUpFailed') . "\");\n          return;\n        }\n        if(a1.features.length > 0) {\n            var id = a1.features[0].fid.slice(" . (strlen($protocol[2]) + 1) . ")\n";
                            if ($filterAttr[1] == "true") {
                                data_entry_helper::$javascript .= "          if(jQuery('#filterSelect" . $idx . "').val() == '' || // not currently filled in\n              (jQuery('#filterSelect" . $idx . "').val() != id && confirm(\"" . lang::get('LANG_PositionInDifferentParent') . "\"))) {\n            ParentLocationLayer.destroyFeatures();\n            ParentLocationLayer.addFeatures(a1.features); // TBD check geometry system - convert?\n            jQuery('#filterSelect" . $idx . "').val(id);\n            jQuery('#" . $options['ParentFieldID'] . "').val(id);\n";
                                foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                    // just need index, so don't explode
                                    if ($idx1 > $idx && $idx1 < count($filterAttrs) - 1) {
                                        // don't do name
                                        data_entry_helper::$javascript .= "            filterLoad" . $idx1 . "();\n";
                                    }
                                }
                                // update drop downs, but leave values as they are.
                                data_entry_helper::$javascript .= "          }\n";
                            } else {
                                data_entry_helper::$javascript .= "          jQuery('#" . $options['ParentFieldID'] . "').val(id);\n          jQuery('#" . $options['ChooseParentFieldID'] . "').val(a1.features[0].attributes['name']);\n";
                            }
                            data_entry_helper::$javascript .= "\n          loadChildFeatures(id, true); // load in children onto map\n        } else {\n" . ($filterAttr[2] == 'true' ? "        alert(\"" . lang::get('LANG_PositionOutsideParent') . "\");\n" : '') . "          jQuery('#" . $options['ParentFieldID'] . "').val('');\n          jQuery('#" . ($filterAttr[1] == "true" ? "filterSelect" . $idx : $options['ChooseParentFieldID']) . "').val('');\n        }\n      }\n    });\n  filter = new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND, filters:[\n  \t\t\tnew OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.CONTAINS,property: 'boundary_geom',value: geom}),\n  \t\t\tnew OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})]});\n  protocol.read({filter: filter});\n};\n";
                            if ($filterAttr[1] == "true") {
                                // filterable.
                                // set up the parent list, cacheable
                                $locOptions = array('label' => lang::get('LANG_CommonParentLabel'), 'id' => 'filterSelect' . $idx, 'table' => 'location', 'fieldname' => $options['ChooseParentFieldName'], 'valueField' => 'id', 'captionField' => 'name', 'template' => 'select', 'itemTemplate' => 'select_item', 'validation' => array('required'), 'columns' => 'id,name', 'extraParams' => array_merge($auth['read'], array('parent_id' => 'NULL', 'view' => 'detail', 'orderby' => 'name', 'location_type_id' => $parentLocTypeID, 'deleted' => 'f')));
                                $locResponse = data_entry_helper::get_population_data($locOptions);
                                if (isset($locResponse['error'])) {
                                    return "PARENT LOOKUP ERROR:  " . $locResponse['error'];
                                }
                                $opts = str_replace(array('{value}', '{caption}', '{selected}'), array('', lang::get('LANG_FirstChooseParentFilter'), ''), $indicia_templates[$locOptions['itemTemplate']]);
                                foreach ($locResponse as $record) {
                                    $include = false;
                                    if ($locations == 'all') {
                                        $include = true;
                                    } else {
                                        if (in_array($record["id"], $locations)) {
                                            $include = true;
                                        }
                                    }
                                    if ($include == true) {
                                        $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array($record[$locOptions['valueField']], htmlentities($record[$locOptions['captionField']]), isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] == $record[$locOptions['valueField']] ? 'selected=selected' : '' : ''), $indicia_templates[$locOptions['itemTemplate']]);
                                    }
                                }
                                $locOptions['items'] = $opts;
                                $retVal .= data_entry_helper::apply_template($locOptions['template'], $locOptions);
                                if ($options['AdminMode']) {
                                    // In admin mode assume can reassign to any location: admins should have access to all squares.
                                    $location_list_args = array('view' => 'detail', 'extraParams' => array_merge(array('orderby' => 'name', 'website_id' => $args['website_id']), $auth['read']), 'location_type_id' => $parentLocTypeID, 'default' => data_entry_helper::$entity_to_load[$options['ParentFieldName']], 'validation' => array('required'), 'label' => $options['ParentLabel'], 'id' => $options['ParentFieldID'], 'fieldname' => $options['ParentFieldName'], 'blankText' => '');
                                    $retVal .= data_entry_helper::location_select($location_list_args);
                                } else {
                                    $retVal .= "<input type='hidden' id='" . $options['ParentFieldID'] . "' name='" . $options['ParentFieldName'] . "' value='" . (isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] : "") . "' />";
                                }
                                data_entry_helper::$javascript .= "indiciaData.filterParent=true;\n// load the counts to the end of the parent drop down list. Do only once. Equivalent to filterLoad" . $idx . "\njQuery('#filterSelect" . $idx . " option').each(function(idx, elem){\n  if(elem.value=='') return;\n  for(i=0, j=0; i< locations.length; i++){\n    if(locations[i]['parent_id']==elem.value) j++;\n  }\n  if(j) elem.text=elem.text+' ('+j+')';\n});\ndisplayParent = function(zoom){\n  var parent_id = jQuery('#filterSelect" . $idx . "').val();\n  loadFeatures(parent_id, '', {initial : false}, true, false, zoom, false, false);\n}\njQuery('#filterSelect" . $idx . "').change(function(){\n  jQuery('#" . $options['ParentFieldID'] . "').val(jQuery(this).val());\n  SetFilterNewLocation();\n";
                                foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                    if ($idx1 > $idx) {
                                        data_entry_helper::$javascript .= "  filterReset" . $idx1 . "();\n";
                                    }
                                }
                                data_entry_helper::$javascript .= "  if(jQuery(this).val()!=''){\n";
                                foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                    if ($idx1 > $idx) {
                                        data_entry_helper::$javascript .= "    filterLoad" . $idx1 . "();\n";
                                    }
                                }
                                data_entry_helper::$javascript .= "  }\n  displayParent(true);\n});\n";
                                $defaultsFunction .= "  if(keepFilter){\n    jQuery('#" . $options['ParentFieldID'] . "').val(jQuery('#filterSelect" . $idx . "').val());\n  } else {\n    jQuery('#filterSelect" . $idx . "').val('');\n  }\n";
                                $prevFilterAttr = $filterAttr;
                                $prevAttr = $attr;
                                $prevIdx = $idx;
                            } else {
                                // not filterable: just readonly field
                                $retVal .= '<input id="' . $options['ParentFieldID'] . '" name="' . $options['ParentFieldName'] . '" type="hidden" value="' . (isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) && data_entry_helper::$entity_to_load[$options['ParentFieldName']] != "" && data_entry_helper::$entity_to_load[$options['ParentFieldName']] != null ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] : '') . '">' . '<input id="' . $options['ChooseParentFieldID'] . '" name="dummy" value="" disabled="disabled" >';
                                $loadFunction .= "  populate" . $idx . "();\n";
                                data_entry_helper::$javascript .= "\n\$('#sample-location-id').before('<label>" . lang::get('LANG_CommonParentLabel') . ":</label> ');\n\$('#" . $options['ChooseParentFieldID'] . "').insertBefore('#sample-location-id');\n\$('#sample-location-id').before('<br/>');\npopulate" . $idx . " = function(){\n  jQuery('#" . $options['ChooseParentFieldID'] . "').val('');\n  if(jQuery('#" . $options['ParentFieldID'] . "').val()!='' && jQuery('#" . $options['ParentFieldID'] . "').val() != null){\n    var protocol = new OpenLayers.Protocol.WFS({\n        url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName:'boundary_geom',featureNS: '" . $protocol[3] . "',srsName: '" . $protocol[4] . "',version: '1.1.0',propertyNames: ['boundary_geom','name']\n       ,callback: function(a1){\n          if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n            alert(\"" . lang::get('LANG_ParentLookUpFailed') . "\");\n          } else if(a1.features.length > 0) {\n            jQuery('#" . $options['ChooseParentFieldID'] . "').val(a1.features[0].attributes['name']);\n        }}});\n    var filter = new OpenLayers.Filter.FeatureId({fids: ['" . $protocol[2] . ".'+jQuery('#" . $options['ParentFieldID'] . "').val()]});\n    protocol.read({filter: filter});\n  }\n};\nfilterLoad" . $idx . " = function(){\n  populate" . $idx . "();\n};\npopulate" . $idx . "();\nfilterReset" . $idx . " = function(){\n  jQuery('#" . $options['ChooseParentFieldID'] . "').val('');\n};";
                            }
                            // have to extract id from fid.
                            break;
                        case "Shape":
                            //special case: geoserver shape file look up, assume only one of these in a form.
                            // 0 = "Shape"
                            // 1 = Attribute Caption, e.g. "Commune"
                            // 2 = display warning if outside list (will be set to blank)
                            // 3 = optional location type term filter
                            // 4 = buffer
                            // Note that for Commune readonly displays, the normal Commune functionality is used, e.g. in the Amphibians Squares where the Commune must be kept in line so the Amphibian Sites can use it.
                            $parentLocTypeID = $filterAttr[3] != '' ? iform_mnhnl_getTermID($auth, 'indicia:location_types', $filterAttr[3]) : -1;
                            // proxiedurl,featurePrefix,featureType,geometryName,featureNS,srsName,propertyNames
                            if ($filterAttr[1] == "Commune") {
                                $includeCommune = false;
                            }
                            $protocol = explode(',', $filterAttr[1] == "Commune" ? $args['communeLayerLookup'] : $args['locationLayerLookup']);
                            $retVal .= '<input id="' . $attr['id'] . '" class="filterFields" name="' . $attr['fieldname'] . '" type="hidden" value="' . $attr['default'] . '"><label>' . $attr['caption'] . ':</label> <select class="required" id="filterSelect' . $idx . '"></select><span class="deh-required">*</span><br/>';
                            $attrList[] = array('id' => $attr['attributeId'], 'shape' => true);
                            data_entry_helper::$javascript .= "\ndisplayShape = function(zoom){\n  ParentLocationLayer.destroyFeatures();\n  if(jQuery('#filterSelect" . $idx . "').val()=='') return;\n  var protocol = new OpenLayers.Protocol.WFS({ // WFS request is to be made in the map projection\n    url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName: '" . $protocol[3] . "',featureNS: '" . $protocol[4] . "',srsName: '" . $protocol[5] . "',version: '1.1.0',propertyNames: ['" . $protocol[6] . "','" . $protocol[3] . "']\n   ,callback:function(data){\n      if(data.features.length>0){ // feature is in map projection\n        ParentLocationLayer.addFeatures(data.features); // TBD check geometry system - convert?\n        if(zoom) ZoomToParent();\n      }}});\n  var filter = new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: '" . $protocol[6] . "', value: jQuery('#filterSelect" . $idx . "').val()});\n" . ($filterAttr[3] != '' ? "  filter = new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND, filters:[filter, new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})]});\n" : '') . "  protocol.read({filter: filter});\n}\nfilterLoad" . $idx . " = function(){\n  var protocol = new OpenLayers.Protocol.WFS({\n    url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName: '" . $protocol[3] . "',featureNS: '" . $protocol[4] . "',srsName: '" . $protocol[5] . "',version: '1.1.0',sortBy: '" . $protocol[6] . "',propertyNames: ['" . $protocol[6] . ($filterAttr[3] != '' ? "','location_type_id" : '') . "']\n    ,callback:function(data){\n      jQuery('#filterSelect" . $idx . "').empty().append('<option value=\"\">" . lang::get("Please select...") . "</option>');\n      var names=[];\n      for(var i=0; i<data.features.length; i++) names.push(data.features[i].attributes['" . $protocol[6] . "']);\n      names.sort(); // the sort WFS does not work...\n      for(var i=0; i<names.length; i++) {\n        for(j=0, count=0; j< locations.length; j++){\n          if(locations[j].attrs['" . $attr['attributeId'] . "']==names[i]) {\n            count++;\n            locations[j].shapeFound=true;\n          }\n        }\n        jQuery('#filterSelect" . $idx . "').append('<option value=\"'+names[i]+'\">'+names[i]+(count?' ('+count+')':'')+'</option>');\n      }\n      for(j=0; j< locations.length; j++){ // add any communes which are in the locations but not in the shape file.\n        if(typeof locations[j].shapeFound == 'undefined'){\n          for(i=0, count=0; i< locations.length; i++){\n            if(locations[j].attrs['" . $attr['attributeId'] . "']==locations[i].attrs['" . $attr['attributeId'] . "']) {\n              count++;\n              locations[i].shapeFound=true;\n            }\n          }\n          jQuery('#filterSelect" . $idx . "').append('<option value=\"'+locations[j].attrs['" . $attr['attributeId'] . "']+'\">'+locations[j].attrs['" . $attr['attributeId'] . "']+' ('+count+')'+'</option>');\n        }\n      }\n      if(jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val()!=''){\n        jQuery('#filterSelect" . $idx . "').val(jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val());\n        displayShape(false);\n      }\n  }});\n  protocol.read(" . ($filterAttr[3] != '' ? "{filter: new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})}" : '') . ");\n}\n// this is only done once\nfilterLoad" . $idx . "();\nhook_setSref_" . $idx . " = function(geom){ // map projection\n  // srsName should be in map projection.\n  var protocol = new OpenLayers.Protocol.WFS({\n      url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName:'" . $protocol[3] . "',featureNS: '" . $protocol[4] . "',srsName: '" . $protocol[5] . "',version: '1.1.0',propertyNames: [\"" . $protocol[6] . "\",'" . $protocol[3] . "']\n     ,callback: function(a1){\n        if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n          alert(\"" . lang::get('LANG_' . $filterAttr[1] . 'LookUpFailed') . "\");\n          return;\n        }\n        if(a1.features.length > 0) {\n          if(jQuery('#filterSelect" . $idx . "').val() == '' || // not currently filled in\n              (jQuery('#filterSelect" . $idx . "').val() != a1.features[0].attributes[\"" . $protocol[6] . "\"] && confirm(\"" . lang::get('LANG_PositionInDifferent' . $filterAttr[1]) . "\"))) {\n            ParentLocationLayer.destroyFeatures();\n            ParentLocationLayer.addFeatures(a1.features); // feature should be in map projection\n            jQuery('#filterSelect" . $idx . "').val(a1.features[0].attributes[\"" . $protocol[6] . "\"]);\n            jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val(a1.features[0].attributes[\"" . $protocol[6] . "\"]);\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                // just need index, so don't explode
                                if ($idx1 > $idx && $idx1 < count($filterAttrs) - 1) {
                                    // don't do name
                                    data_entry_helper::$javascript .= "            filterLoad" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "          } // else user choose not to change\n        } else {\n";
                            if (!isset($args['communeLayerBuffer']) || $args['communeLayerBuffer'] == "") {
                                // No buffer in definition
                                data_entry_helper::$javascript .= "          if(jQuery('#filterSelect" . $idx . "').val() == '') { // not currently filled in\n            alert(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_1") . "\");\n          } else if(!confirm(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_2") . "\")) {\n            jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val('');\n            jQuery('#filterSelect" . $idx . "').val('');\n            ParentLocationLayer.destroyFeatures();\n          }\n";
                            } else {
                                // buffer set
                                data_entry_helper::$javascript .= "          //  Get list of communes within buffer of geom\n          var protocol = new OpenLayers.Protocol.WFS({\n              url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName:'" . $protocol[3] . "',featureNS: '" . $protocol[4] . "',srsName: '" . $protocol[5] . "',version: '1.1.0',propertyNames: [\"" . $protocol[6] . "\",'" . $protocol[3] . "']\n             ,callback: function(a1){\n                var replace = false,\n                    reset = false;\n                if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n                  alert(\"" . lang::get('LANG_' . $filterAttr[1] . 'LookUpFailed') . "\");\n                  return;\n                }\n                if(a1.features.length == 0) {\n                  if(jQuery('#filterSelect" . $idx . "').val() == '') { // not currently filled in\n                    alert(\"" . str_replace('{DISTANCE}', $args['communeLayerBuffer'], lang::get('LANG_PositionOutside' . $filterAttr[1] . "_3")) . "\");\n                  } else if(!confirm(\"" . str_replace('{DISTANCE}', $args['communeLayerBuffer'], lang::get('LANG_PositionOutside' . $filterAttr[1] . "_4")) . "\")) {\n                    reset = true;\n                  }\n                } else {\n                  var closest = 0;\n                  if(a1.features.length >= 0) {\n                    for(var i=0; i< a1.features.length; i++){\n                      var distance, thisDistance = geom.distanceTo(a1.features[i].geometry, {});\n                      if(i==0 || thisDistance<distance){\n                        closest=i;\n                        distance=thisDistance;\n                      }\n                    }\n                  }\n                  if(jQuery('#filterSelect" . $idx . "').val() == '') { // not currently filled in\n                    if(confirm(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_5") . "\".replace(/SHAPE/g, a1.features[closest].attributes['" . $protocol[6] . "']))){\n                      replace = true;\n                    }\n                  } else if(jQuery('#filterSelect" . $idx . "').val() == a1.features[closest].attributes[\"" . $protocol[6] . "\"]){\n                    if(confirm(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_6") . "\".replace(/SHAPE/g, a1.features[closest].attributes['" . $protocol[6] . "']))){\n                      replace = true;\n                    } else {\n                      reset = true;\n                    }\n                  } else { // doesn't match\n                    if(confirm(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_7") . "\".replace(/SHAPE/g, a1.features[closest].attributes['" . $protocol[6] . "']).replace(/OLD/g, jQuery('#filterSelect" . $idx . "').val()))){\n                      replace = true;\n                    }\n                  }\n                }\n                if(reset) {\n                  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val('');\n                  jQuery('#filterSelect" . $idx . "').val('');\n                  ParentLocationLayer.destroyFeatures();\n                } else if(replace){\n                  ParentLocationLayer.destroyFeatures();\n                  ParentLocationLayer.addFeatures([a1.features[closest]]); // feature should be in map projection\n                  jQuery('#filterSelect" . $idx . "').val(a1.features[closest].attributes['" . $protocol[6] . "']);\n                  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val(a1.features[closest].attributes['" . $protocol[6] . "']);\n";
                                foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                    // just need index, so don't explode
                                    if ($idx1 > $idx && $idx1 < count($filterAttrs) - 1) {
                                        // don't do name
                                        data_entry_helper::$javascript .= "                  filterLoad" . $idx1 . "();\n";
                                    }
                                }
                                data_entry_helper::$javascript .= "\n                }\n              }\n          });\n          var filter = new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.DWITHIN, property: '" . $protocol[3] . "', value: geom, distance: '" . $args['communeLayerBuffer'] . "'});\n" . ($filterAttr[3] != '' ? "          filter = new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,\n               filters:[filter,\n\t\t                new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})]});\n" : '') . "          protocol.read({filter: filter});\n";
                            }
                            data_entry_helper::$javascript .= "        }\n      }\n  });\n  var filter = new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.CONTAINS,property: '" . $protocol[3] . "',value: geom});\n" . ($filterAttr[3] != '' ? "  filter = new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND, filters:[filter, new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})]});\n" : '') . "  protocol.read({filter: filter});\n};\njQuery('#filterSelect" . $idx . "').change(function(){\n  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val(jQuery('#filterSelect" . $idx . "').val());\n  SetFilterNewLocation();\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterReset" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  if(jQuery(this).val()!=''){\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterLoad" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  }\n  displayShape(true);\n});\n";
                            $defaultsFunction .= "  if(keepFilter){\n    jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val(jQuery('#filterSelect" . $idx . "').val());\n  } else {\n    jQuery('#filterSelect" . $idx . "').val('');\n  }\n";
                            $loadFunction .= "  jQuery('#filterSelect" . $idx . "').val(jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val());\ndisplayShape(false);\n";
                            $prevFilterAttr = $filterAttr;
                            $prevAttr = $attr;
                            $prevIdx = $idx;
                            break;
                        case "Name":
                            //special case:
                            $retVal .= '<fieldset><legend>' . lang::get('Existing locations') . '</legend><label>' . $options['FilterNameLabel'] . ':</label> ' . '<select id="' . $options['MainFieldID'] . '" name="' . $options['MainFieldName'] . '" disabled="disabled">' . '<option value="">' . lang::get("None") . '</option>' . (array_key_exists($options['MainFieldName'], data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load[$options['MainFieldName']] != "" ? '<option value="' . data_entry_helper::$entity_to_load[$options['MainFieldName']] . '" selected="selected">' . data_entry_helper::$entity_to_load['location:name'] . '</option>' : '') . '</select><br/></fieldset>';
                            // when a field is changed on the drop down, all following ones are reset.
                            // filterLoad function creates the drop down, based on filters. Assumes all filters are filled in - if not then sets to current value.
                            // the existing locations filter drop down runs the location ID. the site name is the location name.
                            data_entry_helper::$javascript .= "\n// when " . $options['MainFieldID'] . " changes the location will be loaded, including " . $options['MainFieldName'] . "\nfilterLoad" . $idx . " = function(){\n  jQuery('#location-name').data('newValue','');\n  if(jQuery('#" . $options['MainFieldID'] . "').val() != '' && jQuery('#" . $options['MainFieldID'] . "').val() != null)\n    jQuery('#" . $options['MainFieldID'] . "').data('storedValue',jQuery('#" . $options['MainFieldID'] . "').val())\n      .data('storedCaption',jQuery('#" . $options['MainFieldID'] . "').find(':selected')[0].text);\n  else\n    jQuery('#" . $options['MainFieldID'] . "').data('storedValue','').data('storedCaption','ERROR');\n  if(";
                            $condition = '';
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 >= $idx) {
                                    continue;
                                }
                                $filterAttr1 = explode(':', $filterAttr1);
                                foreach ($locationAttributes as $locationAttribute1) {
                                    if ($filterAttr1[0] == "Parent") {
                                        if ($filterAttr1[1] == "true") {
                                            $condition .= ($condition == '' ? '' : ' || ') . "jQuery('#location\\\\:parent_id').val()== ''";
                                        }
                                    } else {
                                        if ($locationAttribute1['untranslatedCaption'] == ($filterAttr1[0] == "Shape" ? $filterAttr1[1] : $filterAttr1[0])) {
                                            $condition .= ($condition == '' ? '' : ' || ') . "jQuery('#locAttr\\\\:" . $locationAttribute1['attributeId'] . "').val()== ''";
                                        }
                                    }
                                }
                            }
                            data_entry_helper::$javascript .= $condition . "){\n\tif(jQuery('#" . $options['MainFieldID'] . "').data('storedValue')==null || jQuery('#" . $options['MainFieldID'] . "').data('storedValue')=='')\n      jQuery('#" . $options['MainFieldID'] . "').empty().attr('disabled','disabled').append('<option value=\"\">" . lang::get("First fill in filter options above") . "</option>');\n    else\n      jQuery('#" . $options['MainFieldID'] . "').empty().append('<option selected=\"selected\" value=\"'+jQuery('#" . $options['MainFieldID'] . "').data('storedValue')+'\">'+jQuery('#" . $options['MainFieldID'] . "').data('storedCaption')+'</option>');\n    return;\n  }\n  parent_id=jQuery('[name=location\\\\:parent_id]');\n  if(parent_id.length!=0) parent_id=parent_id.val();\n  // work out new name value: ignores shape attribute and parent_id. options for drop down\n  for(i=0, newName = 1, results=[]; i<locations.length; i++){\n    match=true;\n    for(j=0; j<location_attrs.length; j++)\n      if(jQuery('#locAttr\\\\:'+location_attrs[j].id).val()!=locations[i].attrs[location_attrs[j].id]) match=false;\n    if(match && parseInt(locations[i].name)>=newName) newName=parseInt(locations[i].name)+1;\n    if(typeof indiciaData.filterParent != 'undefined' && locations[i].parent_id!=parent_id) match=false;\n    if(match) results.push(locations[i]);\n  }\n  jQuery('#location-name').data('newValue',newName);\n  if(jQuery('#location-name').val()=='' && (jQuery('#location-id').val()=='' || jQuery('#location-id').val()==null)) jQuery('#location-name').val(newName);\n  // next work out existing sites list\n  jQuery('#" . $options['MainFieldID'] . "').empty(); // clear list\n  var stored = jQuery('#" . $options['MainFieldID'] . "').data('storedValue');\n  if(results.length>0) {\n    jQuery('#" . $options['MainFieldID'] . "').removeAttr('disabled').append('<option value=\"\">" . lang::get("Please select...") . "</option>');\n    for (var i=0;i<results.length;i++)\n      jQuery('#" . $options['MainFieldID'] . "').append('<option value=\"'+results[i].id+'\">'+results[i].name+'</option>');\n    if(stored!=null && stored!=''){\n      if(jQuery('#" . $options['MainFieldID'] . "').find('option').filter('[value='+stored+']').length>0){\n        jQuery('#" . $options['MainFieldID'] . "').val(stored);\n      } else {\n        jQuery('#" . $options['MainFieldID'] . "').prepend('<option selected=\"selected\" value=\"'+stored+'\">'+jQuery('#" . $options['MainFieldID'] . "').data('storedCaption')+'</option>');\n      }\n    }\n  } else {\n    if(stored!=null && stored!='')\n      jQuery('#" . $options['MainFieldID'] . "').prepend('<option selected=\"selected\" value=\"'+stored+'\">'+jQuery('#" . $options['MainFieldID'] . "').data('storedCaption')+'</option>');\n    else\n      jQuery('#" . $options['MainFieldID'] . "').attr('disabled','disabled').empty().append('<option value=\"\">" . lang::get("None available") . "</option>');\n  }\n  var options=\$('#location-name option');\n  if(options.length>0){\n    options.removeAttr('disabled');\n    options.not(':selected').each(function(idx,elem){\n      if(results.length>0) {\n        for (var i=0;i<results.length;i++){\n          if(results[i].name == elem.value) \$(elem).attr('disabled','disabled');\n        }\n      }});\n  }\n};\nfilterReset" . $idx . " = function(){\n  // filterResets also clear the main field. \n  jQuery('#" . $options['MainFieldID'] . "').empty().attr('disabled','disabled').append('<option value=\"\">" . lang::get("First fill in filter options above") . "</option>');\n  jQuery('#location-name').data('newValue','');\n};";
                            if (array_key_exists('location:id', data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load['location:id'] != "") {
                                $initFunctions .= "\nfilterLoad" . $idx . "(true);";
                            } else {
                                $initFunctions .= "\nfilterReset" . $idx . "();";
                            }
                            // $defaultsFunction .= "  jQuery('#location-name').val(jQuery('#location-name').data('newValue'));\n";
                            $defaultsFunction .= "  filterLoad" . $idx . "(true)\n";
                            $loadFunction .= "  filterLoad" . $idx . "(true);\n";
                            break;
                        default:
                            $attr['class'] = (isset($attr['class']) ? $attr['class'] . " " : "") . "filterFields";
                            $ctrl = data_entry_helper::outputAttribute($attr, array('class' => "filterFields")) . '<span id="filter' . $idx . '"><label class="auto-width">' . lang::get("or pick one previously used") . ':</label> ' . '<select id="filterSelect' . $idx . '" ></select></span>';
                            $retVal .= str_replace('<br/>', '', $ctrl) . '<br />';
                            $attrList[] = array('id' => $attr['attributeId'], 'shape' => false);
                            if (count($filterAttr) > 1) {
                                data_entry_helper::add_resource('json');
                                data_entry_helper::add_resource('autocomplete');
                                data_entry_helper::$javascript .= "\njQuery('#locAttr\\\\:" . $attr['attributeId'] . "').autocomplete('" . data_entry_helper::$base_url . "/index.php/services/data/termlists_term', {\n      extraParams : {\n        view : 'detail',\n        orderby : 'term',\n        mode : 'json',\n        qfield : 'term',\n        auth_token: '" . $auth['read']['auth_token'] . "',\n        nonce: '" . $auth['read']['nonce'] . "',\n        termlist_id: '" . $filterAttr[1] . "'\n      },\n      max: 10000,\n      mustMatch : true,\n      parse: function(data) {\n        var results = [];\n        jQuery.each(data, function(i, item) {\n          results[results.length] = {'data' : item,'result' : item.term,'value' : item.term};\n        });\n        return results;\n      },\n      formatItem: function(item) {return item.term;}\n  });\njQuery('#locAttr\\\\:" . $attr['attributeId'] . "').result(function(data,value){\n  jQuery(this).change();\n});";
                            }
                            data_entry_helper::$javascript .= "\njQuery('#filterSelect" . $idx . "').change(function(){\n  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').data('store',jQuery('#filterSelect" . $idx . "').val()).val(jQuery('#filterSelect" . $idx . "').val());\n  SetFilterNewLocation();\n  if(jQuery(this).val()==''){\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterReset" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  } else {\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterLoad" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  }});\n\njQuery('#locAttr\\\\:" . $attr['attributeId'] . "').data('store',jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val()).change(function(){\n  jQuery(this).data('store',jQuery(this).val());\n  if(jQuery(this).val()=='') {\n    jQuery('#filterSelect" . $idx . "').val('');\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterReset" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "    } else {\n    if(jQuery('#filterSelect" . $idx . "').find('option').filter('[value='+jQuery(this).val()+']').length>0)\n      jQuery('#filterSelect" . $idx . "').val(jQuery(this).val());\n    else\n      jQuery('#filterSelect" . $idx . "').val('');\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterLoad" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  }});\n\n// loads in the drop down list for a filter attribute.\n// Triggered in several places: when the filter above changes value\nfilterLoad" . $idx . " = function(){\n  var match, results, results1;\n  var id=jQuery('#" . $options['MainFieldID'] . "').val();\n  if(checkEditable(id=='',id))\n    jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').removeAttr('disabled');\n  parent_id=jQuery('[name=location\\\\:parent_id]');\n  if(parent_id.length!=0) parent_id=parent_id.val();\n  for(i=0, results=[]; i<locations.length; i++){\n    match=true;\n    if(typeof indiciaData.filterParent != 'undefined' && locations[i].parent_id!=parent_id) match=false;\n    for(j=0; j<location_attrs.length; j++) {\n      if(location_attrs[j].id==" . $attr['attributeId'] . ") break;\n      if(jQuery('#locAttr\\\\:'+location_attrs[j].id).val()!=locations[i].attrs[location_attrs[j].id]) match=false;\n    }\n    if(match) results.push(locations[i].attrs[\"" . $attr['attributeId'] . "\"]);\n  }\n  jQuery('#filterSelect" . $idx . "').empty();\n  if(results.length>0) {\n    results.sort();\n    for(i=1, results1=[results[0]]; i<results.length; i++)\n      if(results[i]!=results[i-1]) results1.push(results[i]);\n    jQuery('#filter" . $idx . "').show();\n    jQuery('#filterSelect" . $idx . "').append('<option value=\"\">" . lang::get("Please select...") . "</option>');\n    for (var i=0;i<results1.length;i++){\n      // for each results, need to work out count of matching locations.\n      for(var k=0, count=0; k<locations.length; k++){\n        match=true;\n        if(typeof indiciaData.filterParent != 'undefined' && locations[k].parent_id!=parent_id) match=false;\n        for(var j=0; j<location_attrs.length; j++) {\n          if(location_attrs[j].id==" . $attr['attributeId'] . ") {\n            if(locations[k].attrs[location_attrs[j].id]!=results1[i]) match=false;\n            break;\n          }\n          if(jQuery('#locAttr\\\\:'+location_attrs[j].id).val()!=locations[k].attrs[location_attrs[j].id]) match=false;\n        }\n        if(match) count++;\n      }\n      jQuery('#filterSelect" . $idx . "').append('<option value=\"'+results1[i]+'\" '+(results1[i] == jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val() ? 'selected=\"selected\"' : '')+'>'+results1[i]+' ('+count+')'+'</option>');\n    }\n  } else\n    jQuery('#filter" . $idx . "').hide();\n};\nfilterReset" . $idx . " = function(){\n  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val('');\n  filterLoad" . $idx . "();\n};";
                            if (array_key_exists('location:id', data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load['location:id'] != "") {
                                $initFunctions .= "\nfilterLoad" . $idx . "();";
                            } else {
                                $initFunctions .= "\nfilterReset" . $idx . "();";
                            }
                            $defaultsFunction .= "  filterLoad" . $idx . "();\n";
                            $loadFunction .= "  filterLoad" . $idx . "();\n";
                            $prevFilterAttr = $filterAttr;
                            $prevAttr = $attr;
                            $prevIdx = $idx;
                            break;
                    }
                }
                $creatorAttr = iform_mnhnl_getAttrID($auth, $args, 'location', 'Creator');
                global $user;
                if ($creatorAttr) {
                    $defaultsFunction .= "  jQuery('#locAttr\\:" . $creatorAttr . "').val('" . $user->name . "');\n";
                }
                $communeAttr = iform_mnhnl_getAttrID($auth, $args, 'location', 'Commune');
                if (!(isset($args['communeLayerLookup']) && $args['communeLayerLookup'] != '') || !$communeAttr) {
                    $includeCommune = false;
                } else {
                    $parts = explode(',', $args['communeLayerLookup']);
                }
                data_entry_helper::$javascript .= "\nSetFilterNewLocation = function(){\n  var id=jQuery('#" . $options['MainFieldID'] . "').val();\n  if(checkEditable(id=='',id)) return;\n  setPermissionsNewSite();\n  clearLocation(true,'maybe');\n};\nhook_set_defaults = function(keepFilter){\n" . $defaultsFunction . "\n};\n" . $loadFunction . "\n};\nhook_setSref = function(geom){ // geom is in map projection.\n  jQuery('#map').ajaxStop(function(event){\n";
                if ($includeCommune) {
                    data_entry_helper::$javascript .= "\n  jQuery('[name=locAttr\\:{$communeAttr}],[name^=locAttr\\:{$communeAttr}\\:]').val('');\n  var communeProtocol = new OpenLayers.Protocol.WFS({\n      url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $parts[0]) . "',\n      featurePrefix: '" . $parts[1] . "',\n      featureType: '" . $parts[2] . "',\n      geometryName:'" . $parts[3] . "',\n      featureNS: '" . $parts[4] . "',\n      srsName: '" . $parts[5] . "',\n      version: '1.1.0',\n      propertyNames: ['" . $parts[6] . "']\n     ,callback: function(a1){\n        if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n          alert(\"" . lang::get('LANG_CommuneLookUpFailed') . "\");\n          return;\n        }\n        if(a1.features.length > 0) {\n          jQuery('[name=locAttr\\:{$communeAttr}],[name^=locAttr\\:{$communeAttr}\\:]').val(a1.features[0].attributes[\"" . $parts[6] . "\"]);\n        } else {\n";
                    if (!isset($args['communeLayerBuffer']) || $args['communeLayerBuffer'] == "") {
                        // No buffer in definition
                        data_entry_helper::$javascript .= "          alert(\"" . lang::get('LANG_PositionOutsideCommune_1') . "\");\n";
                    } else {
                        // buffer set
                        data_entry_helper::$javascript .= "          //  Get list of communes within buffer of geom\n          var protocol = new OpenLayers.Protocol.WFS({\n              url:  '" . $parts[0] . "',featurePrefix: '" . $parts[1] . "',featureType: '" . $parts[2] . "',geometryName:'" . $parts[3] . "',featureNS: '" . $parts[4] . "',srsName: '" . $parts[5] . "',version: '1.1.0',propertyNames: [\"" . $parts[6] . "\"]\n             ,callback: function(a1){\n                var replace = false,\n                    reset = false;\n                if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n                  alert(\"" . lang::get('LANG_CommuneLookUpFailed') . "\");\n                  return;\n                }\n                if(a1.features.length == 0) {\n                  alert(\"" . str_replace('{DISTANCE}', $args['communeLayerBuffer'], lang::get('LANG_PositionOutsideCommune_3')) . "\");\n                } else {\n                  var closest = 0;\n                  if(a1.features.length >= 0) {\n                    for(var i=0; i< a1.features.length; i++){\n                      var distance, thisDistance = geom.distanceTo(a1.features[i].geometry, {});\n                      if(i==0 || thisDistance<distance){\n                        closest=i;\n                        distance=thisDistance;\n                      }\n                    }\n                  }\n                  alert(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_5A") . "\".replace(/SHAPE/g, a1.features[closest].attributes['" . $parts[6] . "']));\n                  jQuery('[name=locAttr\\:{$communeAttr}],[name^=locAttr\\:{$communeAttr}\\:]').val(a1.features[closest].attributes[\"" . $parts[6] . "\"]);\n                }\n              }\n          });\n          var filter = new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.DWITHIN, property: '" . $parts[3] . "', value: geom, distance: '" . $args['communeLayerBuffer'] . "'});\n          protocol.read({filter: filter});\n";
                    }
                    data_entry_helper::$javascript .= "        }\n      }\n  });\n  var filter = new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.CONTAINS,property: '" . $parts[3] . "',value: geom});\n  communeProtocol.read({filter: filter});\n";
                }
                foreach ($filterAttrs as $idx => $filterAttr) {
                    $filterAttr = explode(':', $filterAttr);
                    if ($filterAttr[0] == "Parent" || $filterAttr[0] == "Shape") {
                        data_entry_helper::$javascript .= "    hook_setSref_" . $idx . "(geom);\n";
                    }
                    // map projection
                }
                $locAttrText = array();
                foreach ($attrList as $filterAttr) {
                    $locAttrText[] = "  {'id':'" . $filterAttr['id'] . "', 'shape':" . ($filterAttr['shape'] ? 'true' : 'false') . "}";
                }
                data_entry_helper::$javascript .= "    \$(this).unbind(event);\n  });\n};\nlocation_attrs = [" . implode(",\n", $locAttrText) . "];";
                if ($includeCommune) {
                    data_entry_helper::$javascript .= "jQuery('[name=locAttr\\:{$communeAttr}],[name^=locAttr\\:{$communeAttr}\\:]').attr('readonly','readonly');\n";
                }
                if (isset($args['autoGenSiteName']) && $args['autoGenSiteName']) {
                    $retVal .= "<label for=\"location-name\">" . $options['NameLabel'] . ":</label> <input type='text' id=\"location-name\" name=\"location:name\" " . ($options['AdminMode'] ? "class='required integer' min='1'" : "class='required' readonly='readonly'") . " value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\" /><span class='deh-required'>*</span><br/>";
                } else {
                    if ($args['siteNameTermListID'] == '') {
                        $retVal .= "<label for=\"location-name\">" . $options['NameLabel'] . ":</label> <input type='text' id=\"location-name\" name=\"location:name\" class='wide required' value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\" /><span class='deh-required'>*</span><br/>";
                    } else {
                        $retVal .= data_entry_helper::select(array('label' => $options['NameLabel'], 'id' => 'location-name', 'fieldname' => 'location:name', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'term', 'blankText' => '', 'validation' => array('required'), 'extraParams' => $auth['read'] + array('termlist_id' => $args['siteNameTermListID'], 'orderby' => 'id')));
                    }
                }
                data_entry_helper::$javascript .= $initFunctions;
                $retVal .= "<input type='hidden' id=\"sample-location-id\" name=\"sample:location_id\" value='" . data_entry_helper::$entity_to_load['sample:location_id'] . "' />";
            }
        }
    }
    if (isset($args['includeLocationCode']) && $args['includeLocationCode']) {
        $retVal .= "<label for=\"location-code\">" . $options['CodeLabel'] . ":</label> <input id=\"location-code\" class=\"integer\" min=1 name=\"location:code\" value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:code']) . "\" dbCode=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:code']) . "\"><br />";
    }
    // Move any Attribute fields side by side.
    if (isset($args['removeBreakLocAttrIDs']) && $args['removeBreakLocAttrIDs'] != "") {
        $removeBreakLocAttrIDs = explode(':', $args['removeBreakLocAttrIDs']);
        foreach ($removeBreakLocAttrIDs as $removeBreakLocAttrID) {
            data_entry_helper::$javascript .= "\njQuery('[name=locAttr\\:" . $removeBreakLocAttrID . "],[name^=locAttr\\:" . $removeBreakLocAttrID . "\\:]').css('margin-right', '20px').nextAll('br').eq(0).remove();";
        }
    }
    return $retVal;
}
Exemplo n.º 16
0
 /**
  * Returns a control for picking one of the allowed record inclusion methods methods. If there is only one allowed, 
  * then this is output as a single hidden input.
  * @param array $args Form configuration arguments
  * @return string HTML to output
  */
 private static function inclusionMethodControl($args)
 {
     if ($args['data_inclusion_mode'] !== 'choose') {
         $implicit = $args['data_inclusion_mode'] === 'implicit' ? 't' : 'f';
         $r = data_entry_helper::hidden_text(array('fieldname' => 'group:implicit_record_inclusion', 'default' => $implicit));
     } else {
         $r = '<fieldset><legend>' . lang::get('How to post records for the {1}', self::$groupType) . '</legend>';
         $r .= '<p>' . lang::get('LANG_Record_Inclusion_Instruct_1', self::$groupType, lang::get("group's")) . ' ';
         if ($args['include_sensitivity_controls']) {
             $r .= lang::get('LANG_Record_Inclusion_Instruct_Sensitive') . ' ';
         }
         $r .= lang::get('LANG_Record_Inclusion_Instruct_1', self::$groupType, ucfirst(self::$groupType)) . '</p>';
         $r .= data_entry_helper::select(array('fieldname' => 'group:implicit_record_inclusion', 'label' => lang::get('Records are included in the {1} if', self::$groupType), 'lookupValues' => array('t' => lang::get('they match the filter defined above'), 'f' => lang::get('they were recorded on a group data entry form'))));
         $r . ' </fieldset>';
     }
     return $r;
 }
Exemplo n.º 17
0
 /**
  * Internal function to prepare the list of occurrence attribute columns for a species_checklist control.
  */
 private static function species_checklist_prepare_attributes($options, $attributes, &$occAttrControls, &$occAttrs)
 {
     $idx = 0;
     if (array_key_exists('occAttrs', $options)) {
         $attrs = $options['occAttrs'];
     } else {
         // There is no specified list of occurrence attributes, so use all available for the survey
         $attrs = array_keys($attributes);
     }
     foreach ($attrs as $occAttrId) {
         // test that this occurrence attribute is linked to the survey
         if (!isset($attributes[$occAttrId])) {
             throw new Exception('The occurrence attributes requested for the grid are not linked with the survey.');
         }
         $attrDef = $attributes[$occAttrId];
         $occAttrs[$occAttrId] = $attrDef['caption'];
         // Get the control class if available. If the class array is too short, the last entry gets reused for all remaining.
         $class = array_key_exists('occAttrClasses', $options) && $idx < count($options['occAttrClasses']) ? $options['occAttrClasses'][$idx] : strtolower(str_replace(' ', '_', $attrDef['caption']));
         // provide a default class based on the control caption
         // Build the correct control
         switch ($attrDef['data_type']) {
             case 'L':
                 $tlId = $attrDef['termlist_id'];
                 $occAttrControls[$occAttrId] = data_entry_helper::select(array('fieldname' => '{fieldname}', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $options['readAuth'] + array('termlist_id' => $tlId), 'class' => $class, 'blankText' => ''));
                 break;
             case 'D':
             case 'V':
                 // Date-picker control
                 $occAttrControls[$occAttrId] = '<input type="text" class="date $class" ' . 'id="{fieldname}" name="{fieldname}" ' . "value=\"" . lang::get('click here') . "\"/>";
                 break;
             default:
                 $occAttrControls[$occAttrId] = "<input type=\"text\" id=\"{fieldname}\" name=\"{fieldname}\" class=\"{$class}\" value=\"\" />";
                 break;
         }
         $idx++;
     }
 }
Exemplo n.º 18
0
<legend>Milestone details</legend>
<?php 
data_entry_helper::link_default_stylesheet();
if (isset($values['milestone:id'])) {
    ?>
  <input type="hidden" name="milestone:id" value="<?php 
    echo html::initial_value($values, 'milestone:id');
    ?>
" />
<?php 
    echo $metadata;
}
echo data_entry_helper::hidden_text(array('fieldname' => 'milestone:id', 'default' => html::initial_value($values, 'milestone:id')));
echo data_entry_helper::hidden_text(array('fieldname' => 'website_id', 'default' => html::initial_value($values, 'milestone:website_id')));
echo data_entry_helper::text_input(array('label' => 'Title', 'fieldname' => 'milestone:title', 'class' => 'control-width-4', 'default' => html::initial_value($values, 'milestone:title')));
echo data_entry_helper::select(array('label' => 'Count what?', 'fieldname' => 'milestone:entity', 'lookupValues' => array('T' => 'Species or taxa', 'O' => 'Records', 'M' => 'Media/photos'), 'default' => html::initial_value($values, 'milestone:entity'), 'helpText' => 'Are you targetting a total count of species, records or media/photos for this milestone?'));
echo data_entry_helper::text_input(array('label' => 'Count', 'fieldname' => 'milestone:count', 'class' => 'control-width-2', 'default' => html::initial_value($values, 'milestone:count'), 'helpText' => 'What is the target number that must be reached to hit the milestone?'));
echo data_entry_helper::text_input(array('label' => 'Group ID', 'fieldname' => 'milestone:group_id', 'class' => 'control-width-2', 'default' => html::initial_value($values, 'milestone:group_id'), 'helpText' => 'Optional ID of the recording group associated with the milestone, only users that are members of this group will receive the milestone award.'));
echo data_entry_helper::textarea(array('label' => 'Success message', 'fieldname' => 'milestone:success_message', 'class' => 'control-width-6', 'default' => html::initial_value($values, 'milestone:success_message'), 'helpText' => 'This message will be sent to the user on reaching the milestone as a notification.'));
echo data_entry_helper::text_input(array('label' => 'Awarded by', 'fieldname' => 'milestone:awarded_by', 'class' => 'control-width-6', 'default' => html::initial_value($values, 'milestone:awarded_by'), 'helpText' => 'Which organisation is awarding the milestone? This will appear in the from field for the notification sent to the recorder.'));
//The filter title is actually generated using the milestone title we enter. There are issues with using the built-in validator to detect duplicate titles because the filter supermodel is validated
//first. The filter requires a unique title/sharing/created_by_id option that isn't included in the model, the issue is only
//detected once the system tries to add the filter to the database, this will fail with a general error without even getting as far as doing the milestone model's
//title duplciate detection.
//So to fix this, collect the existing filters from the database so we can compare the titles with the one we create and then
//do the validation manually.
$readAuth = data_entry_helper::get_read_auth(0 - $_SESSION['auth_user']->id, kohana::config('indicia.private_key'));
$existingFilterData = data_entry_helper::get_population_data(array('table' => 'filter', 'extraParams' => $readAuth, 'nocache' => true));
//When we save a milestone when we need to automatically set the filter title as there isn't a separate field
//to fill this in.
//Also hide the "who" filter as we don't need this for milestones as they can apply to all users
 private static function get_control_identifier($auth, $args, $tabalias, $options)
 {
     $fieldPrefix = !empty($options['fieldprefix']) ? $options['fieldprefix'] : '';
     $r = '';
     $r .= '<h3 id="' . $fieldPrefix . 'header" class="idn:accordion:header"><a href="#">' . $options['identifierName'] . '</a></h2>';
     $r .= '<div id="' . $fieldPrefix . 'panel" class="idn:accordion:panel">';
     $r .= '<input type="hidden" name="' . $fieldPrefix . 'identifier:identifier_type_id" value="' . $options['identifierTypeId'] . '" />' . "\n";
     $r .= '<input type="hidden" name="' . $fieldPrefix . 'identifier:coded_value" id="' . $fieldPrefix . 'identifier:coded_value" class="identifier_coded_value" value="" />' . "\n";
     $val = isset(data_entry_helper::$entity_to_load[$fieldPrefix . 'identifier:id']) ? data_entry_helper::$entity_to_load[$fieldPrefix . 'identifier:id'] : '0';
     $r .= '<input type="hidden" name="' . $fieldPrefix . 'identifier:id" id="' . $fieldPrefix . 'identifier:id" class="identifier_id" value="' . $val . '" />' . "\n";
     if (isset(data_entry_helper::$entity_to_load[$fieldPrefix . 'identifiers_subject_observation:id'])) {
         $r .= '<input type="hidden" id="' . $fieldPrefix . 'identifiers_subject_observation:id" name="' . $fieldPrefix . 'identifiers_subject_observation:id" ' . 'value="' . data_entry_helper::$entity_to_load[$fieldPrefix . 'identifiers_subject_observation:id'] . '" />' . "\n";
     }
     // checkbox - (now hidden by CSS, probably should refactor to hidden input?)
     $r .= data_entry_helper::checkbox(array_merge(array('label' => '', 'fieldname' => $fieldPrefix . 'identifier:checkbox', 'class' => 'identifier_checkbox identifierRequired noDuplicateIdentifiers'), $options));
     // loop through the requested attributes and output an appropriate control
     $classes = $options['class'];
     foreach ($options['attrList'] as $attribute) {
         // find the definition of this attribute
         $found = false;
         if ($attribute['attrType'] === 'idn') {
             foreach ($options['idnAttributeTypes'] as $attrType) {
                 if ($attrType['id'] === $attribute['typeId']) {
                     $found = true;
                     break;
                 }
             }
         } else {
             if ($attribute['attrType'] === 'iso') {
                 foreach ($options['isoAttributeTypes'] as $attrType) {
                     if ($attrType['id'] === $attribute['typeId']) {
                         $found = true;
                         break;
                     }
                 }
             }
         }
         if (!$found) {
             throw new exception(lang::get('Unknown ' . $attribute['attrType'] . ' attribute type id [' . $attribute['typeId'] . '] specified for ' . $options['identifierName'] . ' in Identifier Attributes array.'));
         }
         // setup any locking
         if (!empty($attribute['lockable']) && $attribute['lockable'] === true) {
             $options['lockable'] = $options['identifiers_lockable'];
         }
         // setup any data filters
         if ($attribute['attrType'] === 'idn' && $options['baseColourId'] == $attribute['typeId']) {
             if (!empty($args['base_colours'])) {
                 // filter the colours available
                 $query = array('in' => array('id', $args['base_colours']));
             }
             $attr_name = 'base-colour';
         } elseif ($attribute['attrType'] === 'idn' && $options['textColourId'] == $attribute['typeId']) {
             if (!empty($args['text_colours'])) {
                 // filter the colours available
                 $query = array('in' => array('id', $args['text_colours']));
             }
             $attr_name = 'text-colour';
         } elseif ($attribute['attrType'] === 'idn' && $options['positionId'] == $attribute['typeId']) {
             $attr_name = 'position';
             if (count($args['position']) > 0) {
                 // filter the identifier position available
                 $query = array('in' => array('id', $args['position']));
             }
         } elseif ($attribute['attrType'] === 'idn' && $options['sequenceId'] == $attribute['typeId']) {
             $attr_name = 'sequence';
             $options['maxlength'] = $options['seq_maxlength'] ? $options['seq_maxlength'] : '';
             if ($options['seq_format_class']) {
                 $options['class'] = empty($options['class']) ? $options['seq_format_class'] : (strstr($options['class'], $options['seq_format_class']) ? $options['class'] : $options['class'] . ' ' . $options['seq_format_class']);
             }
         } elseif ($attribute['attrType'] === 'iso' && $options['conditionsId'] == $attribute['typeId']) {
             // filter the identifier conditions available
             if ($options['identifierTypeId'] == $args['neck_collar_type'] && !empty($args['neck_collar_conditions'])) {
                 $query = array('in' => array('id', $args['neck_collar_conditions']));
             } elseif ($options['identifierTypeId'] == $args['enscribed_colour_ring_type'] && !empty($args['coloured_ring_conditions'])) {
                 $query = array('in' => array('id', $args['coloured_ring_conditions']));
             } elseif ($options['identifierTypeId'] == $args['metal_ring_type'] && !empty($args['metal_ring_conditions'])) {
                 $query = array('in' => array('id', $args['metal_ring_conditions']));
             }
             $attr_name = 'conditions';
         }
         // add classes as identifiers
         $options['class'] = empty($options['class']) ? $options['classprefix'] . $attr_name : (strstr($options['class'], $options['classprefix'] . $attr_name) ? $options['class'] : $options['class'] . ' ' . $options['classprefix'] . $attr_name);
         $options['class'] = $options['class'] . ' idn-' . $attr_name;
         if ($attribute['attrType'] === 'idn' && ($options['baseColourId'] == $attribute['typeId'] || $options['textColourId'] == $attribute['typeId'])) {
             $options['class'] = strstr($options['class'], 'select_colour') ? $options['class'] : $options['class'] . ' select_colour';
             $options['class'] = strstr($options['class'], 'textAndBaseMustDiffer') ? $options['class'] : $options['class'] . ' textAndBaseMustDiffer';
         }
         if ($attribute['attrType'] === 'idn' && $options['sequenceId'] == $attribute['typeId']) {
             $options['class'] = strstr($options['class'], 'identifier_sequence') ? $options['class'] : $options['class'] . ' identifier_sequence';
         }
         if (!empty($attribute['hidden']) && $attribute['hidden'] === true) {
             $dataType = 'H';
             // hidden
             if (!empty($attribute['hiddenValue'])) {
                 $dataDefault = $attribute['hiddenValue'];
             } else {
                 $dataDefault = '';
             }
         } else {
             $dataType = $attrType['data_type'];
         }
         // output an appropriate control for the attribute data type
         switch ($dataType) {
             case 'D':
             case 'V':
                 $r .= data_entry_helper::date_picker(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id']), $options));
                 break;
             case 'L':
                 $filter = array('termlist_id' => $attrType['termlist_id']);
                 if (!empty($query)) {
                     $filter += array('query' => json_encode($query));
                 }
                 $extraParams = array_merge($filter, $auth['read']);
                 if ($attribute['attrType'] === 'iso' && $options['conditionsId'] == $attribute['typeId']) {
                     $fieldname = $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id'];
                     $default = array();
                     // if this attribute exists on DB, we need to write a hidden with id appended to fieldname and set defaults for checkboxes
                     if (is_array(data_entry_helper::$entity_to_load)) {
                         $stored_keys = preg_grep('/^' . $fieldname . ':[0-9]+$/', array_keys(data_entry_helper::$entity_to_load));
                         foreach ($stored_keys as $stored_key) {
                             $r .= '<input type="hidden" name="' . $stored_key . '" value="" />';
                             $default[] = array('fieldname' => $stored_key, 'default' => data_entry_helper::$entity_to_load[$stored_key]);
                             unset(data_entry_helper::$entity_to_load[$stored_key]);
                         }
                     }
                     $r .= data_entry_helper::checkbox_group(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldname, 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'default' => $default, 'extraParams' => $extraParams), $options));
                 } else {
                     $r .= data_entry_helper::select(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id'], 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'blankText' => '<Please select>', 'extraParams' => $extraParams), $options));
                 }
                 break;
             case 'B':
                 $r .= data_entry_helper::checkbox(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id']), $options));
                 break;
             case 'H':
                 // Any multi-value attributes shown as hidden will be single-valued
                 // so transform the array to a scalar
                 $fieldname = $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id'];
                 if (!empty(data_entry_helper::$entity_to_load[$fieldname]) && is_array(data_entry_helper::$entity_to_load[$fieldname])) {
                     data_entry_helper::$entity_to_load[$fieldname] = data_entry_helper::$entity_to_load[$fieldname][0];
                 }
                 $r .= data_entry_helper::hidden_text(array_merge(array('fieldname' => $fieldname, 'default' => $dataDefault), $options));
                 break;
             default:
                 $r .= data_entry_helper::text_input(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id']), $options));
         }
         $options['class'] = $classes;
         if (isset($options['maxlength'])) {
             unset($options['maxlength']);
         }
         if (isset($options['lockable'])) {
             unset($options['lockable']);
         }
     }
     $r .= '</div>';
     return $r;
 }
 /**
  * Returns a control for picking a single species
  * @global type $indicia_templates
  * @param array $auth Read authorisation tokens
  * @param array $args Form configuration
  * @param array $extraParams Extra parameters pre-configured with taxon and taxon name type filters.
  * @param array $options additional options for the control, e.g. those configured in the form structure.
  * @return string HTML for the control.
  */
 protected static function get_control_species_single($auth, $args, $extraParams, $options)
 {
     $r = '';
     if ($args['extra_list_id'] === '' && $args['list_id'] !== '') {
         $extraParams['taxon_list_id'] = $args['list_id'];
     } elseif ($args['extra_list_id'] !== '' && $args['list_id'] === '') {
         $extraParams['taxon_list_id'] = $args['extra_list_id'];
     } elseif ($args['extra_list_id'] !== '' && $args['list_id'] !== '') {
         $extraParams['query'] = json_encode(array('in' => array('taxon_list_id' => array($args['list_id'], $args['extra_list_id']))));
     }
     if (isset($options['taxonGroupSelect']) && $options['taxonGroupSelect']) {
         $label = isset($options['taxonGroupSelectLabel']) ? $options['taxonGroupSelectLabel'] : 'Species Group';
         $helpText = isset($options['taxonGroupSelectHelpText']) ? $options['taxonGroupSelectHelpText'] : 'Choose which species group you want to pick a species from.';
         $default = '';
         if (!empty(data_entry_helper::$entity_to_load['occurrence:taxa_taxon_list_id'])) {
             // need to find the default value
             $species = data_entry_helper::get_population_data(array('table' => 'cache_taxa_taxon_list', 'extraParams' => $auth['read'] + array('id' => data_entry_helper::$entity_to_load['occurrence:taxa_taxon_list_id'])));
             data_entry_helper::$entity_to_load['taxon_group_id'] = $species[0]['taxon_group_id'];
         }
         $r .= data_entry_helper::select(array('fieldname' => 'taxon_group_id', 'id' => 'taxon_group_id', 'label' => lang::get($label), 'helpText' => lang::get($helpText), 'report' => 'library/taxon_groups/taxon_groups_used_in_checklist', 'valueField' => 'id', 'captionField' => 'title', 'extraParams' => $auth['read'] + array('taxon_list_id' => $extraParams['taxon_list_id'])));
         // update the select box to link to the species group picker. It must be a select box!
         $args['species_ctrl'] = 'select';
         $options['parentControlId'] = 'taxon_group_id';
         $options['parentControlLabel'] = lang::get($label);
         $options['filterField'] = 'taxon_group_id';
     }
     $options['speciesNameFilterMode'] = self::getSpeciesNameFilterMode($args);
     global $indicia_templates;
     $ctrl = $args['species_ctrl'] === 'autocomplete' ? 'species_autocomplete' : $args['species_ctrl'];
     $species_ctrl_opts = array_merge(array('fieldname' => 'occurrence:taxa_taxon_list_id', 'label' => lang::get('occurrence:taxa_taxon_list_id'), 'columns' => 2, 'parentField' => 'parent_id', 'blankText' => lang::get('Please select'), 'cacheLookup' => $args['cache_lookup']), $options);
     if (isset($species_ctrl_opts['extraParams'])) {
         $species_ctrl_opts['extraParams'] = array_merge($extraParams, $species_ctrl_opts['extraParams']);
     } else {
         $species_ctrl_opts['extraParams'] = $extraParams;
     }
     if (!empty($args['taxon_filter'])) {
         $species_ctrl_opts['taxonFilterField'] = $args['taxon_filter_field'];
         // applies to autocompletes
         $species_ctrl_opts['taxonFilter'] = helper_base::explode_lines($args['taxon_filter']);
         // applies to autocompletes
     }
     // obtain table to query and hence fields to use
     $db = data_entry_helper::get_species_lookup_db_definition($args['cache_lookup']);
     // get local vars for the array
     extract($db);
     if ($ctrl !== 'species_autocomplete') {
         // The species autocomplete has built in support for the species name filter.
         // For other controls we need to apply the species name filter to the params used for population
         if (!empty($species_ctrl_opts['taxonFilter']) || $options['speciesNameFilterMode']) {
             $species_ctrl_opts['extraParams'] = array_merge($species_ctrl_opts['extraParams'], data_entry_helper::get_species_names_filter($species_ctrl_opts));
         }
         // for controls which don't know how to do the lookup, we need to tell them
         $species_ctrl_opts = array_merge(array('table' => $tblTaxon, 'captionField' => $colTaxon, 'valueField' => $colId), $species_ctrl_opts);
     }
     // if using something other than an autocomplete, then set the caption template to include the appropriate names. Autocompletes
     // use a JS function instead.
     if ($ctrl !== 'autocomplete' && isset($args['species_include_both_names']) && $args['species_include_both_names']) {
         if ($args['species_names_filter'] === 'all') {
             $indicia_templates['species_caption'] = "{{$colTaxon}}";
         } elseif ($args['species_names_filter'] === 'language') {
             $indicia_templates['species_caption'] = "{{$colTaxon}} - {{$colPreferred}}";
         } else {
             $indicia_templates['species_caption'] = "{{$colTaxon}} - {{$colCommon}}";
         }
         $species_ctrl_opts['captionTemplate'] = 'species_caption';
     }
     if ($ctrl == 'tree_browser') {
         // change the node template to include images
         $indicia_templates['tree_browser_node'] = '<div>' . '<img src="' . data_entry_helper::$base_url . '/upload/thumb-{image_path}" alt="Image of {caption}" width="80" /></div>' . '<span>{caption}</span>';
     }
     // Dynamically generate the species selection control required.
     $r .= call_user_func(array('data_entry_helper', $ctrl), $species_ctrl_opts);
     return $r;
 }
 protected static function get_branch_assignment_control($readAuth, $branchCmsUserAttr, $args, $settings)
 {
     if (!$branchCmsUserAttr) {
         return '<span style="display:none;">No branch location attribute</span>';
     }
     // no attribute so don't display
     if (self::$cmsUserList == null) {
         $query = db_query("select uid, name from {users} where name <> '' order by name");
         $users = array();
         // there have been DB API changes for Drupal7: db_query now returns the result array.
         if (version_compare(VERSION, '7', '<')) {
             while ($user = db_fetch_object($query)) {
                 $users[$user->uid] = $user->name;
             }
         } else {
             foreach ($query as $user) {
                 $users[$user->uid] = $user->name;
             }
         }
         self::$cmsUserList = $users;
     } else {
         $users = self::$cmsUserList;
     }
     // next reduce the list to branch users
     if ($settings['canAllocBranch']) {
         // only check the users permissions if can change value - for performance reasons.
         $new_users = array();
         foreach ($users as $uid => $name) {
             $account = user_load($uid);
             if (user_access($args['branch_assignment_permission'], $account)) {
                 $new_users[$uid] = $name;
             }
         }
         $users = $new_users;
     }
     $r = '<fieldset id="alloc-branch"><legend>' . lang::get('Site Branch Allocation') . '</legend>';
     if ($settings['canAllocBranch']) {
         $r .= data_entry_helper::select(array('label' => lang::get('Select Branch Manager'), 'fieldname' => 'branchCmsUserId', 'lookupValues' => $users, 'afterControl' => '<button id="add-branch-coord" type="button">' . lang::get('Add') . '</button>'));
         // tell the javascript which attr to save the user ID into
         data_entry_helper::$javascript .= "indiciaData.locBranchCmsUsrAttr = " . self::$branchCmsUserAttrId . ";\n";
     }
     $r .= '<table id="branch-coord-list" style="width: auto">';
     $rows = '';
     // cmsUserAttr needs to be multivalue
     if (isset($branchCmsUserAttr['default']) && !empty($branchCmsUserAttr['default'])) {
         foreach ($branchCmsUserAttr['default'] as $value) {
             if ($settings['canAllocBranch']) {
                 $rows .= '<tr><td id="branch-coord-' . $value['default'] . '"><input type="hidden" name="' . $value['fieldname'] . '" ' . 'value="' . $value['default'] . '"/>' . $users[$value['default']] . '</td><td><div class="ui-state-default ui-corner-all"><span class="remove-user ui-icon ui-icon-circle-close"></span></div></td></tr>';
             } else {
                 $rows .= '<tr><td>' . $users[$value['default']] . '</td><td></td></tr>';
             }
         }
     }
     if (empty($rows)) {
         $rows = '<tr><td colspan="2"></td></tr>';
     }
     $r .= "{$rows}</table>\n";
     $r .= '</fieldset>';
     return $r;
 }
Exemplo n.º 22
0
    /**
     * Return the generated form output.
     * @return Form HTML.
     */
    public static function get_form($args, $node)
    {
        global $user;
        // There is a language entry in the args parameter list: this is derived from the $language DRUPAL global.
        // It holds the 2 letter code, used to pick the language file from the lang subdirectory of prebuilt_forms.
        // There should be no explicitly output text in this file.
        // We must translate any field names and ensure that the termlists and taxonlists use the correct language.
        // For attributes, the caption is automatically translated by data_entry_helper.
        $logged_in = $user->uid > 0;
        $uid = $user->uid;
        $email = $user->mail;
        $username = $user->name;
        if (!user_access('IForm n' . $node->nid . ' access')) {
            return "<p>" . lang::get('LANG_Insufficient_Privileges') . "</p>";
        }
        $r = '';
        // Get authorisation tokens to update and read from the Warehouse.
        $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
        $svcUrl = data_entry_helper::$base_url . '/index.php/services';
        drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module');
        data_entry_helper::link_default_stylesheet();
        data_entry_helper::add_resource('jquery_ui');
        data_entry_helper::add_resource('autocomplete');
        if ($args['language'] != 'en') {
            data_entry_helper::add_resource('jquery_ui_' . $args['language']);
        }
        data_entry_helper::enable_validation('cc-1-collection-details');
        // don't care about ID itself, just want resources
        if ($args['help_module'] != '' && $args['help_inclusion_function'] != '' && module_exists($args['help_module']) && function_exists($args['help_inclusion_function'])) {
            $use_help = true;
            data_entry_helper::$javascript .= call_user_func($args['help_inclusion_function']);
        } else {
            $use_help = false;
        }
        // The only things that will be editable after the collection is saved will be the identifiaction of the flower/insects.
        // no id - just getting the attributes, rest will be filled in using AJAX
        $sample_attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $occurrence_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $location_attributes = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $taxon_attributes = data_entry_helper::getAttributes(array('valuetable' => 'taxa_taxon_list_attribute_value', 'attrtable' => 'taxa_taxon_list_attribute', 'key' => 'taxa_taxon_list_id', 'fieldprefix' => 'taxAttr', 'extraParams' => $readAuth), false);
        if (count($taxon_attributes) != 1 || $taxon_attributes[0][caption] != "XPER ID") {
            return "<p>Internal error: Expected 1 taxon attribute (XPER ID), got " . count($taxon_attributes) . "</p>Dump:<br/>" . print_r($taxon_attributes, true);
        }
        $defNRAttrOptions = array('extraParams' => $readAuth + array('orderby' => 'id'), 'lookUpListCtrl' => 'radio_group', 'lookUpKey' => 'meaning_id', 'language' => iform_lang_iso_639_2($args['language']), 'booleanCtrl' => 'radio', 'containerClass' => 'group-control-box', 'sep' => ' &nbsp; ');
        $defAttrOptions = $defNRAttrOptions;
        $defAttrOptions['validation'] = array('required');
        $checkOptions = $defNRAttrOptions;
        $checkOptions['lookUpListCtrl'] = 'checkbox_group';
        $language = iform_lang_iso_639_2($args['language']);
        global $indicia_templates;
        $indicia_templates['sref_textbox_latlong'] = '<div class="latLongDiv"><label for="{idLat}">{labelLat}:</label>' . '<input type="text" id="{idLat}" name="{fieldnameLat}" {class} {disabled} value="{default}" /></div>' . '<div class="latLongDiv"><label for="{idLong}">{labelLong}:</label>' . '<input type="text" id="{idLong}" name="{fieldnameLong}" {class} {disabled} value="{default}" /></div>';
        $base = base_path();
        if (substr($base, -1) != '/') {
            $base .= '/';
        }
        $r .= '<script type="text/javascript">
/* <![CDATA[ */
document.write("<div class=\\"ui-widget ui-widget-content ui-corner-all loading-panel\\" ><img src=\\"' . $base . drupal_get_path('module', 'iform') . '/media/images/ajax-loader2.gif\\" />' . lang::get('loading') . '...<span class=\\"poll-loading-extras\\">0</span></div>");
document.write("<div class=\\"poll-loading-hide\\" style=\\"display:none;\\">");
/* ]]> */</script>
';
        data_entry_helper::$javascript .= "var flowerTaxa = [";
        $extraParams = $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'view' => 'list');
        $species_data_def = array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams);
        $taxa = data_entry_helper::get_population_data($species_data_def);
        $first = true;
        // Flowers do not have XPER ID. Flowers list still required to do multiple selection list conversion.
        foreach ($taxa as $taxon) {
            data_entry_helper::$javascript .= ($first ? '' : ',') . "{id: " . $taxon['id'] . ", taxon: \"" . str_replace('"', '\\"', $taxon['taxon']) . "\"}\n";
            $first = false;
        }
        data_entry_helper::$javascript .= "];\nvar insectTaxa = [";
        $extraParams = $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'view' => 'list');
        $taxa_attribute_values_data_def = array('table' => 'taxa_taxon_list_attribute_value', 'extraParams' => $extraParams);
        $taxa_attribute_values = data_entry_helper::get_population_data($taxa_attribute_values_data_def);
        // full list : no allow_data_entry filter.
        $extraParams['taxon_list_id'] = $args['insect_list_id'];
        $species_data_def['extraParams'] = $extraParams;
        $taxa = data_entry_helper::get_population_data($species_data_def);
        $first = true;
        foreach ($taxa as $taxon) {
            // TODO this is not the most performance orientated, but it works.
            $xperID = "NoXPERID";
            foreach ($taxa_attribute_values as $xperRecord) {
                if ($xperRecord["id"] != NULL && $xperRecord['taxa_taxon_list_id'] == $taxon['id']) {
                    $xperID = $xperRecord['value'];
                    break;
                }
            }
            data_entry_helper::$javascript .= ($first ? '' : ',') . '{id: ' . $taxon['id'] . ', taxon: "' . str_replace('"', '\\"', $taxon['taxon']) . '", xperID: "' . $xperID . '"}' . "\n";
            $first = false;
        }
        data_entry_helper::$javascript .= "];";
        // note we have to proxy the post. Every time a write transaction is carried out, the write nonce is trashed.
        // For security reasons we don't want to give the user the ability to generate their own nonce, so we use
        // the fact that the user is logged in to drupal as the main authentication/authorisation/identification
        // process for the user. The proxy packages the post into the correct format
        //
        // There are 2 types of submission:
        // When a user validates a panel using the validate button, the following panel is opened on success
        // When a user presses a modify button, the open panel gets validated, and the panel to be modified is opened.
        // loadAttribute
        // <form id="cc-1-collection-details"
        // has the main sample (+attributes), location (no attributes).
        // form id="cc-1-delete-collection" just has the main sample.
        // form id="cc-2-flower-upload" just uploads the flower picture: no DB
        // form id="cc-2-environment-upload" just uploads the location picture: no DB
        // form id="cc-2-floral-station"
        // has the location (+attributes), location_image, main sample (no attributes), flower occurrence (+attributes), determination, flower_image
        // form id="cc-3-delete-session" just has the session sample.
        // form class=\"poll-session-form\" has the session (+attributes)
        // form id="cc-4-insect-upload" just uploads the insect picture: no DB
        // form id="cc-4-main-form"
        // has the insect occurrence (+attributes), determination, insect image
        // form id="cc-4-delete-insect" just has the insect occurrence.
        // form id="cc-5-collection" has the main sample and closed attribute (forced to 1).
        $r .= '
<div id="refresh-message" style="display:none" ><p>' . lang::get('LANG_Please_Refresh_Page') . '</p></div>
<div id="cc-1" class="poll-section">
  <div id="cc-1-title" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top poll-section-title">
  	<span id="cc-1-title-details">' . lang::get('LANG_Collection_Details') . '</span>
    <div class="right">
      <div>
        <span id="cc-1-reinit-button" class="ui-state-default ui-corner-all reinit-button">' . lang::get('LANG_Reinitialise') . '</span>
        <span id="cc-1-mod-button" class="ui-state-default ui-corner-all mod-button">' . lang::get('LANG_Modify') . '</span>
      </div>
    </div>
  </div>
  <div id="cc-1-details" class="ui-accordion-content ui-helper-reset ui-widget-content">
    <span id="cc-1-protocol-details"></span>
  </div>
  <div id="cc-1-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active poll-section-body">
   <form id="cc-1-collection-details" action="' . iform_ajaxproxy_url($node, 'loc-sample') . '" method="POST">
    <input type="hidden" id="website_id"       name="website_id" value="' . $args['website_id'] . '" />
    <input type="hidden" id="imp-sref"         name="location:centroid_sref"  value="" />
    <input type="hidden" id="imp-geom"         name="location:centroid_geom" value="" />
    <input type="hidden" id="X-sref-system"  name="location:centroid_sref_system" value="900913" />
    <input type="hidden" id="sample:survey_id" name="sample:survey_id" value="' . $args['survey_id'] . '" />
    ' . iform_pollenators::help_button($use_help, "collection-help-button", $args['help_function'], $args['help_collection_arg']) . '
    <label for="location:name">' . lang::get('LANG_Collection_Name_Label') . ':</label>
 	<input type="text" id="location:name"      name="location:name" value="" class="required"/>
    <input type="hidden" id="sample:location_name" name="sample:location_name" value=""/>
 	' . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['protocol_attr_id']], $defNRAttrOptions)) . '    <input type="hidden"                       name="sample:date" value="2010-01-01"/>
    <input type="hidden" id="smpAttr:' . $args['complete_attr_id'] . '" name="smpAttr:' . $args['complete_attr_id'] . '" value="0" />
    <input type="hidden" id="smpAttr:' . $args['uid_attr_id'] . '" name="smpAttr:' . $args['uid_attr_id'] . '" value="' . $uid . '" />
    <input type="hidden" id="smpAttr:' . $args['email_attr_id'] . '" name="smpAttr:' . $args['email_attr_id'] . '" value="' . $email . '" />
    <input type="hidden" id="smpAttr:' . $args['username_attr_id'] . '" name="smpAttr:' . $args['username_attr_id'] . '" value="' . $username . '" />  
    <input type="hidden" id="locations_website:website_id" name="locations_website:website_id" value="' . $args['website_id'] . '" />
    <input type="hidden" id="location:id"      name="location:id" value="" disabled="disabled" />
    <input type="hidden" id="sample:id"        name="sample:id" value="" disabled="disabled" />
    </form>
    <div class="button-container">
      <div id="cc-1-valid-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate') . '</div>
    </div>
  </div>
  <div id="cc-1-trailer" class="poll-section-trailer">
    <div id="cc-1-trailer-image" ><img src="' . $base . drupal_get_path('module', 'iform') . '/media/images/exclamation.jpg" /></div>
    <p>' . lang::get('LANG_Collection_Trailer_Point_1') . '</p>
    <p>' . lang::get('LANG_Collection_Trailer_Point_2') . '</p>
  </div>
<div style="display:none" />
    <form id="cc-1-delete-collection" action="' . iform_ajaxproxy_url($node, 'sample') . '" method="POST">
       <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
       <input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '" />
       <input type="hidden" name="sample:id" value="" />
       <input type="hidden" name="sample:date" value="2010-01-01"/>
       <input type="hidden" name="sample:location_id" value="" />
       <input type="hidden" name="sample:deleted" value="t" />
    </form>
</div>
  <div id="cc-1-main-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
';
        data_entry_helper::$javascript .= "\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";\nvar sessionCounter = 0;\njQuery('#imp-georef-search-btn').removeClass('indicia-button').addClass('search-button');\n// can't use shuffle to side as dynamic generated code does like it in IE7\n\nhtmlspecialchars = function(value){\n\treturn value.replace(/[<>\"'&]/g, function(m){return replacechar(m)})\n};\n\nreplacechar = function(match){\n\tif (match==\"<\") return \"&lt;\"\n\telse if (match==\">\") return \"&gt;\"\n\telse if (match=='\"') return \"&quot;\"\n\telse if (match==\"'\") return \"&#039;\"\n\telse if (match==\"&\") return \"&amp;\"\n};\n\n\$.fn.foldPanel = function(){\n\tthis.children('.poll-section-body,.poll-section-footer,.poll-section-trailer').hide();\n\tthis.children('.poll-section-title').find('.reinit-button,.mod-button').show();\n\tthis.children('.photoReelContainer').addClass('ui-corner-all').removeClass('ui-corner-top'); /* visibility depends on specific circumstances */\n};\n\n\$.fn.unFoldPanel = function(){\n\tthis.children('.poll-section-body,.poll-section-footer,.poll-section-trailer,.photoReelContainer').show();\n\tthis.children('.poll-section-title').find('.mod-button').hide();\n\tthis.children('.photoReelContainer').addClass('ui-corner-top').removeClass('ui-corner-all');\n\twindow.scroll(0,0); // force the window to display the top.\n\tbuildMap();\n\tcheckSessionButtons();\n\t// any reinit button is left in place\n};\n\n\$.fn.showPanel = function(){\n\tthis.show();\n\tthis.unFoldPanel();\n};\n\n\$.fn.hidePanel = function(){\n\tthis.hide(); \n};\n\ninseeLayer = null;\n\nnewDefaultSref = '0, 0';\noldDefaultSref = '" . ((int) $args['map_centroid_lat'] > 0 ? $args['map_centroid_lat'] . 'N' : -(int) $args['map_centroid_lat'] . 'S') . ' ' . ((int) $args['map_centroid_long'] > 0 ? $args['map_centroid_long'] . 'E' : -(int) $args['map_centroid_long'] . 'W') . "';\ndefaultGeom = '';\n\$.getJSON('" . $svcUrl . "' + '/spatial/sref_to_wkt'+\n        \t\t\t'?sref=' + newDefaultSref +\n          \t\t\t'&system=' + jQuery('#imp-sref-system').val() +\n          \t\t\t'&callback=?', function(data) {\n            \tdefaultGeom = data.wkt;\n                   \t});\n\n\$.fn.resetPanel = function(){\n\tthis.find('.poll-section-body').show();\n\tthis.find('.poll-section-footer,.poll-section-trailer').show();\n\tthis.find('.reinit-button').show();\n\tthis.find('.mod-button').show();\n\tthis.find('.poll-image').empty();\n\tthis.find('.poll-session').remove();\n\tthis.find('.inline-error').remove();\n\tthis.find('#imp-georef-search').val('');\n\tthis.find('#imp-georef-div').hide();\n\tthis.find('#imp-georef-output-div').empty();\n\tthis.find('[name=place\\:INSEE]').val('" . lang::get('LANG_INSEE') . "');\n\tthis.find('#imp-sref-lat').val('');\n\tthis.find('#imp-sref-long').val('');\n\tthis.find('#X-sref-system').val('900913'); //note only one of these in cc-1, distinct from location:centroid_sref_system. This indicates no geolocation loaded.\n\t// TODO Map\n\tthis.find('.thumb').not('.blankPhoto').remove();\n\tthis.find('.blankPhoto').addClass('currentPhoto');\n\t\n\t// resetForm does not reset the hidden fields. record_status, website_id and survey_id are not altered so do not reset.\n\t// hidden Attributes generally hold unchanging data, but the name needs to be reset (does it for non hidden as well).\n\t// hidden location:name are set in code anyway.\n\tthis.find('.poll-dummy-form input').val('');\n\tthis.find('.poll-dummy-form input').removeAttr('checked');\n\tthis.find('.poll-dummy-form select').val('');\n\tthis.find('.poll-dummy-form textarea').val('');\n\tthis.find('.poll-dummy-form').find('[name\$=\\:determination_type]').val('A');\n\tthis.find('form').each(function(){\n\t\tjQuery(this).resetForm();\n\t\tjQuery(this).find('[name=sample\\:location_name],[name=location_image\\:path],[name=occurrence_image\\:path]').val('');\n\t\tjQuery(this).filter('#cc-1-collection-details').find('[name=sample\\:id],[name=location\\:id]').val('').attr('disabled', 'disabled');\n\t\tjQuery(this).find('[name=location_image\\:id],[name=occurrence\\:id],[name=determination\\:id],[name=occurrence_image\\:id]').val('').attr('disabled', 'disabled');\n\t\tjQuery(this).find('[name=sample\\:date]:hidden').val('2010-01-01');\n\t\tjQuery(this).find('input[name=locations_website\\:website_id]').removeAttr('disabled');\n\t\tjQuery(this).find('[name=locAttr\\:" . $args['location_picture_camera_attr_id'] . "],[name^=locAttr\\:" . $args['location_picture_camera_attr_id'] . "\\:],[name=locAttr\\:" . $args['location_picture_datetime_attr_id'] . "],[name^=locAttr\\:" . $args['location_picture_datetime_attr_id'] . "\\:],[name=occAttr\\:" . $args['occurrence_picture_camera_attr_id'] . "],[name^=occAttr\\:" . $args['occurrence_picture_camera_attr_id'] . "\\:],[name=occAttr\\:" . $args['occurrence_picture_datetime_attr_id'] . "],[name^=occAttr\\:" . $args['occurrence_picture_datetime_attr_id'] . "\\:]').val('');\n\t\tjQuery(this).find('[name^=smpAttr\\:],[name^=locAttr\\:],[name^=occAttr\\:]').filter('.multiselect').remove();\n\t\tjQuery(this).find('[name^=smpAttr\\:],[name^=locAttr\\:],[name^=occAttr\\:]').each(function(){\n\t\t\tvar name = jQuery(this).attr('name').split(':');\n\t\t\tif(name[1].indexOf('[]') > 0) name[1] = name[1].substr(0, name[1].indexOf('[]'));\n\t\t\tjQuery(this).attr('name', name[0]+':'+name[1]);\n\t\t});\n\t\tjQuery(this).find('[name^=smpAttr\\:],[name^=locAttr\\:],[name^=occAttr\\:]').filter(':checkbox').removeAttr('checked').each(function(){\n\t\t\tvar name = jQuery(this).attr('name').split(':');\n\t\t\tvar similar = jQuery('[name='+name[0]+'\\:'+name[1]+'],[name='+name[0]+'\\:'+name[1]+'\\[\\]]').filter(':checkbox');\n\t\t\tif(similar.length > 1)\n\t\t\t\tjQuery(this).attr('name', name[0]+':'+name[1]+'[]');\n\t\t});\n\t\tjQuery(this).find('input[name=location\\:centroid_sref]').val('');\n\t\tjQuery(this).find('input[name=location\\:centroid_geom]').val('');\n    });\t\n  };\n\nalertIndiciaError = function(data){\n\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\tif(data.error){\terrorString = errorString + ' : ' + data.error;\t}\n\tif(data.errors){\n\t\tfor (var i in data.errors){\n\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t}\t\t\t\t\n\t}\n\talert(errorString);\n\t// the most likely cause is authentication failure - eg the read authentication has timed out.\n\t// prevent further use of the form:\n\t\$('.loading-panel').remove();\n\t\$('.poll-loading-hide').show();\n\tjQuery('#cc-1').hide();\n\tjQuery('#refresh-message').show();\n\tthrow('WAREHOUSE ERROR');\n};\n\t\t\t\ncheckProtocolStatus = function(display){\n  \tvar checkedProtocol = jQuery('[name=smpAttr\\:" . $args['protocol_attr_id'] . "],[name^=smpAttr\\:" . $args['protocol_attr_id'] . "\\:]').filter('[checked]').parent();\n    if(jQuery('[name=location\\:name]').val() != '' && checkedProtocol.length > 0) {\n        jQuery('#cc-1-title-details').empty().text(jQuery('#cc-1-collection-details input[name=location\\:name]:first').val());\n        firstBracket = checkedProtocol.find('label')[0].innerHTML.indexOf('(');\n        secondBracket = checkedProtocol.find('label')[0].innerHTML.lastIndexOf(')');\n        jQuery('#cc-1-protocol-details').empty().show().html('<strong>" . lang::get('LANG_Protocol_Title_Label') . "</strong> : <span class=\"protocol-head\">' +\n                  checkedProtocol.find('label')[0].innerHTML.slice(0, firstBracket-1) +\n                  '</span><span class=\"protocol-description\"> | ' +\n                  checkedProtocol.find('label')[0].innerHTML.slice(firstBracket+1, secondBracket) + '</span>');\n    } else {\n        jQuery('#cc-1-title-details').empty().text(\"" . lang::get('LANG_Collection_Details') . "\");\n        // TODO autogenerate a name\n        jQuery('#cc-1-protocol-details').empty().hide();\n    }\n    if(display == true){\n      jQuery('#cc-1-details').addClass('ui-accordian-content-active');\n    } else if(display == false){\n      jQuery('#cc-1-details').removeClass('ui-accordian-content-active');\n    } // anything else just leave\n};\ncheckForagingStatus = function(setForagingConfirm){\n\tjQuery('[name=occAttr\\:" . $args['foraging_attr_id'] . "],[name^=occAttr\\:" . $args['foraging_attr_id'] . ":]').filter('[checked]').each(function(index, elem){\n\t\tif(elem.value==1){ // need to allow string 1 comparison so no ===\n\t\t\tjQuery('#Foraging_Confirm').show();\n\t\t\tif(setForagingConfirm)\n\t\t\t\tjQuery('[name=dummy_foraging_confirm]').filter('[value=1]').attr('checked',true);\n\t\t} else\n\t\t\tjQuery('#Foraging_Confirm').hide();\n\t});\n};\ncheckSessionButtons = function(){\n\tif (jQuery('#cc-3-body').children().length === 1) {\n\t    jQuery('#cc-3').find('.delete-button').hide();\n\t    jQuery('#cc-3-valid-button').empty().text(\"" . lang::get('LANG_Validate_Session') . "\")\n  \t} else {\n\t\tjQuery('#cc-3').find('.delete-button').show();\n\t    jQuery('#cc-3-valid-button').empty().text(\"" . lang::get('LANG_Validate_Session_Plural') . "\")\n  \t}\n\tif(jQuery('[name=smpAttr\\:" . $args['protocol_attr_id'] . "],[name^=smpAttr\\:" . $args['protocol_attr_id'] . "\\:]').filter(':first').filter('[checked]').length >0){\n\t    jQuery('#cc-3-title-title').empty().text(\"" . lang::get('LANG_Sessions_Title') . "\");\n\t\tjQuery('#cc-3').find('.add-button').hide();\n\t} else {\n\t    jQuery('#cc-3-title-title').empty().text(\"" . lang::get('LANG_Sessions_Title_Plural') . "\");\n\t\tjQuery('#cc-3').find('.add-button').show();\n  \t}\n};\n\nshowStationPanel = true;\n\n// The validate functionality for each panel is sufficiently different that we can't generalise a function\n// this is the one called when we don't want the panel following to be opened automatically.\nvalidateCollectionPanel = function(){\n\tclearErrors('form#cc-1-collection-details');\n\tif(jQuery('#cc-1-body:visible').length == 0) return true; // body hidden so data already been validated successfully.\n\tif(!jQuery('#cc-1-body').find('form > input').valid()){\n\t\tmyScrollToError();\n\t\treturn false;\n  \t}\n\t// no need to check protocol - if we are this far, we've already filled it in.\n  \tshowStationPanel = false;\n\tjQuery('#cc-1-collection-details').submit();\n\treturn true;\n  };\n\nerrorPos = null;\nclearErrors = function(formSel) {\n\tjQuery(formSel).find('.inline-error').remove();\n\terrorPos = null;\n};\nmyScrollTo = function(selector){\n\tjQuery(selector).filter(':visible').each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\nmyScrollToError = function(){\n\tjQuery('.inline-error,.error').filter(':visible').prev().each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\n\nvalidateRadio = function(name, formSel){\n    var controls = jQuery(formSel).find('[name='+name+'],[name^='+name+'\\:]');\n    if(controls.filter('[checked]').length < 1) {\n        var label = \$('<p/>')\n\t\t\t\t.attr({'for': name})\n\t\t\t\t.addClass('inline-error')\n\t\t\t\t.html(\$.validator.messages.required);\n\t\tlabel.insertBefore(controls.filter(':first').parent());\n\t\treturn false;\n    }\n    return true;\n}\n\nvalidateRequiredField = function(name, formSel){\n    var control = jQuery(formSel).find('[name='+name+']');\n    if(control.val() == '') {\n        var label = \$('<p/>')\n\t\t\t\t.attr({'for': name})\n\t\t\t\t.addClass('inline-error')\n\t\t\t\t.html(\$.validator.messages.required);\n\t\tlabel.insertBefore(control);\n\t\treturn false;\n    }\n    return true;\n}\n\nvalidateOptInt = function(name, formSel){\n\tvar control = jQuery(formSel).find('[name='+name+'],[name^='+name+'\\:]');\n\tvar ctrvalue = control.val();\n\tvar OK = true;\n\tif(ctrvalue == '') return true;\n\tfor (i = 0 ; i < ctrvalue.length ; i++) {\n\t\tif ((ctrvalue.charAt(i) < '0') || (ctrvalue.charAt(i) > '9')) OK = false\n\t}\n\tif(OK) return OK;\n\tvar label = \$('<p/>')\n\t\t\t\t.attr({'for': name})\n\t\t\t\t.addClass('inline-error')\n\t\t\t\t.html(\"" . lang::get('validation_integer') . "\");\n\tlabel.insertBefore(control);\n\treturn false;\n}\n\ninsertImage = function(path, target, ratio){\n\tvar img = new Image();\n\tjQuery(img).load(function () {\n        target.removeClass('loading').append(this);\n        if(this.width/this.height > ratio){\n\t    \tjQuery(this).css('width', '100%').css('height', 'auto').css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n  \t\t} else {\n\t        jQuery(this).css('width', (100*this.width/(this.height*ratio))+'%').css('height', 'auto').css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n  \t\t}\n\t}).attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "'+path);\n}\n\t\t\t\t    \n\$('#cc-1').ajaxError(function(event, request, settings){\n\tvar insectURL = insectIDstruc.pollURL+insectIDstruc.sessionID;\n\tif(settings.url != insectURL){ // this url may not be present.\n\t\talert(\"" . lang::get('ajax_error') . "\" + '\\n' + settings.url + '\\n' + request.status + ' ' + request.statusText + '\\n' + \"" . lang::get('ajax_error_bumpf') . "\");\n\t\t// unknown data state so prevent further use of the form:\n\t\t\$('.loading-panel').remove();\n\t\t\$('.poll-loading-hide').show();\n\t\tjQuery('#cc-1').hide();\n\t\tjQuery('#refresh-message').show();\n\t\tthrow('AJAX ERROR');\n\t}\n});\n \nvalidateTime = function(name, formSel){\n    var control = jQuery(formSel).find('[name='+name+'],[name^='+name+'\\:]');\n    if(control.val().match(/^(2[0-3]|[0,1][0-9]):[0-5][0-9]\$/) == null) {\n        var label = \$('<p/>')\n\t\t\t\t.attr({'for': name})\n\t\t\t\t.addClass('inline-error')\n\t\t\t\t.html('" . lang::get('validation_time') . "');\n\t\tlabel.insertBefore(control);\n\t\treturn false;\n    }\n    return true;\n}\n\n\$('#cc-1-collection-details').ajaxForm({\n\t\tasync: false,\n        dataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n        \t// if location id filled in but sample id is not -> error\n        \tif(data.length == 15 && data[14].value == ''){\n        \t\talertIndiciaError({error : \"" . lang::get('Internal Error 1: sample id not filled in, so not safe to save collection') . "\"});\n\t\t\t\treturn false;\n\t\t\t}\n        \tclearErrors('form#cc-1-collection-details');\n        \tvar valid = true;\n        \tif (!jQuery('form#cc-1-collection-details > input').valid()) { valid = false; }\n        \tif (!validateRadio('smpAttr\\:" . $args['protocol_attr_id'] . "', 'form#cc-1-collection-details')) { valid = false; }\n\t       \tif ( valid == false ) {\n\t\t\t\tmyScrollToError();\n\t\t\t\treturn false;\n  \t\t\t};\n  \t\t\t// Warning this assumes that:\n  \t\t\t// 1) the location:name is the sixth field in the form.\n  \t\t\t// 1) the sample:location_name is the seventh field in the form.\n  \t\t\tdata[6].value = data[5].value;\n  \t\t\tif(data[3].value=='900913'){\n  \t\t\t\tdata[1].value=newDefaultSref;\n  \t\t\t\tdata[2].value=defaultGeom;\n  \t\t\t}\n  \t\t\tjQuery('#cc-2-floral-station > input[name=location\\:name]').val(data[5].value);\n  \t\t\tjQuery('#cc-1-valid-button').addClass('loading-button');\n        \treturn true;\n  \t\t},\n        success:   function(data){\n        \tif(data.success == 'multiple records' && data.outer_table == 'location'){\n        \t    jQuery('[name=location\\:id],[name=sample\\:location_id]').removeAttr('disabled').val(data.outer_id);\n        \t    jQuery('[name=locations_website\\:website_id]').attr('disabled', 'disabled');\n        \t    // data.struct.children[0] holds the details of the sample record.\n\t\t\t\tjQuery('#cc-6-consult-collection').attr('href', '" . url('node/' . $args['gallery_node']) . "'+'?collection_id='+data.struct.children[0].id);\n\t\t\t\tjQuery('#cc-1-collection-details,#cc-2-floral-station,#cc-1-delete-collection').find('[name=sample\\:id]').removeAttr('disabled').val(data.struct.children[0].id);\n\t\t\t\t// In this case we use loadAttributes to set the names of the attributes to include the attribute_value id.\n\t\t\t\t// cant use the struct as it can't tell which attribute is which. \n\t\t\t\tloadAttributes('#cc-1-collection-details,#cc-5-collection', 'sample_attribute_value', 'sample_attribute_id', 'sample_id', data.struct.children[0].id, 'smpAttr', true, true);\n\t\t\t   \tcheckProtocolStatus(true);\n        \t\t\$('#cc-1').foldPanel();\n    \t\t\tif(showStationPanel){ \$('#cc-2').showPanel(); }\n\t\t    \tshowStationPanel = true;\n        \t}  else \n\t\t\t\talertIndiciaError(data);\n        },\n        complete: function (){\n  \t\t\tjQuery('.loading-button').removeClass('loading-button');\n  \t\t}\n});\n\n\$('#cc-1-delete-collection').ajaxForm({ \n\t\tasync: false,\n\t\tdataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n  \t\t\t// Warning this assumes that the data is fixed position:\n       \t\tdata[3].value = jQuery('#cc-1-collection-details input[name=sample\\:date]').val();\n        \tif(data[2].value == '') return false;\n\t\t\tif(data[4].value == ''){ // double check that location id is filled in\n\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 3: location id not set, so unsafe to delete collection.') . "\"});\n\t\t\t\treturn false;\n\t\t\t}\n  \t\t\tjQuery('#cc-1-reinit-button').addClass('loading-button');\n        \treturn true;\n  \t\t},\n        success:   function(data){\n        \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n        \t\tjQuery('#cc-3-body').empty();\n        \t\tpollReset(insectIDstruc);\n\t        \tjQuery('.poll-section').resetPanel();\n\t\t\t\tsessionCounter = 0;\n\t\t\t\taddSession();\n\t\t\t\tcheckProtocolStatus(false);\n\t\t\t\tjQuery('.poll-section').hidePanel();\n\t\t\t\tjQuery('.poll-image').empty();\n\t\t\t\tjQuery('#cc-1').showPanel();\n\t\t\t\tjQuery('.reinit-button').hide();\n\t\t\t\tif(jQuery('#map').children().length > 0) {\n\t\t\t\t\tvar div = jQuery('#map')[0];\n\t\t\t\t\tdiv.map.editLayer.destroyFeatures();\n\t\t\t\t\tdiv.map.searchLayer.destroyFeatures();\n\t\t\t\t\tif(inseeLayer != null) inseeLayer.destroyFeatures();\n\t\t\t\t\tjQuery('#cc-2-loc-description').empty();\n\t\t\t\t\tvar center = new OpenLayers.LonLat(" . $args['map_centroid_long'] . ", " . $args['map_centroid_lat'] . ");\n\t\t\t\t\tcenter.transform(div.map.displayProjection, div.map.projection);\n\t\t\t\t\tdiv.map.setCenter(center, " . (int) $args['map_zoom'] . ");\n\t\t\t\t}\n        \t}  else \n\t\t\t\talertIndiciaError(data);\n  \t\t},\n        complete: function (){\n  \t\t\tjQuery('.loading-button').removeClass('loading-button');\n  \t\t}\n});\n\n\$('#cc-1-valid-button').click(function() {\n\tjQuery('#cc-1-collection-details').submit();\n});\n\n\$('#cc-1-reinit-button').click(function() {\n    clearErrors('form#cc-1-collection-details');\n\tif(jQuery('form#cc-1-collection-details > input[name=sample\\:id]').filter('[disabled]').length > 0) { return } // sample id is disabled, so no data has been saved - do nothing.\n    if (!jQuery('form#cc-1-collection-details > input').valid()) {\n    \tmyScrollToError();\n    \talert(\"" . lang::get('LANG_Unable_To_Reinit') . "\");\n        return ;\n  \t}\n\tif(confirm(\"" . lang::get('LANG_Confirm_Reinit') . "\")){\n\t\tjQuery('#cc-1-delete-collection').submit();\n\t}\n});\n\n";
        // Flower Station section.
        $options = iform_map_get_map_options($args, $readAuth);
        $olOptions = iform_map_get_ol_options($args);
        // The maps internal projection will be left at its default of 900913.
        $options['searchLayer'] = 'true';
        $options['initialFeatureWkt'] = null;
        $options['proxy'] = '';
        // Switch to degrees, minutes, seconds for lat long.
        $options['latLongFormat'] = 'DMS';
        if (lang::get('msgGeorefSelectPlace') != 'msgGeorefSelectPlace') {
            $options['msgGeorefSelectPlace'] = lang::get('msgGeorefSelectPlace');
        }
        if (lang::get('msgGeorefNothingFound') != 'msgGeorefNothingFound') {
            $options['msgGeorefNothingFound'] = lang::get('msgGeorefNothingFound');
        }
        $extraParams = $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order', 'allow_data_entry' => 't');
        $species_ctrl_args = array('fieldname' => 'flowerSelect', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'listCaptionSpecialChars' => true, 'valueField' => 'id', 'columns' => 2, 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $extraParams, 'suffixTemplate' => 'nosuffix');
        $r .= '
<div id="cc-2" class="poll-section">
  <div id="cc-2-title" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all poll-section-title"><span>' . lang::get('LANG_Flower_Station') . '</span>
    <div class="right">
      <span id="cc-2-mod-button" class="ui-state-default ui-corner-all mod-button">' . lang::get('LANG_Modify') . '</span>
    </div>
  </div>
  <div id="cc-2-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-top ui-accordion-content-active poll-section-body">
    <div id="cc-2-flower" >
	  <div id="cc-2-flower-title">' . lang::get('LANG_Upload_Flower') . '</div>
	  <form id="cc-2-flower-upload" enctype="multipart/form-data" action="' . iform_ajaxproxy_url($node, 'media') . '" method="POST">
    		<input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
    		<input name="upload_file" type="file" class="required" />
     		<input type="submit" value="' . lang::get('LANG_Upload') . '" class="btn-submit" />
 	  		<div id="cc-2-flower-image" class="poll-image"></div>
      </form>
      <div id="cc-2-flower-identify" class="poll-dummy-form">
        <div class="id-tool-group">
          ' . iform_pollenators::help_button($use_help, "flower-help-button", $args['help_function'], $args['help_flower_arg']) . '
		  <p><strong>' . lang::get('LANG_Identify_Flower') . ' :</strong></p>
          <div class="id-later-group">
            <label for="id-flower-later" class="follow-on">' . lang::get('LANG_ID_Flower_Later') . ' </label><input type="checkbox" id="id-flower-later" name="id-flower-later" /> 
          </div>
		  <input type="hidden" id="flower:taxon_details" name="flower:taxon_details" value=""/>
          <input type="hidden" name="flower:determination_type" value="A" />
          <input type="hidden" name="flower:taxa_taxon_list_id" value="" />
          <label for="id-flower-unknown" class="follow-on">' . lang::get('LANG_ID_Flower_Unknown') . ' </label><input type="checkbox" id="id-flower-unknown" name="id-flower-unknown" /><br/>
          ' . lang::get('LANG_Known_Species') . ' : <input name="flowerAutocomplete" id="flowerAutocomplete" />' . data_entry_helper::select($species_ctrl_args) . '
          <table id="flower-species-list"><tbody id="flower-species-list-body"></tbody></table>
        </div>
 	    <div class="id-specified-group">
          <label for="flower:taxon_extra_info" class="follow-on">' . lang::get('LANG_ID_More_Precise') . ' </label> 
          <input type="text" id="flower:taxon_extra_info" name="flower:taxon_extra_info" class="taxon-info" />
        </div>
      </div>
      <div class="id-comment">
        <label for="flower:comment" >' . lang::get('LANG_ID_Comment') . ' </label>
        <textarea id="flower:comment" name="flower:comment" class="taxon-comment" rows="3" ></textarea>
      </div>
    </div>
    <div class="poll-break"></div>
 	<div id="cc-2-environment">
	  ' . iform_pollenators::help_button($use_help, "environment-help-button", $args['help_function'], $args['help_environment_arg']) . '
	  <div id="cc-2-environment-title">' . lang::get('LANG_Upload_Environment') . '</div>
 	  <form id="cc-2-environment-upload" enctype="multipart/form-data" action="' . iform_ajaxproxy_url($node, 'media') . '" method="POST">
    	<input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
    	<input name="upload_file" type="file" class="required" />
    	<input type="submit" value="' . lang::get('LANG_Upload') . '" class="btn-submit" />
 	  	<div id="cc-2-environment-image" class="poll-image"></div>
      </form>
 	</div>
 	<form id="cc-2-floral-station" action="' . iform_ajaxproxy_url($node, 'loc-smp-occ') . '" method="POST">
      <input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
      <input type="hidden" id="location:id" name="location:id" value="" />
      <input type="hidden" id="location:name" name="location:name" value=""/>
      <input type="hidden" name="location:centroid_sref" />
      <input type="hidden" name="location:centroid_geom" />
      <input type="hidden" id="imp-sref-system" name="location:centroid_sref_system" value="4326" />
      <input type="hidden" id="location_image:path" name="location_image:path" value="" />
      <input type="hidden" id="location_picture_camera_attr" name="locAttr:' . $args['location_picture_camera_attr_id'] . '" value="" />
      <input type="hidden" id="location_picture_datetime_attr" name="locAttr:' . $args['location_picture_datetime_attr_id'] . '" value="" />
      <input type="hidden" id="sample:survey_id" name="sample:survey_id" value="' . $args['survey_id'] . '" />
      <input type="hidden" id="sample:id" name="sample:id" value=""/>
      <input type="hidden" name="sample:date" value="2010-01-01"/>
      <input type="hidden" name="determination:taxa_taxon_list_id" value=""/>  
      <input type="hidden" name="determination:taxon_details" value=""/>  
      <input type="hidden" name="determination:taxon_extra_info" value=""/>  
      <input type="hidden" name="determination:comment" value=""/>  
      <input type="hidden" name="determination:determination_type" value="A" />  
      <input type="hidden" name="determination:cms_ref" value="' . $uid . '" />
      <input type="hidden" name="determination:email_address" value="' . $email . '" />
      <input type="hidden" name="determination:person_name" value="' . $username . '" />  
      <input type="hidden" name="occurrence:use_determination" value="Y"/>    
      <input type="hidden" name="occurrence:record_status" value="C" />
      <input type="hidden" id="location_image:id" name="location_image:id" value="" disabled="disabled" />
      <input type="hidden" id="occurrence:id" name="occurrence:id" value="" disabled="disabled" />
      <input type="hidden" id="determination:id" name="determination:id" value="" disabled="disabled" />
      <input type="hidden" id="occurrence_image:id" name="occurrence_image:id" value="" disabled="disabled" />
      <input type="hidden" id="occurrence_image:path" name="occurrence_image:path" value="" />
      <input type="hidden" id="flower_picture_camera_attr" name="occAttr:' . $args['occurrence_picture_camera_attr_id'] . '" value="" />
      <input type="hidden" id="flower_picture_datetime_attr" name="occAttr:' . $args['occurrence_picture_datetime_attr_id'] . '" value="" />
      ' . str_replace("\n", "", data_entry_helper::outputAttribute($occurrence_attributes[$args['flower_type_attr_id']], $defNRAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($location_attributes[$args['distance_attr_id']], $defNRAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($location_attributes[$args['within50m_attr_id']], $defNRAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($location_attributes[$args['habitat_attr_id']], $checkOptions)) . '
    </form>
    <div class="poll-break"></div>
    <div id="cc-2-location-container">
      ' . iform_pollenators::help_button($use_help, "location-help-button", $args['help_function'], $args['help_location_arg']) . '
      <div id="cc-2-location-notes" >' . lang::get('LANG_Location_Notes') . '</div>
      <div id="cc-2-location-entry">
        ' . data_entry_helper::georeference_lookup(iform_map_get_georef_options($args, $readAuth)) . '
  	    <label for="place:INSEE">' . lang::get('LANG_Or') . '</label><input type="text" id="place:INSEE" name="place:INSEE" value="' . lang::get('LANG_INSEE') . '"
	 		onclick="if(this.value==\'' . lang::get('LANG_INSEE') . '\'){this.value=\'\'; this.style.color=\'#000\'}"  
            onblur="if(this.value==\'\'){this.value=\'' . lang::get('LANG_INSEE') . '\'; this.style.color=\'#555\'}" /><input type="button" id="search-insee-button" class="ui-corner-all ui-widget-content ui-state-default search-button" value="' . lang::get('search') . '" />
 	    <label >' . lang::get('LANG_Or') . '</label>
    	' . data_entry_helper::sref_textbox(array('srefField' => 'place:entered_sref', 'systemfield' => 'place:entered_sref_system', 'id' => 'place-sref', 'fieldname' => 'place:name', 'splitLatLong' => true, 'labelLat' => lang::get('Latitude'), 'fieldnameLat' => 'place:lat', 'labelLong' => lang::get('Longitude'), 'fieldnameLong' => 'place:long', 'idLat' => 'imp-sref-lat', 'idLong' => 'imp-sref-long')) . '
 	  </div>
 	  <div class="poll-map-container">';
        $tempScript = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = '';
        $r .= data_entry_helper::map_panel($options, $olOptions);
        $map1JS = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = $tempScript;
        $r .= '</div>
 	  <div id="cc-2-loc-description"></div>
    </div>
  </div>
  <div id="cc-2-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active poll-section-footer">
    <div id="cc-2-valid-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate_Flower') . '</div>
  </div>
</div>';
        // NB the distance attribute is left blank at the moment if unknown: TODO put in a checkbox : checked if blank for nsp
        data_entry_helper::$javascript .= "\njQuery('input#flowerAutocomplete').autocomplete(flowerTaxa,\n      { matchContains: true,\n        parse: function(data)\n        {\n          var results = [];\n          jQuery.each(data, function(i, item) {\n            results[results.length] =\n            {\n              'data' : item,\n              'result' : item.id,\n              'value' : item.taxon\n            };\n          });\n          return results;\n        },\n      formatItem: function(item)\n      {\n        return item.taxon;\n      }\n      // {max}\n});\njQuery('input#flowerAutocomplete').result(function(event, data) {\n  if(jQuery('#flower-species-list input[value='+data.id+']').length > 0) return;\n  jQuery('input#flowerAutocomplete').val('');\n  jQuery('<tr class=\"flower-species-list-entry\"><td><input type=\"hidden\" name=\"flower:taxa_taxon_list_id_list[]\" value=\"'+data.id+'\"\\>'+htmlspecialchars(data.taxon)+'</td><td><img class=\"removeRow\" src=\"/misc/watchdog-error.png\" alt=\"" . lang::get('Remove this entry') . "\" title=\"" . lang::get('Remove this entry') . "\"/></td></tr>').appendTo('#flower-species-list-body');\n  jQuery('#cc-2-flower-identify [name=flower\\:determination_type]').val('A');\n  jQuery('#id-flower-unknown').removeAttr('checked');\n  jQuery('#id-flower-later').removeAttr('checked').attr('disabled','disabled');\n});\njQuery('select#flowerSelect').change(function() {\n  if(jQuery('#flower-species-list input[value='+jQuery(this).val()+']').length > 0) return;\n  jQuery('<tr class=\"flower-species-list-entry\"><td><input type=\"hidden\" name=\"flower:taxa_taxon_list_id_list[]\" value=\"'+jQuery(this).val()+'\"\\>'+htmlspecialchars(jQuery(this).find('option[value='+jQuery(this).val()+']').text())+'</td><td><img class=\"removeRow\" src=\"/misc/watchdog-error.png\" alt=\"" . lang::get('Remove this entry') . "\" title=\"" . lang::get('Remove this entry') . "\"/></td></tr>').appendTo('#flower-species-list-body');\n  jQuery('#cc-2-flower-identify [name=flower\\:determination_type]').val('A');\n  jQuery('select#flowerSelect').val('');\n  jQuery('#id-flower-unknown').removeAttr('checked');\n  jQuery('#id-flower-later').removeAttr('checked').attr('disabled','disabled');\n});\nshowSessionsPanel = true;\n\nbuildMap = function (){\n\tif(jQuery('.poll-map-container:visible').length == 0) return; \n\tif(jQuery('#map').children().length == 0) {\n\t\t" . $map1JS . "\n  \t\tjQuery('#map')[0].map.searchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tif(inseeLayer != null) inseeLayer.destroyFeatures();\n\t\t});\n\t\tjQuery('#map')[0].map.editLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tif(inseeLayer != null) inseeLayer.destroy();\n\t\t\tjQuery('#cc-2-loc-description').empty();\n\t\t  \tvar filter = new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.CONTAINS, property: 'the_geom', value: jQuery('#map')[0].map.editLayer.features[0].geometry});\n\t\t\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\t\t\tvar styleMap = new OpenLayers.StyleMap({\"default\": new OpenLayers.Style({fillColor: \"Red\", strokeColor: \"Red\", fillOpacity: 0, strokeWidth: 1})});\n\t\t\tinseeLayer = new OpenLayers.Layer.Vector('INSEE Layer', {\n\t\t\t\tstyleMap: styleMap,\n\t\t\t\tstrategies: [strategy],\n\t\t\t\tdisplayInLayerSwitcher: false,\n\t\t\t\tprotocol: new OpenLayers.Protocol.WFS({\n\t\t\t\t\turl:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n\t\t\t\t\tfeaturePrefix: '" . $args['INSEE_prefix'] . "',\n\t\t\t\t\tfeatureType: '" . $args['INSEE_type'] . "',\n\t\t\t\t\tgeometryName:'the_geom',\n\t\t\t\t\tfeatureNS: '" . $args['INSEE_ns'] . "',\n\t\t\t\t\tsrsName: 'EPSG:900913',\n\t\t\t\t\tversion: '1.1.0'                  \n\t\t\t\t\t,propertyNames: ['the_geom', 'NOM', 'INSEE_NEW', 'DEPT_NUM', 'DEPT_NOM', 'REG_NUM', 'REG_NOM']\n\t\t\t\t}),\n\t\t\t\tfilter: filter\n\t\t\t});\n\t\t    inseeLayer.events.register('featuresadded', {}, function(a1){\n    \t\t\tif(a1.features.length > 0)\n\t\t\t    \tjQuery('<span>'+a1.features[0].attributes.NOM+' ('+a1.features[0].attributes.INSEE_NEW+'), '+a1.features[0].attributes.DEPT_NOM+' ('+a1.features[0].attributes.DEPT_NUM+'), '+a1.features[0].attributes.REG_NOM+' ('+a1.features[0].attributes.REG_NUM+')</span>').appendTo('#cc-2-loc-description');\n\t\t    });\n\t\t\tjQuery('#map')[0].map.addLayer(inseeLayer);\n\t\t\tstrategy.load({});\n\t\t});\n\t}\n}\n\nflowerIDstruc = {\n\ttype: 'flower',\n\tselector: '#cc-2-flower-identify',\n\tmainForm: 'form#cc-2-floral-station',\n\tuseKey: false,\n\tstoredTaxaList: [],\n\tname: 'flowerIDstruc',\n\ttaxaList: flowerTaxa\n};\n\ntoolPoller = function(toolStruct){\n\tif(toolStruct.sessionID == '') return;\n\ttoolStruct.pollTimer = setTimeout('toolPoller('+toolStruct.name+');', " . $args['ID_tool_poll_interval'] . ");\n\tjQuery.ajax({\n\t url: toolStruct.pollURL+toolStruct.sessionID,\n\t dataType: 'jsonp',\n     toolStruct: toolStruct,\n\t success: function(da){ // now jsonp form, so comes in already parsed.\n\t  pollReset(this.toolStruct);\n\t  var status = da.data.sddversion + ' : ' + JSON.stringify(da.data.history);\n      jQuery(this.toolStruct.selector+' [name='+this.toolStruct.type+'\\:taxon_details]').val(status); // Stores details how the identification was arrived at within the tool.\n      if(typeof da.urlimage != 'undefined' && da.urlimage != 'none'){\n        // Upload image file into server.\n        // TODO ids should be data driven from ID Struct items.\n        jQuery('#cc-4-insect-upload input[name=upload_file]').val('');\n        \$('#cc-4-insect-image').empty();\n        \$('#cc-4-insect-image').addClass('loading');\n        jQuery('form#cc-4-main-form input[name=occurrence_image\\:path]').val('');\n        \$.post('" . iform_ajaxproxy_url($node, 'remoteMedia') . "',\n\t\t\t{ website_id : '" . $args['website_id'] . "',\n\t\t\t  file_url : da.urlimage },\n\t\t\tfunction(data) {\n\t\t\t\t\$('#cc-4-insect-image').removeClass('loading');\n        \t\tif(data.success == true){\n\t        \t\t// There is only one file\n\t        \t\tjQuery('form#cc-4-main-form input[name=occurrence_image\\:path]').val(data.files[0].filename);\n\t        \t\tjQuery('#insect_picture_camera_attr').val(data.files[0].EXIF_Camera_Make);\n\t        \t\tjQuery('#insect_picture_datetime_attr').val(data.files[0].EXIF_DateTime);\n\t        \t\tinsertImage('med-'+data.files[0].filename, jQuery('#cc-4-insect-image'), " . $args['Insect_Image_Ratio'] . ");\n\t\t\t\t}  else\n\t\t\t\t\talertIndiciaError(data);\n\t\t\t},\n\t\t\t'json');\n      }\n      var items = da.data.itemsselected;\n\t  var count = items.length;\n\t  if(count <= 0){\n\t  \t// no valid stuff so blank it all out.\n\t  \tjQuery('#'+this.toolStruct.type+'_taxa_list').append(\"" . lang::get('LANG_Taxa_Unknown_In_Tool') . "\");\n\t  \tjQuery(this.toolStruct.selector+' [name='+this.toolStruct.type+'\\:determination_type]').val('X'); // Unidentified.\n      } else {\n      \tvar resultsIDs = [];\n      \tvar resultsText = \"" . lang::get('LANG_Taxa_Returned') . "<br />{ \";\n      \tvar notFound = '';\n\t\tfor(var j=0; j < count; j++){\n\t\t\tvar found = false;\n\t\t\tfor(i = 0; i< this.toolStruct.taxaList.length; i++){\n  \t\t\t\tif(this.toolStruct.taxaList[i].xperID == items[j].itemId){\n\t  \t\t\t\tresultsIDs.push(this.toolStruct.taxaList[i].id);\n\t  \t\t\t\tresultsText = resultsText + (j == 0 ? '' : '<br />&nbsp;&nbsp;') + htmlspecialchars(this.toolStruct.taxaList[i].taxon);\n\t  \t\t\t\tfound = true;\n\t  \t\t\t\tbreak;\n  \t\t\t\t}\n  \t\t\t};\n  \t\t\tif(!found){\n  \t\t\t\tnotFound = (notFound == '' ? '' : notFound + ', ') + items[j].itemId; // don't need special chars as going into an input field\n  \t\t\t}\n  \t\t}\n\t\tjQuery('#'+this.toolStruct.type+'_taxa_list').append(resultsText+ ' }');\n\t\tthis.toolStruct.storedTaxaList = resultsIDs;\n\t  \tif(notFound != ''){\n\t\t\tvar comment = jQuery('[name='+this.toolStruct.type+'\\:comment]');\n\t\t\tcomment.val('" . lang::get('LANG_ID_Unrecognised') . " '+notFound+'. '+comment.val());\n\t\t}\n  \t  }\n    }});\n};\n\npollReset = function(toolStruct){\n\tclearTimeout(toolStruct.timeOutTimer);\n\tclearTimeout(toolStruct.pollTimer);\n\tjQuery('#'+toolStruct.type+'-id-cancel').hide();\n\tjQuery('#'+toolStruct.type+'-id-button').show();\n\ttoolStruct.storedTaxaList = [];\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_details]').val('');\n\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\ttoolStruct.sessionID='';\n\ttoolStruct.timeOutTimer = null;\n\ttoolStruct.pollTimer = null;\n};\n\nidButtonPressed = function(toolStruct){\n    if(!toolStruct.useKey) return;\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:determination_type]').val('A');\n\tjQuery('#id-'+toolStruct.type+'-later').removeAttr('checked');\n\ttoolStruct.storedTaxaList = [];\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_details]').val('');\n\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxa_taxon_list_id]').val('');\n\tjQuery('#'+toolStruct.type+'-id-cancel').show();\n\tjQuery('#'+toolStruct.type+'-id-button').hide();\n\tvar d = new Date;\n\tvar s = d.getTime();\n\ttoolStruct.sessionID = '" . session_id() . "_'+s.toString()\n\tclearTimeout(toolStruct.timeOutTimer);\n\tclearTimeout(toolStruct.pollTimer);\n\tvar toolURL = toolStruct.invokeURL+'" . $args['ID_tool_session_param'] . "'+toolStruct.sessionID;\n\tvar path = jQuery('form#cc-4-main-form input[name=occurrence_image\\:path]').val();\n\tif(path != '') {\n    \tvar file = '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "'+path;\n    \ttoolURL += '&urlimageuser='******'','');\n\ttoolStruct.pollTimer = setTimeout('toolPoller('+toolStruct.name+');', " . $args['ID_tool_poll_interval'] . ");\n\ttoolStruct.timeOutTimer = setTimeout('toolReset('+toolStruct.name+');', " . $args['ID_tool_poll_timeout'] . ");\n};\n\ntaxonChosen = function(toolStruct){\n  \tjQuery('#id-'+toolStruct.type+'-later').removeAttr('checked');\n\ttoolStruct.storedTaxaList = [];\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_details]').val('');\n\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\tjQuery('[name='+toolStruct.type+'\\:comment]').val('');\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_extra_info]').val('');\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:determination_type]').val('A');\n};\n\nidLater = function (toolStruct){\n  if (jQuery('#id-'+toolStruct.type+'later').attr('checked') != '') {\n    jQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:determination_type]').val('A');\n    jQuery('.'+toolStruct.type+'-species-list-entry').remove();\n    jQuery('#id-'+toolStruct.type+'-unknown').removeAttr('checked');\n    toolStruct.storedTaxaList = [];\n    jQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_details]').val('');\n    jQuery('#'+toolStruct.type+'_taxa_list').empty();\n    jQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxa_taxon_list_id]').val('');\n    jQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_extra_info]').val(''); // more precise info\n    jQuery('[name='+toolStruct.type+'\\:comment]').val('');\n  }\n};\njQuery('#id-flower-later').change(function (){\n\tidLater(flowerIDstruc);\n});\njQuery('#id-flower-unknown').change(function (){\n  if (jQuery('#id-flower-unknown').attr('checked') != '') {\n    jQuery('#id-flower-later').removeAttr('checked').attr('disabled','disabled');\n    jQuery('#cc-2-flower-identify [name=flower\\:determination_type]').val('X');\n    jQuery('.flower-species-list-entry').remove();\n    jQuery('#cc-2-flower-identify [name=flower\\:taxon_details]').val('');\n    jQuery('#cc-2-flower-identify [name=flower\\:taxa_taxon_list_id]').val('');\n    jQuery('#cc-2-flower-identify [name=flower\\:taxon_extra_info]').val(''); // more precise info\n    jQuery('[name=flower\\:comment]').val('');\n  } else\n    jQuery('#id-flower-later').removeAttr('disabled');\n});\njQuery('.removeRow').live('click', function (){\n  if(jQuery('.removeRow').length <= 1)\n    jQuery('#id-flower-later').removeAttr('disabled');\n  jQuery(this).closest('tr.flower-species-list-entry').remove();\n});\n\njQuery('#search-insee-button').click(function(){\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroy();\n\tvar filters = [];\n  \tvar place = jQuery('input[name=place\\:INSEE]').val();\n  \tif(place == '" . lang::get('LANG_INSEE') . "') return;\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_NEW',\n    \t\tvalue: place\n  \t\t}));\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_OLD',\n    \t\tvalue: place\n  \t\t}));\n\n\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\tvar styleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Red\",\n                    strokeColor: \"Red\",\n                    fillOpacity: 0,\n                    strokeWidth: 1\n                  })\n\t});\n\tinseeLayer = new OpenLayers.Layer.Vector('INSEE Layer', {\n\t\t  styleMap: styleMap,\n          strategies: [strategy],\n          displayInLayerSwitcher: false,\n\t      protocol: new OpenLayers.Protocol.WFS({\n              url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n              featurePrefix: '" . $args['INSEE_prefix'] . "',\n              featureType: '" . $args['INSEE_type'] . "',\n              geometryName:'the_geom',\n              featureNS: '" . $args['INSEE_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0'                  \n      \t\t  ,propertyNames: ['the_geom']\n  \t\t\t}),\n  \t\t  filter: new OpenLayers.Filter.Logical({\n\t\t\t      type: OpenLayers.Filter.Logical.OR,\n\t\t\t      filters: filters\n\t\t  })\n    });\n\tinseeLayer.events.register('featuresadded', {}, function(a1){\n\t\tvar div = jQuery('#map')[0];\n\t\tdiv.map.searchLayer.destroyFeatures();\n\t\tvar bounds=inseeLayer.getDataExtent();\n    \tvar dy = (bounds.top-bounds.bottom)/10;\n    \tvar dx = (bounds.right-bounds.left)/10;\n    \tbounds.top = bounds.top + dy;\n    \tbounds.bottom = bounds.bottom - dy;\n    \tbounds.right = bounds.right + dx;\n    \tbounds.left = bounds.left - dx;\n    \t// if showing a point, don't zoom in too far\n    \tif (dy===0 && dx===0) {\n    \t\tdiv.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n    \t} else {\n    \t\tdiv.map.zoomToExtent(bounds);\n    \t}\n    });\n\tinseeLayer.events.register('loadend', {}, function(){\n\t\tif(inseeLayer.features.length == 0){\n\t\t\talert(\"" . lang::get('LANG_NO_INSEE') . "\");\n\t\t}\n    });\n    jQuery('#map')[0].map.addLayer(inseeLayer);\n\tstrategy.load({});\n});\n\nvalidateStationPanel = function(){\n\tvar myPanel = jQuery('#cc-2');\n\tvar valid = true;\n\tclearErrors('form#cc-2-floral-station');\n\tclearErrors('#cc-2-flower-identify');\n\tif(myPanel.filter(':visible').length == 0) return true; // panel is not visible so no data to fail validation.\n\tif(myPanel.find('.poll-section-body:visible').length == 0) return true; // body hidden so data already been validated successfully.\n\t// If no data entered also return true: this can only be the case when pressing the modify button on the collections panel\n\tif(jQuery('form#cc-2-floral-station > input[name=location_image\\:path]').val() == '' &&\n\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence\\:id]').val() == '' &&\n\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence_image\\:path]').val() == '' &&\n\t\t\tjQuery('.flower-species-list-entry').length == 0 &&\n\t\t\tjQuery('#cc-2-flower-identify [name=flower\\:taxon_extra_info]').val() == '' &&\n\t\t\tjQuery('[name=flower\\:comment]').val() == '' &&\n\t\t\tjQuery('[name=occAttr\\:" . $args['flower_type_attr_id'] . "],[name^=occAttr\\:" . $args['flower_type_attr_id'] . "\\:]').filter('[checked]').length == 0 &&\n\t\t\tjQuery('[name=locAttr\\:" . $args['within50m_attr_id'] . "],[name^=locAttr\\:" . $args['within50m_attr_id'] . "\\:]').filter('[checked]').length == 0 &&\n\t\t\tjQuery('[name=locAttr\\:" . $args['habitat_attr_id'] . "],[name^=locAttr\\:" . $args['habitat_attr_id'] . "\\:]').filter('[checked]').length == 0 &&\n    \t\tjQuery('[name=locAttr\\:" . $args['distance_attr_id'] . "],[name^=locAttr\\:" . $args['distance_attr_id'] . "\\:]').val() == '') {\n\t\tjQuery('#cc-2').foldPanel();\n\t\treturn true;\n\t}\n    if(jQuery('form#cc-2-floral-station > input[name=location_image\\:path]').val() == '' ||\n\t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence_image\\:path]').val() == ''){\n\t\tif(jQuery('form#cc-2-floral-station > input[name=occurrence_image\\:path]').val() == '')\n\t\t\tmyScrollTo('#cc-2-flower-upload');\n\t\telse\n\t\t\tmyScrollTo('#cc-2-environment-upload');\n\t\talert(\"" . lang::get('LANG_Must_Provide_Pictures') . "\");\n\t\tvalid = false;\n\t}\n    if(jQuery('#imp-geom').val() == '') {\n\t\talert(\"" . lang::get('LANG_Must_Provide_Location') . "\");\n\t\tmyScrollTo('.poll-map-container');\n\t\tvalid = false;\n\t}\n\tif (jQuery('#id-flower-later').attr('checked') == '' && jQuery('#id-flower-unknown').attr('checked') == '' && jQuery('.flower-species-list-entry').length == 0){\n\t\talert(\"" . lang::get('LANG_Must_Provide_Identification') . "\");\n\t\tmyScrollTo('#id-flower-later');\n\t\tvalid = false;\n    }\n\tif (!jQuery('form#cc-2-floral-station > input').valid()) { valid = false; }\n\tif (!validateRadio('occAttr\\:" . $args['flower_type_attr_id'] . "', 'form#cc-2-floral-station')) { valid = false; }\n\tif (!validateRadio('locAttr\\:" . $args['within50m_attr_id'] . "', 'form#cc-2-floral-station')) { valid = false; }\n\tif (!validateOptInt('locAttr\\:" . $args['distance_attr_id'] . "', 'form#cc-2-floral-station')) { valid = false; }\n   \tif ( valid == false ) {\n   \t\tmyScrollToError();\n   \t\treturn valid;\n   \t}\n\tshowSessionsPanel = false;\n\tjQuery('form#cc-2-floral-station').submit();\n\treturn true;\n};\n\n// Flower upload picture form.\n\$('#cc-2-flower-upload').ajaxForm({ \n\t\tasync: false,\n\t\tdataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n         \tif (!jQuery('form#cc-2-flower-upload').valid() ||\n                    jQuery('#cc-2-flower-image').hasClass('loading')) {\n   \t\t\t\treturn false;\n   \t\t\t}\n   \t\t\t\$('#cc-2-flower-image').empty();\n        \t\$('#cc-2-flower-image').addClass('loading');\n\t\t   \tjQuery('form#cc-2-floral-station input[name=occurrence_image\\:path]').val('');\n  \t\t},\n        success:   function(data){\n        \tif(data.success == true){\n\t        \t// There is only one file\n\t        \tjQuery('form#cc-2-floral-station input[name=occurrence_image\\:path]').val(data.files[0].filename);\n\t        \tjQuery('#flower_picture_camera_attr').val(data.files[0].EXIF_Camera_Make);\n\t        \tjQuery('#flower_picture_datetime_attr').val(data.files[0].EXIF_DateTime);\n\t        \tinsertImage('med-'+data.files[0].filename, jQuery('#cc-2-flower-image'), " . $args['Flower_Image_Ratio'] . ");\n\t        \tjQuery('#cc-2-flower-upload input[name=upload_file]').val('');\n  \t\t\t} else\n\t\t\t\talertIndiciaError(data);\n  \t\t},\n  \t\tcomplete: function(){\n\t\t\t\$('#cc-2-flower-image').removeClass('loading');\n  \t\t}\n});\n\n// Flower upload picture form.\n\$('#cc-2-environment-upload').ajaxForm({ \n\t\tasync: false,\n\t\tdataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n         \tif (!jQuery('form#cc-2-environment-upload').valid()) {\n   \t\t\t\treturn false;\n   \t\t\t}\n        \t\$('#cc-2-environment-image').empty();\n        \t\$('#cc-2-environment-image').addClass('loading')\n\t       \tjQuery('form#cc-2-floral-station input[name=location_image\\:path]').val('');\n  \t\t},\n        success:   function(data){\n        \tif(data.success == true){\n\t        \t// There is only one file\n\t        \tjQuery('form#cc-2-floral-station input[name=location_image\\:path]').val(data.files[0].filename);\n\t        \tjQuery('#location_picture_camera_attr').val(data.files[0].EXIF_Camera_Make);\n\t        \tjQuery('#location_picture_datetime_attr').val(data.files[0].EXIF_DateTime);\n\t        \tinsertImage('med-'+data.files[0].filename, jQuery('#cc-2-environment-image'), " . $args['Environment_Image_Ratio'] . ");\n\t\t\t\tjQuery('#cc-2-environment-upload input[name=upload_file]').val('');\n\t\t\t} else\n\t\t\t\talertIndiciaError(data);\n        },\n  \t\tcomplete: function(){\n\t\t\t\$('#cc-2-environment-image').removeClass('loading');\n  \t\t}\n});\n\nfindID = function(name, data){\n\tfor(var i=0; i< data.length;i++){\n\t\tif(data[i].name == name) return i;\n\t}\n};\n\n\$('#cc-2-floral-station').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n    beforeSubmit:   function(data, obj, options){\n\t\tvar valid = true;\n\t\tclearErrors('form#cc-2-floral-station');\n\t\tclearErrors('#cc-2-flower-identify');\n    \tif(jQuery('form#cc-2-floral-station > input[name=location_image\\:path]').val() == '' ||\n\t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence_image\\:path]').val() == '' ){\n\t\t\tif(jQuery('form#cc-2-floral-station > input[name=occurrence_image\\:path]').val() == '')\n\t\t\t\tmyScrollTo('#cc-2-flower-upload');\n\t\t\telse\n\t\t\t\tmyScrollTo('#cc-2-environment-upload');\n\t\t\talert(\"" . lang::get('LANG_Must_Provide_Pictures') . "\");\n\t\t\tvalid = false;\n\t\t}\n\t\tif(jQuery('#imp-geom').val() == '') {\n\t\t\tmyScrollTo('.poll-map-container');\n\t\t\talert(\"" . lang::get('LANG_Must_Provide_Location') . "\");\n\t\t\tvalid = false;\n\t\t}\n\t\tif (!jQuery('form#cc-2-floral-station > input').valid()) { valid = false; }\n\t\tif (!validateRadio('occAttr\\:" . $args['flower_type_attr_id'] . "', 'form#cc-2-floral-station')) { valid = false; }\n\t\tif (!validateRadio('locAttr\\:" . $args['within50m_attr_id'] . "', 'form#cc-2-floral-station')) { valid = false; }\n\t\tif (!validateOptInt('locAttr\\:" . $args['distance_attr_id'] . "', 'form#cc-2-floral-station')) { valid = false; }\n\t\tdata[findID('location:centroid_sref', data)].value = jQuery('#imp-sref').val();\n\t\tdata[findID('location:centroid_geom', data)].value = jQuery('#imp-geom').val();\n\t\tif (jQuery('#id-flower-later').attr('checked') == ''){\n\t\t    var entries = jQuery('.flower-species-list-entry');\n\t\t    if (jQuery('#id-flower-unknown').attr('checked') == '' && entries.length == 0){\n\t\t      alert(\"" . lang::get('LANG_Must_Provide_Identification') . "\");\n\t\t      myScrollTo('#id-flower-later');\n\t\t      valid = false;\n            }\n\t\t    data[findID('determination:taxa_taxon_list_id', data)].value = '';\n\t\t\tdata[findID('determination:taxon_details', data)].value = jQuery('#cc-2-flower-identify [name=flower\\:taxon_details]').val();\n\t\t\tdata[findID('determination:taxon_extra_info', data)].value = jQuery('#cc-2-flower-identify [name=flower\\:taxon_extra_info]').val();\n\t\t\tdata[findID('determination:comment', data)].value = jQuery('[name=flower\\:comment]').val();\n\t\t\tdata[findID('determination:determination_type', data)].value = jQuery('#cc-2-flower-identify [name=flower\\:determination_type]').val();\n\t\t\tif (data[findID('determination:determination_type', data)].value == 'A'){\n\t\t\t  if(entries.length == 1)\n\t\t\t    data[findID('determination:taxa_taxon_list_id', data)].value = jQuery(entries[0]).find('input').val();\n\t\t\t  else\n\t\t\t    for(var i = 0; i< entries.length; i++){\n\t\t\t\t  data.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: jQuery(entries[i]).find('input').val()});\n                }\n\t\t\t}\n\t\t} else { // ID later - remove determination entries from form.\n\t\t    data.splice(findID('determination:taxa_taxon_list_id', data),1);\n\t\t\tdata.splice(findID('determination:taxon_details', data),1);\n\t\t\tdata.splice(findID('determination:taxon_extra_info', data),1);\n\t\t\tdata.splice(findID('determination:comment', data),1);\n\t\t\tdata.splice(findID('determination:determination_type', data),1);\n\t\t\tdata.splice(findID('determination:cms_ref', data),1);\n\t\t\tdata.splice(findID('determination:email_address', data),1);\n\t\t\tdata.splice(findID('determination:person_name', data),1);\n\t\t\t// data.splice(12,8); \n\t\t}\n   \t\tif ( valid == false ) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n  \t\tjQuery('#cc-2-valid-button').addClass('loading-button');\n   \t\treturn true;\n\t},\n    success:   function(data){\n       \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n       \t\t// the sample and location ids are already fixed, so just need to populate the occurrence and image IDs, and rename the location and occurrence attribute.\n\t\t\t// ONLY 1 CHILD, THE OCCURRENCE: TBD ADD CHECK THAT IF ALREADY EXISTS THAT VALUES ARE THE SAME.\n\t\t\tjQuery('#cc-2-floral-station > input[name=occurrence\\:id]').removeAttr('disabled').val(data.struct.children[0].id);\n\t\t\t// the occurrence has whole range of children: attributes, image and determination.\n\t\t\tloadAttributes('#cc-2-floral-station', 'occurrence_attribute_value', 'occurrence_attribute_id', 'occurrence_id', data.struct.children[0].id, 'occAttr', false, true);\n\t\t\tfor(i=0; i<data.struct.children[0].children.length; i++){\n\t\t\t\tif(data.struct.children[0].children[i].model == 'occurrence_image'){\n\t\t\t\t\tjQuery('#cc-2-floral-station > input[name=occurrence_image\\:id]').removeAttr('disabled').val(data.struct.children[0].children[i].id);}\n\t\t\t\tif(data.struct.children[0].children[i].model == 'determination'){\n\t\t\t\t\tjQuery('#cc-2-floral-station > input[name=determination\\:id]').removeAttr('disabled').val(data.struct.children[0].children[i].id);}\n\t\t\t}\n\t\t\t// ONLY 1 PARENT, THE LOCATION: TBD ADD CHECK THAT IF ALREADY EXISTS THAT VALUES ARE THE SAME.\n\t\t    var location_id = jQuery('#cc-2-floral-station > input[name=location\\:id]').val();\n       \t\tloadAttributes('#cc-2-floral-station', 'location_attribute_value', 'location_attribute_id', 'location_id', location_id, 'locAttr', true, true);\n\t\t\tfor(i=0; i<data.struct.parents[0].children.length; i++){\n\t\t\t\tif(data.struct.parents[0].children[i].model == 'location_image'){\n\t\t\t\t\tjQuery('#cc-2-floral-station > input[name=location_image\\:id]').removeAttr('disabled').val(data.struct.parents[0].children[i].id);}}\n\t\t\tjQuery('#cc-2').foldPanel();\n\t\t\tif(showSessionsPanel) { jQuery('#cc-3').showPanel(); }\n\t\t\tshowSessionsPanel = true;\n        }  else {\n\t\t\tif(data.error){\n\t\t\t\tvar lastIndex = data.error.lastIndexOf('Validation error'); \n    \t\t\tif (lastIndex != -1 && lastIndex  == (data.error.length - 16)){ \n\t\t\t\t\tif(data.errors){\n\t\t\t\t\t\tif(data.errors['location:centroid_sref']){\n\t\t\t\t\t\t\tvar label = \$('<p/>')\n\t\t\t\t\t\t\t\t.addClass('inline-error')\n\t\t\t\t\t\t\t\t.html(\"" . lang::get('LANG_Invalid_Location') . "\");\n\t\t\t\t\t\t\tlabel.insertBefore('.latLongDiv:first');\n\t\t\t\t\t\t\tmyScrollToError();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\talertIndiciaError(data);\n\t\t}\n\t},\n    complete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n});\n\n\$('#cc-2-valid-button').click(function() {\n\tjQuery('#cc-2-floral-station').submit();\n});\n\n";
        // Sessions.
        $r .= '
<div id="cc-3" class="poll-section">
  <div id="cc-3-title" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all poll-section-title"><span id="cc-3-title-title" >' . lang::get('LANG_Sessions_Title') . '</span>
    <div id="cc-3-mod-button" class="right ui-state-default ui-corner-all mod-button">' . lang::get('LANG_Modify') . '</div>
  </div>
  <div id="cc-3-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-top ui-accordion-content-active poll-section-body">
  </div>
  <div id="cc-3-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active poll-section-footer">
	<div id="cc-3-add-button" class="ui-state-default ui-corner-all add-button">' . lang::get('LANG_Add_Session') . '</div>
    <div id="cc-3-valid-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate_Session') . '</div>
  </div>
</div>
<div style="display:none" />
    <form id="cc-3-delete-session" action="' . iform_ajaxproxy_url($node, 'sample') . '" method="POST">
       <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
       <input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '" />
       <input type="hidden" name="sample:id" value="" />
       <input type="hidden" name="sample:date" value="2010-01-01"/>
       <input type="hidden" name="sample:location_id" value="" />
       <input type="hidden" name="sample:deleted" value="t" />
    </form>
</div>';
        data_entry_helper::$javascript .= "\n\$('#cc-3-delete-session').ajaxForm({ \n\t\tasync: false,\n\t\tdataType:  'json', \n\t\tbeforeSubmit:   function(data, obj, options){\n\t\t\t// Warning this assumes that the data is fixed position:\n\t\t\tdata[4].value = jQuery('#cc-1-collection-details input[name=location\\:id]').val();\n\t\t\tif(data[2].value == '') return false;\n\t\t\t// double check that location id is filled in\n\t\t\tif(data[4].value == ''){\n\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 7: location id not set, so unsafe to delete session.') . "\"});\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// don't have to worry about parent_id\n\t\t\treturn true;\n  \t\t},\n        success:   function(data){\n        \tif(data.success != 'multiple records' || data.outer_table != 'sample')\n\t\t\t\talertIndiciaError(data);\n  \t\t}\n        ,complete: function (){\n  \t\t\tjQuery('.loading-button').removeClass('loading-button');\n  \t\t}\n});\npopulateSessionSelect = function(){\n\tvar insectSessionSelect = jQuery('form#cc-4-main-form > select[name=occurrence\\:sample_id]');\n\tvar value = insectSessionSelect.val();\n\tinsectSessionSelect.empty();\n\t// NB at this point the attributes have been loaded so have full name.\n\t\$('.poll-session-form').each(function(i){\n\t\tjQuery('<option value=\"'+\n\t\t\t\tjQuery(this).children('input[name=sample\\:id]').val()+\n\t\t\t\t'\">'+\n\t\t\t\tjQuery(this).children('input[name=dummy_date]').val()+\n\t\t\t\t' : '+\n\t\t\t\tjQuery(this).children('[name=smpAttr\\:" . $args['start_time_attr_id'] . "],[name^=smpAttr\\:" . $args['start_time_attr_id'] . "\\:]').val()+\n\t\t\t\t' > '+\n\t\t\t\tjQuery(this).children('[name=smpAttr\\:" . $args['end_time_attr_id'] . "],[name^=smpAttr\\:" . $args['end_time_attr_id'] . "\\:]').val()+\n\t\t\t\t'</option>')\n\t\t\t.appendTo(insectSessionSelect);\n\t});\n\tinsectSessionSelect.find('option').each(function(i,obj){\n  \t\tif(i == 0 || jQuery(obj).val() == value)\n\t\t\tinsectSessionSelect.val(insectSessionSelect.find('option').filter(':first').val());\n  \t});\n}\ncompareTimes = function(nameStart, nameEnd, formSel){\n    var controlStart = jQuery(formSel).find('[name='+nameStart+'],[name^='+nameStart+'\\:]');\n    var controlEnd = jQuery(formSel).find('[name='+nameEnd+'],[name^='+nameEnd+'\\:]');\n    var valueStart = controlStart.val().split(':');\n    var valueEnd = controlEnd.val().split(':');\n    var minsDiff = (valueEnd[0]-valueStart[0])*60+(valueEnd[1]-valueStart[1]);\n    if(minsDiff < 0){\n        \$('<p/>').attr({'for': nameEnd}).addClass('inline-error').html(\"" . lang::get('validation_endtime_before_start') . "\").insertBefore(controlEnd);\n\t\treturn false;\n    }\n    // The Flash selection is first, Long second for the protocol: So\n    var isFlashProtocol = jQuery('[name=smpAttr\\:" . $args['protocol_attr_id'] . "],[name^=smpAttr\\:" . $args['protocol_attr_id'] . "\\:]').filter(':first').filter('[checked]').length >0;\n    if(!isFlashProtocol && minsDiff < 20){ // Long Protocol, session must not be less than 20mins\n        \$('<p/>').attr({'for': nameStart}).addClass('inline-error').html(\"" . lang::get('validation_time_less_than_20') . "\").insertBefore(controlStart);\n        \$('<p/>').attr({'for': nameEnd}).addClass('inline-error').html(\"" . lang::get('validation_please_check') . "\").insertBefore(controlEnd);\n\t\treturn false;\n    }\n    if(isFlashProtocol && minsDiff != 20){ // Flash Protocol, session must be exactly 20mins\n        \$('<p/>').attr({'for': nameStart}).addClass('inline-error').html(\"" . lang::get('validation_time_not_20') . "\").insertBefore(controlStart);\n        \$('<p/>').attr({'for': nameEnd}).addClass('inline-error').html(\"" . lang::get('validation_please_check') . "\").insertBefore(controlEnd);\n\t\treturn false;\n    }\n    return true;\n}\nconvertDate = function(dateStr){\n\t// Converts a YYYY-MM-DD date to YYYY/MM/DD so IE can handle it.\n\treturn dateStr.slice(0,4)+'/'+dateStr.slice(5,7)+'/'+dateStr.slice(8,10);\n} \n\ncheckDate = function(name, formSel){\n  var control = jQuery(formSel).find('[name='+name+']');\n  var session = this;\n  var dateError = false;\n  var d2 = new Date(convertDate(control.val()));\n  var two_days=1000*60*61*(24+25); // allows a bit of leaway, plus extra hour for Day light saving transition. (milliSeconds)\n  jQuery('.required').filter('[name=sample:date]').each(function(){\n    var d1 = new Date(convertDate(jQuery(this).val()));\n    if(Math.abs(d1.getTime()-d2.getTime()) > two_days){\n      dateError=true;\n    }\n  });\n  if(dateError){\n    \$('<p/>').attr({'for': name}).addClass('inline-error').html(\"" . lang::get('validation_session_date_error') . "\").insertBefore(control);\n    return false;\n  };\n  return true;\n}\n\nvalidateAndSubmitOpenSessions = function(){\n\tvar valid = true;\n\t// only check the visible forms as rest have already been validated successfully.\n\t\$('.poll-session-form:visible').each(function(i){\n\t\tclearErrors(this);\n   \t\tif (valid && !checkDate('sample\\:date', this)) { valid = false; }\n\t\tif (!jQuery(this).children('input').valid()) { valid = false; }\n\t    if (!validateTime('smpAttr\\:" . $args['start_time_attr_id'] . "', this)) { valid = false; }\n   \t\tif (!validateTime('smpAttr\\:" . $args['end_time_attr_id'] . "', this)) { valid = false; }\n   \t\tif (valid && !compareTimes('smpAttr\\:" . $args['start_time_attr_id'] . "', 'smpAttr\\:" . $args['end_time_attr_id'] . "', this)) { valid = false; }\n   \t\tif (!validateRadio('smpAttr\\:" . $args['sky_state_attr_id'] . "', this)) { valid = false; }\n   \t\tif (!validateRadio('smpAttr\\:" . $args['temperature_attr_id'] . "', this)) { valid = false; }\n   \t\tif (!validateRadio('smpAttr\\:" . $args['wind_attr_id'] . "', this)) { valid = false; }\n   \t\tif (!validateRadio('smpAttr\\:" . $args['shade_attr_id'] . "', this)) { valid = false; }\n   });\n\tif(valid == false) {\n\t\tmyScrollToError();\n\t\treturn false;\n\t};\n\t\$('.poll-session-form:visible').submit();\n\treturn true;\n}\n\naddSession = function(){\n\tsessionCounter = sessionCounter + 1;\n\t// dynamically build the contents of the session block.\n\tvar newSession = jQuery('<div id=\"cc-3-session-'+sessionCounter+'\" class=\"poll-session\"/>')\n\t\t.appendTo('#cc-3-body');\n\tvar newTitle = jQuery('<div class=\"poll-session-title\">" . lang::get('LANG_Session') . " '+sessionCounter+'</div>')\n\t\t.appendTo(newSession);\n\tvar newModButton = jQuery('<div class=\"right ui-state-default ui-corner-all mod-button\">" . lang::get('LANG_Modify') . "</div>')\n\t\t.appendTo(newTitle).hide();\n\tvar newDeleteButton = jQuery('<div class=\"right ui-state-default ui-corner-all delete-button\">" . lang::get('LANG_Delete_Session') . "</div>')\n\t\t.appendTo(newTitle);\t\n\tnewModButton.click(function() {\n\t\tif(!validateAndSubmitOpenSessions()) return false;\n\t\tvar session=\$(this).parents('.poll-session');\n\t\tsession.show();\n\t\tsession.children().show();\n\t\tsession.children(':first').children(':first').hide(); // this is the mod button itself\n    });\n    var formContainer = jQuery('<div />').appendTo(newSession);\n    var newForm = jQuery('<form action=\"" . iform_ajaxproxy_url($node, 'sample') . "\" method=\"POST\" class=\"poll-session-form\" />').appendTo(formContainer);\n\tjQuery('<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />').appendTo(newForm);\n\tjQuery('<input type=\"hidden\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />').appendTo(newForm);\n\tjQuery('<input type=\"hidden\" name=\"sample:parent_id\" />').appendTo(newForm).val(jQuery('#cc-1-collection-details > input[name=sample\\:id]').val());\n\tjQuery('<input type=\"hidden\" name=\"sample:location_id\" />').appendTo(newForm).val(jQuery('#cc-1-collection-details > input[name=location\\:id]').val());\n\tjQuery('<input type=\"hidden\" name=\"sample:id\" value=\"\" disabled=\"disabled\" />').appendTo(newForm);\n";
        if ($use_help) {
            data_entry_helper::$javascript .= "\n\tvar helpDiv = jQuery('<div class=\"right ui-state-default ui-corner-all help-button\">" . lang::get('LANG_Help_Button') . "</div>');\n\thelpDiv.click(function(){\n\t\t" . $args['help_function'] . "(" . $args['help_session_arg'] . ");\n\t});\n\thelpDiv.appendTo(newForm);";
        }
        // we have to be careful with the dates: Indicia supplies dates as YYYY-MM-DD, but this is not ready understood by the IE JS Date, which is OK with YYYY/MM/DD.
        // We keep the YYYY-MM-DD internally for consistency.
        data_entry_helper::$javascript .= "\n\tvar dateID = 'cc-3-session-date-'+sessionCounter;\n\tvar dateAttr = '<label for=\"'+dateID+'\">" . lang::get('LANG_Date') . " :</label><input type=\"text\" size=\"10\" class=\"vague-date-picker required\" id=\"'+dateID+'\" name=\"dummy_date\" value=\"" . lang::get('click here') . "\" /> ';\n\tdateAttr = dateAttr + '<input type=\"hidden\" id=\"real-'+dateID+'\" name=\"sample:date\" value=\"\" class=\"required\"/> ';\n    jQuery(dateAttr).appendTo(newForm);\n\tjQuery('#'+dateID).datepicker({\n\t\tdateFormat : 'dd/mm/yy',\n\t\tconstrainInput: false,\n\t\tmaxDate: '0',\n\t\taltField : '#real-'+dateID,\n\t\taltFormat : 'yy-mm-dd'\n\t});\n    jQuery('" . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['start_time_attr_id']], $defAttrOptions)) . "').appendTo(newForm);\n\tjQuery('" . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['end_time_attr_id']], $defAttrOptions)) . "').appendTo(newForm);\n\tjQuery('" . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['sky_state_attr_id']], $defNRAttrOptions)) . "').appendTo(newForm);\n\tjQuery('" . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['temperature_attr_id']], $defNRAttrOptions)) . "').appendTo(newForm);\n\tjQuery('" . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['wind_attr_id']], $defNRAttrOptions)) . "').appendTo(newForm);\n\tjQuery('" . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['shade_attr_id']], array_merge($defNRAttrOptions, array('default' => '-1')))) . "').appendTo(newForm);\n\tnewDeleteButton.click(function() {\n\t\tvar container = \$(this).parent().parent();\n\t\tjQuery('#cc-3-delete-session').find('[name=sample\\:id]').val(container.find('[name=sample\\:id]').val());\n\t\tjQuery('#cc-3-delete-session').find('[name=sample\\:date]').val(container.find('[name=sample\\:date]').val());\n\t\tjQuery('#cc-3-delete-session').find('[name=sample\\:location_id]').val(container.find('[name=sample\\:location_id]').val());\n\t\tif(container.find('[name=sample\\:id]').filter('[disabled]').length == 0){\n\t\t\tjQuery(this).addClass('loading-button');\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n\t\t\t\t\t\"?mode=json&view=detail&reset_timeout=true&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\t\t\"&sample_id=\"+container.find('[name=sample\\:id]').val()+\"&deleted=f&callback=?\", function(insectData) {\n\t\t\t\tif(!(insectData instanceof Array)){\n   \t\t\t\t\talertIndiciaError(insectData);\n   \t\t\t\t} else if (insectData.length>0) {\n\t\t\t\t\tjQuery('.loading-button').removeClass('loading-button');\n\t\t\t\t\talert(\"" . lang::get('LANG_Cant_Delete_Session') . "\");\n\t\t\t\t} else if(confirm(\"" . lang::get('LANG_Confirm_Session_Delete') . "\")){\n\t\t\t\t\tjQuery('#cc-3-delete-session').submit();\n\t\t\t\t\tcontainer.remove();\n\t\t\t\t\tcheckSessionButtons();\n\t\t\t\t}\n\t\t\t});\n\t\t} else if(confirm(\"" . lang::get('LANG_Confirm_Session_Delete') . "\")){\n\t\t\tcontainer.remove();\n\t\t\tcheckSessionButtons();\n\t\t}\n    });\n    newForm.ajaxForm({\n   \t\tasync: false,\n    \tdataType:  'json',\n    \tbeforeSubmit:   function(data, obj, options){\n\t\t\t// double check that location id and sample id are filled in\n\t\t\tif(jQuery('#cc-1-collection-details input[name=location\\:id]').val() == ''){\n\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 8: location id not set, so unsafe to save session.') . "\"});\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(jQuery('#cc-1-collection-details input[name=sample\\:id]').val() == ''){\n\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 9: sample id not set, so unsafe to save session.') . "\"});\n\t\t\t\treturn false;\n\t\t\t}\n\t    \tvar valid = true;\n    \t\tclearErrors(obj);\n    \t\tif (!obj.find('input').valid()) {\n    \t\t\tvalid = false; }\n    \t\tif (!validateRadio('smpAttr\\:" . $args['sky_state_attr_id'] . "', obj)) { valid = false; }\n   \t\t\tif (!validateRadio('smpAttr\\:" . $args['temperature_attr_id'] . "', obj)) { valid = false; }\n   \t\t\tif (!validateRadio('smpAttr\\:" . $args['wind_attr_id'] . "', obj)) { valid = false; }\n   \t\t\tif (!validateRadio('smpAttr\\:" . $args['shade_attr_id'] . "', obj)) { valid = false; }\n   \t\t\tdata[2].value = jQuery('#cc-1-collection-details > input[name=sample\\:id]').val();\n\t\t\tdata[3].value = jQuery('#cc-1-collection-details > input[name=location\\:id]').val();\n\t\t\tjQuery('#cc-3-valid-button').addClass('loading-button');\n\t\t\tif(!valid) myScrollToError();\n\t\t\treturn valid;\n\t\t},\n   \t    success:   function(data, status, form){\n   \t    \tvar thisSession = form.parents('.poll-session');\n    \t\tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n   \t    \t    form.children('input[name=sample\\:id]').removeAttr('disabled').val(data.outer_id);\n   \t    \t    loadAttributes(form, 'sample_attribute_value', 'sample_attribute_id', 'sample_id', data.outer_id, 'smpAttr', true, true);\n\t\t\t\tthisSession.show();\n\t\t\t\tthisSession.children(':first').show().find('*').show();\n\t\t\t\tthisSession.children().not(':first').hide();\n  \t\t\t} else \n\t        \talertIndiciaError(data);\n  \t\t},\n        complete: function (){\n  \t\t\tjQuery('.loading-button').removeClass('loading-button');\n  \t\t}\n\t});\n\tnewSession.find('.deh-required').remove();\n    return(newSession);\n};\n\nvalidateSessionsPanel = function(){\n\tif(jQuery('#cc-3:visible').length == 0) return true; // panel is not visible so no data to fail validation.\n\tif(jQuery('#cc-3').find('.poll-section-body:visible').length == 0) return true; // body hidden so data already been validated successfully.\n\tvar openSession = jQuery('.poll-session-form:visible');\n\tif(openSession.length > 0){\n\t\tif(jQuery('input[name=sample\\:id]', openSession).val() == '' &&\n\t\t\t\tjQuery('input[name=sample\\:date]', openSession).val() == '' &&\n\t\t\t\tjQuery('[name=smpAttr\\:" . $args['start_time_attr_id'] . "],[name^=smpAttr\\:" . $args['start_time_attr_id'] . "\\:]', openSession).val() == '' &&\n\t\t\t\tjQuery('[name=smpAttr\\:" . $args['end_time_attr_id'] . "],[name^=smpAttr\\:" . $args['end_time_attr_id'] . "\\:]', openSession).val() == '' &&\n\t\t\t\tjQuery('[name=smpAttr\\:" . $args['sky_state_attr_id'] . "],[name^=smpAttr\\:" . $args['sky_state_attr_id'] . "\\:]', openSession).filter('[checked]').length == 0 &&\n    \t\t\tjQuery('[name=smpAttr\\:" . $args['temperature_attr_id'] . "],[name^=smpAttr\\:" . $args['temperature_attr_id'] . "\\:]', openSession).filter('[checked]').length == 0 &&\n    \t\t\tjQuery('[name=smpAttr\\:" . $args['wind_attr_id'] . "],[name^=smpAttr\\:" . $args['wind_attr_id'] . "\\:]', openSession).filter('[checked]').length == 0 &&\n    \t\t\tjQuery('[name=smpAttr\\:" . $args['shade_attr_id'] . "],[name^=smpAttr\\:" . $args['shade_attr_id'] . "\\:]', openSession).filter('[checked]').length == 0) {\n    \t\tjQuery('#cc-3').foldPanel();\n\t\t\treturn true;\n\t\t}\n\t}\n\t// not putting in an empty data set check here - user can delete the session if needed, and there must be at least one.\n\tif(!validateAndSubmitOpenSessions()) return false;\n\tjQuery('#cc-3').foldPanel();\n\tpopulateSessionSelect();\n\treturn true;\n};\njQuery('#cc-3-valid-button').click(function(){\n\tif(!validateAndSubmitOpenSessions()) return;\n\tjQuery('#cc-3').foldPanel();\n\tjQuery('#cc-4').showPanel();\n\tpopulateSessionSelect();\n});\njQuery('#cc-3-add-button').click(function(){\n\tif(!validateAndSubmitOpenSessions()) return;\n\taddSession();\n\tcheckSessionButtons();\n});\n\njQuery('.mod-button').click(function() {\n\t// first close all the other panels, ensuring any data is saved.\n\tif(!validateCollectionPanel() || !validateStationPanel() || !validateSessionsPanel() || !validateInsectPanel())\n\t\treturn;\n\tjQuery('#cc-5').hidePanel();\n\tjQuery(this).parents('.poll-section-title').parent().unFoldPanel(); //slightly complicated because cc-1 contains the rest.\n});\n\n";
        $extraParams = $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order', 'allow_data_entry' => 't');
        $species_ctrl_args = array('label' => lang::get('LANG_Insect_Species'), 'fieldname' => 'insect:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'listCaptionSpecialChars' => true, 'valueField' => 'id', 'columns' => 2, 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $extraParams);
        $checkOptions['labelClass'] = 'checkbox-label';
        $r .= '
<div id="cc-4" class="poll-section">
  <div id="cc-4-title" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all poll-section-title">' . lang::get('LANG_Photos') . '
    <div id="cc-4-mod-button" class="right ui-state-default ui-corner-all mod-button">' . lang::get('LANG_Modify') . '</div>
  </div>
  <div id="cc-4-photo-reel" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-top ui-accordion-content-active photoReelContainer" >
    <div class="photo-blurb">' . lang::get('LANG_Photo_Blurb') . '</div>
    <div class="blankPhoto thumb currentPhoto"></div>
  </div>
  <div id="cc-4-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active poll-section-body">  
    <div id="cc-4-insect">
      <div id="cc-4-insect-title">' . lang::get('LANG_Upload_Insect') . '</div>
      <form id="cc-4-insect-upload" enctype="multipart/form-data" action="' . iform_ajaxproxy_url($node, 'media') . '" method="POST">
    	<input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
    	<input name="upload_file" type="file" class="required" />
        <input type="submit" value="' . lang::get('LANG_Upload') . '" class="btn-submit" />
 	    <div id="cc-4-insect-image" class="poll-image"></div>
      </form>
      <div id="cc-4-insect-identify" class="poll-dummy-form">
 	    <div class="id-tool-group">
          ' . iform_pollenators::help_button($use_help, "insect-help-button", $args['help_function'], $args['help_insect_arg']) . '
          <p><strong>' . lang::get('LANG_Identify_Insect') . '</strong></p>
          <input type="hidden" id="insect:taxon_details" name="insect:taxon_details" />
          <input type="hidden" name="insect:determination_type" value="A" />  
		  <label for="insect-id-button">' . lang::get('LANG_Insect_ID_Key_label') . ' :</label><span id="insect-id-button" class="ui-state-default ui-corner-all poll-id-button" >' . lang::get('LANG_Launch_ID_Key') . '</span>
		  <span id="insect-id-cancel" class="ui-state-default ui-corner-all poll-id-cancel" >' . lang::get('LANG_Cancel_ID') . '</span>
		  <p id="insect_taxa_list"></p> 
 	    </div>
 	    <div class="id-later-group">
 	      <label for="id-insect-later" class="follow-on">' . lang::get('LANG_ID_Insect_Later') . ' </label><input type="checkbox" id="id-insect-later" name="id-insect-later" />
 	    </div>
 	    <div class="id-specified-group">
 	      ' . data_entry_helper::select($species_ctrl_args) . '
          <label for="insect:taxon_extra_info" class="follow-on">' . lang::get('LANG_ID_More_Precise') . ' </label> 
    	  <input type="text" id="insect:taxon_extra_info" name="insect:taxon_extra_info" class="taxon-info" />
        </div>
      </div>
 	  <div class="id-comment">
        <label for="insect:comment" >' . lang::get('LANG_ID_Comment') . ' </label>
        <textarea id="insect:comment" name="insect:comment" class="taxon-comment" rows="3" ></textarea>
      </div>
    </div>
    <div class="poll-break"></div> 
 	<form id="cc-4-main-form" action="' . iform_ajaxproxy_url($node, 'occurrence') . '" method="POST" >
    	<input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" id="occurrence_image:path" name="occurrence_image:path" value="" />
    	<input type="hidden" id="occurrence:record_status" name="occurrence:record_status" value="C" />
        <input type="hidden" name="occurrence:use_determination" value="Y"/>    
        <input type="hidden" name="determination:taxa_taxon_list_id" value=""/> 
        <input type="hidden" name="determination:taxon_details" value=""/>  	
        <input type="hidden" name="determination:taxon_extra_info" value=""/>  	
        <input type="hidden" name="determination:comment" value=""/>  	
    	<input type="hidden" name="determination:determination_type" value="A" /> 
        <input type="hidden" name="determination:cms_ref" value="' . $uid . '" />
    	<input type="hidden" name="determination:email_address" value="' . $email . '" />
    	<input type="hidden" name="determination:person_name" value="' . $username . '" /> 
    	<input type="hidden" id="occurrence:id" name="occurrence:id" value="" disabled="disabled" />
	    <input type="hidden" id="determination:id" name="determination:id" value="" disabled="disabled" />
	    <input type="hidden" id="occurrence_image:id" name="occurrence_image:id" value="" disabled="disabled" />
        <input type="hidden" id="insect_picture_camera_attr" name="occAttr:' . $args['occurrence_picture_camera_attr_id'] . '" value="" />
        <input type="hidden" id="insect_picture_datetime_attr" name="occAttr:' . $args['occurrence_picture_datetime_attr_id'] . '" value="" />
	    <label for="occurrence:sample_id">' . lang::get('LANG_Session') . ' :</label>
	    <select id="occurrence:sample_id" name="occurrence:sample_id" value="" class="required" /></select>
	    ' . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence:comment')) . str_replace("\n", "", data_entry_helper::outputAttribute($occurrence_attributes[$args['number_attr_id']], $defNRAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($occurrence_attributes[$args['foraging_attr_id']], $checkOptions)) . '
	<div id="Foraging_Confirm"><label>' . lang::get('Foraging_Confirm') . '</label><div class="control-box "><nobr><span><input type="radio" name="dummy_foraging_confirm" value="0" checked="checked"  /><label>' . lang::get('No') . '</label></span></nobr> &nbsp; <nobr><span><input type="radio" name="dummy_foraging_confirm" value="1" /><label>' . lang::get('Yes') . '</label></span></nobr></div></div></form><br />
    <div class="button-container">
      <span id="cc-4-valid-insect-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate_Insect') . '</span>
      <span id="cc-4-delete-insect-button" class="ui-state-default ui-corner-all delete-button">' . lang::get('LANG_Delete_Insect') . '</span>
    </div>
  </div>
  <div id="cc-4-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active poll-section-footer">
    <div id="cc-4-valid-photo-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate_Photos') . '</div>
  </div>
</div>
<div style="display:none" />
    <form id="cc-4-delete-insect" action="' . iform_ajaxproxy_url($node, 'occurrence') . '" method="POST">
       <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
       <input type="hidden" name="occurrence:use_determination" value="Y"/>    
       <input type="hidden" name="occurrence:id" value="" />
       <input type="hidden" name="occurrence:sample_id" value="" />
       <input type="hidden" name="occurrence:deleted" value="t" />
    </form>
</div>';
        data_entry_helper::$javascript .= "\njQuery('#Foraging_Confirm').hide();\njQuery('[name=occAttr\\:" . $args['foraging_attr_id'] . "],[name^=occAttr\\:" . $args['foraging_attr_id'] . ":]').change(function(){\n\tjQuery('[name=dummy_foraging_confirm]').filter('[value=0]').attr('checked',true);\n\tcheckForagingStatus(false);\n});\n\ninsectIDstruc = {\n\ttype: 'insect',\n\tselector: '#cc-4-insect-identify',\n\tmainForm: '#cc-4-main-form',\n\tuseKey: true,\n\tstoredTaxaList: [],\n\ttimeOutTimer: null,\n\tpollTimer: null,\n\tsessionID: '',\n\tinvokeURL: '" . $args['ID_tool_insect_url'] . "',\n\tpollURL: '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['ID_tool_insect_poll_dir']) . "',\n\tname: 'insectIDstruc',\n\ttaxaList: insectTaxa\n};\n\njQuery('#insect-id-button').click(function(){\n\tidButtonPressed(insectIDstruc);\n});\n\njQuery('#insect-id-cancel').click(function(){\n\tpollReset(insectIDstruc);\n});\njQuery('#insect-id-cancel').hide();\n\njQuery('#cc-4-insect-identify select[name=insect\\:taxa_taxon_list_id]').change(function(){\n\tpollReset(insectIDstruc);\n\ttaxonChosen(insectIDstruc);\n});\njQuery('#id-insect-later').change(function (){\n\tpollReset(insectIDstruc);\n\tidLater(insectIDstruc);\n});\n\n// Insect upload picture form.\n\$('#cc-4-insect-upload').ajaxForm({ \n\t\tasync: false,\n\t\tdataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n        \tif(jQuery('#cc-4-insect-upload input[name=upload_file]').val() == '')\n        \t\treturn false;\n        \t\$('#cc-4-insect-image').empty();\n        \t\$('#cc-4-insect-image').addClass('loading');\n        \tjQuery('form#cc-4-main-form input[name=occurrence_image\\:path]').val('');\n        },\n        success:   function(data){\n        \tif(data.success == true){\n\t        \t// There is only one file\n\t        \tjQuery('form#cc-4-main-form input[name=occurrence_image\\:path]').val(data.files[0].filename);\n\t        \tjQuery('#insect_picture_camera_attr').val(data.files[0].EXIF_Camera_Make);\n\t        \tjQuery('#insect_picture_datetime_attr').val(data.files[0].EXIF_DateTime);\n\t        \tinsertImage('med-'+data.files[0].filename, jQuery('#cc-4-insect-image'), " . $args['Insect_Image_Ratio'] . ");\n\t\t\t\tjQuery('#cc-4-insect-upload input[name=upload_file]').val('');\n\t\t\t}  else\n\t\t\t\talertIndiciaError(data);\n  \t\t},\n  \t\tcomplete: function(){\n\t\t\t\$('#cc-4-insect-image').removeClass('loading');\n  \t\t}\n});\n\n\$('#cc-4-main-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n    beforeSubmit:   function(data, obj, options){\n    \tvar valid = true;\n    \tclearErrors('form#cc-4-main-form');\n    \tclearErrors('#cc-4-insect-identify');\n    \tif (!jQuery('form#cc-4-main-form > input').valid()) { valid = false; }\n\t\tif (!validateRequiredField('occurrence\\:sample_id', 'form#cc-4-main-form')) { valid = false; }\n\t\tif (!validateRadio('occAttr\\:" . $args['number_attr_id'] . "', obj)) { valid = false; }\n    \tif(data[1].value == '' ){\n    \t\tmyScrollTo('#cc-4-insect-upload');\n\t\t\talert(\"" . lang::get('LANG_Must_Provide_Insect_Picture') . "\");\n\t\t\tvalid = false;\n\t\t}\n\t\tif (jQuery('#id-insect-later').attr('checked') == ''){\n\t\t\tprepPhotoReelForNew(false, jQuery('#cc-4-main-form').find('[name=occurrence\\:id]').val());\n\t\t\tdata[findID('determination:taxa_taxon_list_id', data)].value = jQuery('#cc-4-insect-identify select[name=insect\\:taxa_taxon_list_id]').val();\n\t\t\tdata[findID('determination:taxon_details', data)].value = jQuery('#cc-4-insect-identify [name=insect\\:taxon_details]').val();\n\t\t\tdata[findID('determination:taxon_extra_info', data)].value = jQuery('#cc-4-insect-identify [name=insect\\:taxon_extra_info]').val();\n\t\t\tdata[findID('determination:comment', data)].value = jQuery('[name=insect\\:comment]').val();\n\t\t\tdata[findID('determination:determination_type', data)].value = jQuery('#cc-4-insect-identify [name=insect\\:determination_type]').val();\n\t\t\tif (jQuery('#cc-4-insect-identify [name=insect\\:taxon_details]').val() == ''){\n\t\t\t\tif (!validateRequiredField('insect\\:taxa_taxon_list_id', '#cc-4-insect-identify')) {\n\t\t\t\t\tvalid = false;\n  \t\t\t\t} else {\n\t\t\t\t\tdata.push({name: 'determination:taxa_taxon_list_id_list[]', value: ''});\n  \t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvar toolValues = insectIDstruc.storedTaxaList;\n\t\t\t\tfor(var i = 0; i<toolValues.length; i++){\n\t\t\t\t\tdata.push({name: 'determination:taxa_taxon_list_id_list[]', value: toolValues[i]});\n\t\t\t\t}\t\t\t\n\t\t\t}\n\t\t} else {\n\t\t\tprepPhotoReelForNew(true, jQuery('#cc-4-main-form').find('[name=occurrence\\:id]').val());\n\t\t\tdata.splice(4,8); // remove determination entries: TODO expand to be explicit - see flowers\n\t\t}\n   \t\tif ( valid == false ) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n\t\tjQuery('#cc-4-valid-insect-button').addClass('loading-button');\n\t\treturn true;\n\t},\n    success:   function(data){\n       \tif(data.success == 'multiple records' && data.outer_table == 'occurrence'){\n       \t\taddNewToPhotoReel(data.outer_id);\n\t\t\twindow.scroll(0,0);\n        } else\n\t\t\talertIndiciaError(data);\n\t},\n    complete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n});\n\nvalidateInsectPanel = function(){\n\tif(jQuery('#cc-4:visible').length == 0) return true; // panel is not visible so no data to fail validation.\n\tif(jQuery('#cc-4-body:visible').length == 0) return true; // body hidden so data already been validated successfully.\n\tif(!validateInsect()){ return false; }\n\tclearInsect();\n  \tjQuery('#cc-4').foldPanel();\n\treturn true;\n};\n\nclearInsect = function(){\n\tjQuery('#cc-4-main-form').resetForm();\n\tinsectIDstruc.storedTaxaList = [];\n\tjQuery('#insect_taxa_list').empty();\n\tjQuery('[name=insect\\:taxa_taxon_list_id],[name=insect\\:taxon_extra_info],[name=insect\\:comment],[name=insect\\:taxon_details]').val('');\n    jQuery('[name=insect\\:determination_type]').val('A'); \n\tjQuery('#id-insect-later').removeAttr('checked').removeAttr('disabled');\n    jQuery('#cc-4-main-form').find('[name=determination\\:cms_ref]').val('" . $uid . "');\n    jQuery('#cc-4-main-form').find('[name=determination\\:email_address]').val('" . $email . "');\n    jQuery('#cc-4-main-form').find('[name=determination\\:person_name]').val('" . $username . "'); \n    jQuery('#cc-4-main-form').find('[name=determination\\:determination_type]').val('A'); \n    jQuery('#cc-4-main-form').find('[name=occurrence_image\\:path]').val('');\n\tjQuery('#cc-4-main-form').find('[name=occurrence\\:id],[name=occurrence_image\\:id],[name=determination\\:id]').val('').attr('disabled', 'disabled');\n\t// First rename, to be safe. Then add [] to multiple choice checkboxes.\n\tjQuery('#cc-4-main-form').find('[name^=occAttr\\:]').each(function(){\n\t\tvar name = jQuery(this).attr('name').split(':');\n\t\tif(name[1].indexOf('[]') > 0) name[1] = name[1].substr(0, name[1].indexOf('[]'));\n\t\tjQuery(this).attr('name', 'occAttr:'+name[1]);\n\t});\n\tjQuery('#cc-4-main-form').find('[name^=occAttr\\:]').filter(':checkbox').removeAttr('checked').each(function(){\n\t\tvar myName = jQuery(this).attr('name').split(':');\n\t\tvar similar = jQuery('[name=occAttr\\:'+name[1]+'],[name=occAttr\\:'+name[1]+'\\[\\]]').filter(':checkbox');\n\t\tif(similar.length > 1) jQuery(this).attr('name', 'occAttr:'+name[1]+'[]');\n\t});\n    jQuery('#cc-4-insect-image').empty();\n    populateSessionSelect();\n    jQuery('#Foraging_Confirm').hide();\n    jQuery('[name=dummy_foraging_confirm]').filter('[value=0]').attr('checked',true);\n    jQuery('#cc-4').find('.inline-error').remove();\n\tjQuery('.currentPhoto').removeClass('currentPhoto');\n\tjQuery('.blankPhoto').addClass('currentPhoto');\n};\n\nloadInsect = function(id){\n\tclearInsect();\n\tjQuery('form#cc-4-main-form > input[name=occurrence\\:id]').removeAttr('disabled').val(id);\n\tloadAttributes('form#cc-4-main-form', 'occurrence_attribute_value', 'occurrence_attribute_id', 'occurrence_id', id, 'occAttr', true, true);\n\tloadImage('occurrence_image', 'occurrence_id', 'occurrence\\:id', id, '#cc-4-insect-image', " . $args['Insect_Image_Ratio'] . ", true);\n\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" + id +\n          \"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&callback=?\", function(data) {\n\t    if(!(data instanceof Array)){\n   \t\t\talertIndiciaError(data);\n   \t\t} else if (data.length>0) {\n\t        jQuery('form#cc-4-main-form > [name=occurrence\\:sample_id]').val(data[0].sample_id);\n\t\t\tjQuery('form#cc-4-main-form > textarea[name=occurrence\\:comment]').val(data[0].comment);\n  \t\t} else {\n   \t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 10: no insect data available for id ') . "\"+id});\n  \t\t}\n\t});\n\t\$.getJSON(\"" . $svcUrl . "/data/determination?occurrence_id=\" + id +\n          \"&mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&orderby=id&deleted=f&callback=?\", function(data) {\n        if(!(data instanceof Array)){\n   \t\t\talertIndiciaError(data);\n   \t\t} else loadDetermination(data, insectIDstruc);\n\t});\t\n\tjQuery('.currentPhoto').removeClass('currentPhoto');\n\tjQuery('[occId='+id+']').addClass('currentPhoto');\n}\n\nprepPhotoReelForNew = function(notID, id){\n\tvar container;\n\tif(id == '')\n\t\tcontainer = jQuery('<div/>').addClass('thumb').insertBefore('.blankPhoto').attr('occId', 'new');\n\telse\n\t\tcontainer = jQuery('[occId='+id+']').empty();\n\tif(notID){\n\t\tvar img = new Image();\n\t\tvar src = '" . $base . drupal_get_path('module', 'iform') . "/client_helpers/prebuilt_forms/images/boundary-unknown.png';\n\t\timg = jQuery(img).attr('src', src).attr('width', container.width()).attr('height', container.height()).addClass('thumb-image').addClass('unidentified').appendTo(container);\n\t}\n}\n\naddNewToPhotoReel = function(occId){\n\tvar container = jQuery('[occId='+occId+']');\n\tif(container.length == 0) {\n\t\tcontainer = jQuery('[occId=new]');\n\t\tcontainer.attr('occId', occId.toString()).click(function () {\n\t\t    setInsect(occId)});\n\t}\n\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_image\" +\n\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\"&occurrence_id=\" + occId + \"&callback=?\", function(imageData) {\n\t\tif(!(imageData instanceof Array)){\n\t\t\talertIndiciaError(imageData);\n\t\t} else if (imageData.length>0) {\n\t\t\tvar img = new Image();\n\t\t\tvar container = jQuery('[occId='+imageData[0].occurrence_id+']');\n\t\t\tif(container.children().length>0){\n\t\t\t\tvar background = '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "thumb-'+imageData[0].path;\n\t\t\t\tcontainer.children().css('background', 'url('+background+')').css('background-size','100% 100%');\n\t\t\t} else {\n\t\t\t\tjQuery(img).attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "thumb-'+imageData[0].path)\n\t\t\t\t    .attr('width', container.width()).attr('height', container.height()).addClass('thumb-image').appendTo(container);\n\t\t\t}\n\t\t} else {\n\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 11: image could not be loaded into photoreel for insect ') . "\"+occId});\n\t\t}});\n}\n\naddExistingToPhotoReel = function(occId){\n\tvar container = jQuery('[occId='+occId+']');\n\tif(container.length == 0)\n\t\tcontainer = jQuery('<div/>').addClass('thumb').insertBefore('.blankPhoto').attr('occId', occId.toString()).click(function () {\n\t\t    setInsect(occId)});\n\telse\n\t\tcontainer.empty();\n\t// we use the presence of the text to determine whether the \n\t// insect has been identified or not. NB an insect tagged as unidentified (type = 'X') has actually been through the ID\n\t// process, so is not unidentified!!!\n\tjQuery.ajax({ \n        type: \"GET\", \n        url: \"" . $svcUrl . "/data/determination\" + \n    \t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n    \t\t\"&reset_timeout=true&occurrence_id=\" + occId + \"&orderby=id&deleted=f&callback=?\", \n        success: function(detData) {\n\t    \tif(!(detData instanceof Array)){\n   \t\t\t\talertIndiciaError(detData);\n   \t\t\t} else if (detData.length>0) {\n\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_image\" +\n\t\t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\t\t\t\"&occurrence_id=\" + occId + \"&callback=?\", function(imageData) {\n\t\t\t\t\tif(!(imageData instanceof Array)){\n\t\t\t\t\t\talertIndiciaError(imageData);\n\t\t\t\t\t} else if (imageData.length>0) {\n\t\t\t\t\t\tvar img = new Image();\n\t\t\t\t\t\tvar container = jQuery('[occId='+imageData[0].occurrence_id+']');\n\t\t\t\t\t\tjQuery(img).attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "thumb-'+imageData[0].path)\n\t\t\t    \t\t\t.attr('width', container.width()).attr('height', container.height()).addClass('thumb-image').appendTo(container);\n\t\t\t\t\t} else {\n\t\t\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 12: image could not be loaded into photoreel for existing insect ') . "\"+occId});\n\t\t\t\t\t}\n\t\t\t\t});\n\t    \t} else { // is conceivable that insect is not identified yet -> does not have determinations\n\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_image\" +\n\t\t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\t\t\t\"&occurrence_id=\" + occId + \"&callback=?\", function(imageData) {\n\t\t\t\t\tif(!(imageData instanceof Array)){\n\t\t\t\t\t\talertIndiciaError(imageData);\n\t\t\t\t\t} else if (imageData.length>0) {\n\t\t\t\t\t\tvar img = new Image();\n\t\t\t\t\t\tvar container = jQuery('[occId='+imageData[0].occurrence_id+']');\n\t\t\t\t\t\tvar src = '" . $base . drupal_get_path('module', 'iform') . "/client_helpers/prebuilt_forms/images/boundary-unknown.png';\n\t\t\t\t\t\tvar background = '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "thumb-'+imageData[0].path;\n\t\t\t\t\t\timg = jQuery(img).attr('src', src).attr('width', container.width()).attr('height', container.height()).addClass('thumb-image').addClass('unidentified').appendTo(container);\n\t\t\t\t\t\timg.css('background', 'url('+background+')').css('background-size','100% 100%');\n\t\t\t\t\t} else {\n\t\t\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 12: image could not be loaded into photoreel for existing insect ') . "\"+occId});\n\t\t\t\t\t}\n\t\t\t\t});\n\t    \t}\n  \t\t}, \n    \tdataType: 'json' \n    });\n}\n\nsetInsect = function(id){\n\t// first close all the other panels, ensuring any data is saved.\n\tif(!validateCollectionPanel() || !validateStationPanel() || !validateSessionsPanel())\n\t\treturn;\n\tjQuery('#cc-5').hidePanel();\n\n\tif(jQuery('#cc-4-body:visible').length == 0)\n\t\tjQuery('div#cc-4').unFoldPanel();\n\telse\n\t\tif(!validateInsect()){ return ; }\n\tloadInsect(id);\n};\n\nsetNoInsect = function(){\n\t// first close all the other panels, ensuring any data is saved.\n\tif(!validateCollectionPanel() || !validateStationPanel() || !validateSessionsPanel())\n\t\treturn;\n\t\t\n\tif(jQuery('#cc-4-body:visible').length == 0)\n\t\tjQuery('div#cc-4').unFoldPanel();\n\telse\n\t\tif(!validateInsect()){ return ; }\n\tclearInsect();\n};\n\njQuery('.blankPhoto').click(setNoInsect);\n\n// TODO separate photoreel out into own js\nvalidateInsect = function(){\n    clearErrors('form#cc-4-main-form');\n    clearErrors('#cc-4-insect-identify');\n    if(jQuery('form#cc-4-main-form > input[name=occurrence\\:id]').val() == '' &&\n\t\t\tjQuery('form#cc-4-main-form > input[name=occurrence_image\\:path]').val() == '' &&\n\t\t\tjQuery('[name=insect\\:taxa_taxon_list_id]').val() == '' &&\n\t\t\tjQuery('[name=insect\\:taxon_details]').val() == '' &&\n\t\t\tjQuery('[name=insect\\:comment]').val() == '' &&\n\t\t\tjQuery('[name=insect\\:taxon_extra_info]').val() == '' &&\n\t\t\tjQuery('form#cc-4-main-form > textarea[name=occurrence\\:comment]').val() == '' &&\n\t\t\tjQuery('[name=occAttr\\:" . $args['number_attr_id'] . "],[name^=occAttr\\:" . $args['number_attr_id'] . "\\:]').filter('[checked]').length == 0){\n\t\treturn true;\n\t}\n\tvar valid = true;\n    if (!jQuery('form#cc-4-main-form > input').valid()) { valid = false; }\n  \tif (!validateRadio('occAttr\\:" . $args['number_attr_id'] . "', 'form#cc-4-main-form')) { valid = false; }\n\tif (jQuery('#id-insect-later').attr('checked') == '' && jQuery('[name=insect\\:taxon_details]').val() == ''){\n\t\tif (!validateRequiredField('insect\\:taxa_taxon_list_id', '#cc-4-insect-identify')) { valid = false; }\n\t}\n \tif (!validateRequiredField('occurrence\\:sample_id', 'form#cc-4-main-form')) { valid = false; }\n\tif(jQuery('form#cc-4-main-form input[name=occurrence_image\\:path]').val() == ''){\n    \tmyScrollTo('#cc-4-insect-upload');\n\t\talert(\"" . lang::get('LANG_Must_Provide_Insect_Picture') . "\");\n\t\tvalid = false;\n\t}\n\tif(jQuery('[name=occAttr\\:" . $args['foraging_attr_id'] . "],[name^=occAttr\\:" . $args['foraging_attr_id'] . ":]').filter('[checked]').val()==1){\n\t\tif(jQuery('[name=dummy_foraging_confirm]').filter('[checked]').val()==0){\n\t\t\tvalid = false;\n\t        var label = \$('<p/>')\n\t\t\t\t.attr({'for': 'dummy_foraging_confirm'})\n\t\t\t\t.addClass('inline-error')\n\t\t\t\t.html(\"" . lang::get('Foraging_Validation') . "\");\n\t\t\tlabel.appendTo(jQuery('#Foraging_Confirm'));\n\t\t}\n\t}\n\tif(valid == false) {\n\t\tmyScrollToError();\n\t\treturn false;\n\t}\n\tjQuery('form#cc-4-main-form').submit();\n\tclearInsect();\n\tmyScrollTo('.blankPhoto')\n\treturn true;\n}\n\n\$('#cc-4-valid-insect-button').click(validateInsect);\n\n\$('#cc-4-delete-insect-button').click(function() {\n\tvar container = \$(this).parent().parent();\n\tjQuery('#cc-4-delete-insect').find('[name=occurrence\\:id]').val(jQuery('#cc-4-main-form').find('[name=occurrence\\:id]').val()).removeAttr('disabled');\n\tjQuery('#cc-4-delete-insect').find('[name=occurrence\\:sample_id]').val(jQuery('#cc-4-main-form').find('[name=occurrence\\:sample_id]').val()).removeAttr('disabled');\n\tif(confirm(\"" . lang::get('LANG_Confirm_Insect_Delete') . "\")){\n\t\tif(jQuery('#cc-4-main-form').find('[name=occurrence\\:id]').filter('[disabled]').length == 0){\n\t\t\tjQuery('#cc-4-delete-insect').submit();\n\t\t\tjQuery('.currentPhoto').remove();\n\t\t\tjQuery('.blankPhoto').addClass('currentPhoto');\n\t\t}\n\t\tclearInsect();\n\t\tmyScrollTo('.blankPhoto')\n\t}\n});\n\n\$('#cc-4-delete-insect').ajaxForm({ \n\t\tasync: false,\n\t\tdataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n  \t\t\t// Warning this assumes that the data is fixed position:\n        \tif(data[2].value == '') return false;\n\t\t\tif(data[3].value == ''){\n\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 13: sample id not set, so unsafe to save insect.') . "\"});\n\t\t\t\treturn false;\n\t\t\t}\n        \tjQuery('#cc-4-delete-insect').addClass('loading-button');\n        \treturn true;\n  \t\t},\n        success:   function(data){\n       \t\tif(data.success != 'multiple records' || data.outer_table != 'occurrence')\n        \t\talertIndiciaError(data);\n  \t\t},\n        complete: function (){\n  \t\t\tjQuery('.loading-button').removeClass('loading-button');\n  \t\t}\n});\n\n\$('#cc-4-valid-photo-button').click(function(){\n\tif(!validateInsect()) return;\n\tjQuery('#cc-4').foldPanel();\n\tjQuery('#cc-5').showPanel();\n\tvar numInsects = jQuery('#cc-4-photo-reel').find('.thumb').length - 1; // ignore blank\n\tvar numUnidentified = jQuery('#cc-4-photo-reel').find('.unidentified').length;\n\tif(jQuery('#id-flower-later').attr('checked') != '' || (numInsects>0 && (numUnidentified/numInsects > (1-(" . $args['percent_insects'] . "/100.0))))){\n\t\tjQuery('#cc-5-bad').show();\n\t\tjQuery('#cc-5-good,#cc-5-body2,#cc-5-complete-collection').hide();\n    } else {\n    \tjQuery('#cc-5-bad').hide(); // photoreel is left showing\n    \tjQuery('#cc-5-good,#cc-5-body2,#cc-5-complete-collection').show();\n\t}\n});\n";
        $r .= '
<div id="cc-5" class="poll-section">
  <div id="cc-5-body" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top poll-section-body"> 
   <p id="cc-5-good">' . lang::get('LANG_Can_Complete_Msg') . '</p> 
   <p id="cc-5-bad">' . lang::get('LANG_Cant_Complete_Msg') . '</p> 
   <div style="display:none" />
    <form id="cc-5-collection" action="' . iform_ajaxproxy_url($node, 'sample') . '" method="POST">
       <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
       <input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '" />
       <input type="hidden" name="sample:id" value="" />
       <input type="hidden" name="sample:date_start" value="2010-01-01"/>
       <input type="hidden" name="sample:date_end" value="2010-01-01"/>
       <input type="hidden" name="sample:date_type" value="D"/>
       <input type="hidden" name="sample:location_id" value="" />
       <input type="hidden" id="smpAttr:' . $args['complete_attr_id'] . '" name="smpAttr:' . $args['complete_attr_id'] . '" value="1" />
    </form>
   </div>
  </div>
  <div id="cc-5-body2" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active poll-section-body">
    <p><img src="' . $base . drupal_get_path('module', 'iform') . '/media/images/exclamation.jpg" /> ' . lang::get('LANG_Trailer_Head') . ' :</p>
    <ul>
      <li>' . lang::get('LANG_Trailer_Point_1') . '</li>
      <li>' . lang::get('LANG_Trailer_Point_2') . '</li>
      <li>' . lang::get('LANG_Trailer_Point_3') . '</li>
      <li>' . lang::get('LANG_Trailer_Point_4') . '</li>
    </ul>
  </div>
  <div id="cc-5-trailer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active poll-section-footer">
    <div id="cc-5-complete-collection" class="ui-state-default ui-corner-all complete-button">' . lang::get('LANG_Complete_Collection') . '</div>
  </div>
</div>';
        data_entry_helper::$javascript .= "\n\$('#cc-5-collection').ajaxForm({ \n\t\tasync: false,\n\t\tdataType:  'json', \n        beforeSubmit:   function(data, obj, options){\n            // double check that location id and sample id are filled in\n\t\t\tif(jQuery('#cc-1-collection-details input[name=location\\:id]').val() == ''){\n\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 14: location id not set, so unsafe to save collection.') . "\"});\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(jQuery('#cc-1-collection-details input[name=sample\\:id]').val() == ''){\n\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 15: sample id not set, so unsafe to save collection.') . "\"});\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tjQuery('#cc-5-complete-collection').addClass('loading-button');\n        \tdata[findID('sample:id', data)].value = jQuery('#cc-1-collection-details input[name=sample\\:id]').val();\n\t\t\tdata[findID('sample:date_start', data)].value = '';\n\t\t\tdata[findID('sample:date_end', data)].value = '';\n\t\t\tdate_start = '';\n\t\t\tdate_end = '';\n\t\t\tjQuery('.poll-session-form').each(function(i){\n\t\t\t\tif(jQuery(this).find('input[name=sample\\:id]').val() != '') {\n\t\t\t\t\tvar sessDate = jQuery(this).find('input[name=sample\\:date]').val();\n\t\t\t\t\tvar sessDateDate = new Date(convertDate(sessDate)); // sessions are only on one date.\n\t\t\t\t\tif(date_start == '' || date_start > sessDateDate) {\n\t\t\t\t\t\tdate_start = sessDateDate;\n\t\t\t\t\t\tdata[findID('sample:date_start', data)].value = sessDate;\n\t\t\t\t\t}\n\t\t\t\t\tif(date_end == '' || date_end < sessDateDate) {\n\t\t\t\t\t\tdate_end = sessDateDate;\n\t\t\t\t\t\tdata[findID('sample:date_end', data)].value = sessDate;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(data[findID('sample:date_start', data)].value == '') {\n\t\t\t\talert(\"" . lang::get('LANG_Session_Error') . "\");\n\t\t\t\tjQuery('#cc-5-complete-collection').removeClass('loading-button');\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdata[findID('sample:date_type', data)].value = (data[3].value == data[4].value ? 'D' : 'DD');\n\t       \tjQuery('#cc-1-collection-details,#cc-2').find('[name=sample\\:date]:hidden').val(data[3].value);\n  \t\t\tdata[findID('sample:location_id', data)].value = jQuery('#cc-1-collection-details input[name=location\\:id]').val();\n       \t\tdata[7].name = jQuery('#cc-1-collection-details input[name^=smpAttr\\:" . $args['complete_attr_id'] . "\\:]').attr('name');\n       \t\treturn true;\n  \t\t},\n        success:   function(data){\n       \t\tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n\t\t\t\t\$('#cc-6').showPanel();\n  \t\t\t}  else\n\t\t\t\talertIndiciaError(data);\n  \t\t},\n        complete: function (){\n  \t\t\tjQuery('.loading-button').removeClass('loading-button');\n  \t\t}\n});\n\$('#cc-5-complete-collection').click(function(){\n\tjQuery('#cc-5-complete-collection').addClass('loading-button');\n\tjQuery('#cc-2,#cc-3,#cc-4,#cc-5').hidePanel();\n\tjQuery('.reinit-button').hide();\n\tjQuery('.mod-button').hide();\n\tjQuery('#cc-5-collection').submit();\n});\n";
        $r .= '
<div id="cc-6" class="poll-section">
  <div id="cc-6-body" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top poll-section-body"> 
   <p>' . lang::get('LANG_Final_1') . '</p> 
   <p>' . lang::get('LANG_Final_2') . '</p> 
   </div>
  <div id="cc-6-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active poll-section-footer">
    <a id="cc-6-consult-collection" href="" class="ui-state-default ui-corner-all link-button">' . lang::get('LANG_Consult_Collection') . '</a>
    <a href="' . url('node/' . $node->nid) . '" class="ui-state-default ui-corner-all link-button">' . lang::get('LANG_Create_New_Collection') . '</a>
  </div>
</div>
</div></div>
<script type="text/javascript">
/* <![CDATA[ */
document.write("</div>");
/* ]]> */</script>
';
        data_entry_helper::$javascript .= "\nloadAttributes = function(formsel, attributeTable, attributeKey, key, keyValue, prefix, reset_timeout, required){\n\t// first need to remove any hidden multiselect checkbox unclick fields\n\tjQuery(formsel).find('[name^='+prefix+'\\:]').filter('.multiselect').remove();\n\t// rename, to be safe. Then add [] to multiple choice checkboxes.\n\tjQuery(formsel).find('[name^='+prefix+'\\:]').each(function(){\n\t\tvar name = jQuery(this).attr('name').split(':');\n\t\tif(name[1].indexOf('[]') > 0) name[1] = name[1].substr(0, name[1].indexOf('[]'));\n\t\tjQuery(this).attr('name', name[0]+':'+name[1]);\n\t});\n\tjQuery(formsel).find('[name^='+prefix+'\\:]').filter(':checkbox').removeAttr('checked').each(function(){\n\t\tvar myName = jQuery(this).attr('name').split(':');\n\t\tvar similar = jQuery('[name='+myName[0]+'\\:'+myName[1]+'],[name='+myName[0]+'\\:'+myName[1]+'\\[\\]]').filter(':checkbox');\n\t\tif(similar.length > 1)\n\t\t\tjQuery(this).attr('name', myName[0]+':'+myName[1]+'[]');\n\t});\n    jQuery.ajax({ \n        type: \"GET\", \n        url: \"" . $svcUrl . "/data/\" + attributeTable + \"?mode=json&view=list\" +\n        \t(reset_timeout ? \"&reset_timeout=true\" : \"\") + \"&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\", \n        data: {},\n        myFormsel: formsel,\n        myAttributeKey: attributeKey,\n        success: function(attrdata) {\n\t\t  if(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t  } else if (attrdata.length>0) {\n\t\t\tfor (var i=0;i<attrdata.length;i++){\n\t\t\t\t// attribute list views now use id rather than meaning_id for the term.\n\t\t\t\t// This means (1) that the term will be either not present or wrong, as we are storing the meaning_id.\n\t\t\t\t// and (2) only one row will be returned per attribute.\n\t\t\t\t// As we already use raw_value below, the only change is no need to check the iso field.\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tvar radiobuttons = jQuery(this.myFormsel).find('[name='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+'],[name^='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+'\\:]').filter(':radio');\n\t\t\t\t\tvar multicheckboxes = jQuery(this.myFormsel).find('[name='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+'\\[\\]],[name^='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+':]').filter(':checkbox');\n\t\t\t\t\tvar boolcheckbox = jQuery(this.myFormsel).find('[name='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+'],[name^='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+':]').filter(':checkbox');\n\t\t\t\t\tif(radiobuttons.length > 0){ // radio buttons all share the same name, only one checked.\n\t\t\t\t\t\tradiobuttons\n\t\t\t\t\t\t\t.attr('name', prefix+':'+attrdata[i][this.myAttributeKey]+':'+attrdata[i].id)\n\t\t\t\t\t\t\t.filter('[value='+attrdata[i].raw_value+']')\n\t\t\t\t\t\t\t.attr('checked', 'checked');\n\t\t\t\t\t} else if(multicheckboxes.length > 0){ // individually named\n\t\t\t\t\t\tmulticheckboxes = multicheckboxes.filter('[value='+attrdata[i].raw_value+']')\n\t\t\t\t\t\t\t.attr('name', prefix+':'+attrdata[i][this.myAttributeKey]+':'+attrdata[i].id)\n\t\t\t\t\t\t\t.attr('checked', 'checked');\n\t\t\t\t\t\tmulticheckboxes.each(function(){\n\t\t\t\t\t\t\tjQuery('<input type=\"hidden\" value=\"0\" class=\"multiselect\">').attr('name', jQuery(this).attr('name')).insertBefore(this);\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if(boolcheckbox.length > 0){ // has extra hidden field to force zero if unchecked.\n\t\t\t\t\t\tjQuery(this.myFormsel).find('[name='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+'],[name^='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+':]')\n\t\t\t\t\t\t\t.attr('name', prefix+':'+attrdata[i][this.myAttributeKey]+':'+attrdata[i].id);\n\t\t\t\t\t\tif (attrdata[i].raw_value == '1')\n\t\t\t\t\t\t\tboolcheckbox.attr('checked', 'checked');\n\t\t\t\t\t} else if (prefix == 'smpAttr' && attrdata[i][this.myAttributeKey] == " . $args['complete_attr_id'] . ") {\n\t\t\t\t\t\t// The hidden closed attributes are special: these have forced values, and are used to control the state. Do not update their values.\n\t\t\t\t\t\tjQuery(this.myFormsel).find('[name='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+']')\n\t\t\t\t\t\t\t.attr('name', prefix+':'+attrdata[i][this.myAttributeKey]+':'+attrdata[i].id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tjQuery(this.myFormsel).find('[name='+prefix+'\\:'+attrdata[i][this.myAttributeKey]+']')\n\t\t\t\t\t\t\t.attr('name', prefix+':'+attrdata[i][this.myAttributeKey]+':'+attrdata[i].id)\n\t\t\t\t\t\t\t.val(attrdata[i].raw_value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t  } else if (required){\n\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 16: could not load attributes ') . "\"+attributeTable+' '+keyName+' '+keyValue});\n\t\t  }\n\t\t  checkProtocolStatus('leave');\n\t\t  populateSessionSelect();\n\t\t  checkForagingStatus(true);\n\t\t},\n\t\tdataType: 'json'\n\t});\n}\n\nloadImage = function(imageTable, key, keyName, keyValue, target, ratio, required){\n\t\t\t\t\t// location_image, location_id, location:id, 1, #cc-4-insect-image\n\t\$.getJSON(\"" . $svcUrl . "/data/\" + imageTable +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\", function(imageData) {\n\t\tif(!(imageData instanceof Array)){\n   \t\t\talertIndiciaError(imageData);\n   \t\t} else if (imageData.length>0) {\n\t\t\tvar form = jQuery('input[name='+keyName+'][value='+keyValue+']').parent();\n\t\t\tjQuery('[name='+imageTable+'\\:id]', form).val(imageData[0].id).removeAttr('disabled');\n\t\t\tjQuery('[name='+imageTable+'\\:path]', form).val(imageData[0].path);\n\t        insertImage('med-'+imageData[0].path, jQuery(target), ratio);\n\t\t} else if(required){\n\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 17: could not load ') . "\"+imageTable+' '+keyName+' '+keyValue});\n\t\t}\n\t});\n}\n\nloadDetermination = function(detData, toolStruc){\n\tjQuery('#'+toolStruc.type+'_taxa_list').empty();\n\ttoolStruc.storedTaxaList = [];\n\tjQuery(toolStruc.mainForm+' input[name=determination\\:id]').val('').attr('disabled', 'disabled');\n\tjQuery('#id-'+toolStruc.type+'-later').removeAttr('checked').removeAttr('disabled');\n\tjQuery('[name='+toolStruc.type+'\\:determination_type]').val('A');\n\tjQuery(toolStruc.mainForm+' input[name=determination\\:determination_type]').val('A');\n\tjQuery('[name='+toolStruc.type+'\\:taxon_details],[name='+toolStruc.type+'\\:taxa_taxon_list_id],[name='+toolStruc.type+'\\:comment],[name='+toolStruc.type+'\\:taxon_extra_info]').val('');\n\n\tif (detData.length>0) {\n\t\tjQuery('#id-'+toolStruc.type+'-later').attr('disabled', 'disabled');\n\t\tjQuery(toolStruc.mainForm+' input[name=determination\\:id]').val(detData[0].id).removeAttr('disabled');\n\t\tjQuery('[name='+toolStruc.type+'\\:taxon_details]').val(detData[0].taxon_details);\n\t\tjQuery('[name='+toolStruc.type+'\\:determination_type]').val(detData[0].determination_type);\n\t\tjQuery('[name='+toolStruc.type+'\\:taxa_taxon_list_id]').val(detData[0].taxa_taxon_list_id == null ? '' : detData[0].taxa_taxon_list_id);\n\t\tjQuery('[name='+toolStruc.type+'\\:comment]').val(detData[0].comment);\n\t\tjQuery('[name='+toolStruc.type+'\\:taxon_extra_info]').val(detData[0].taxon_extra_info == null ? '' : detData[0].taxon_extra_info);\n\t\tif(detData[0].determination_type == 'X'){\n\t\t\tjQuery('#'+toolStruc.type+'_taxa_list').append(\"" . lang::get('LANG_Taxa_Unknown_In_Tool') . "\");\n\t\t} else {\n\t\t\tvar resultsIDs = [];\n\t\t\tif(detData[0].taxa_taxon_list_id_list != null && detData[0].taxa_taxon_list_id_list != ''){\n\t\t\t  \tvar resultsText = \"" . lang::get('LANG_Taxa_Returned') . "<br />{ \";\n\t\t\t  \tresultsIDs = detData[0].taxa_taxon_list_id_list.substring(1, detData[0].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t  \tfor(var j=0; j < resultsIDs.length; j++){\n\t\t\t\t\tfor(i = 0; i< toolStruc.taxaList.length; i++)\n\t\t\t\t\t\tif(toolStruc.taxaList[i].id == resultsIDs[j])\n\t\t\t\t\t\t\tresultsText = resultsText + (j == 0 ? '' : '<br />&nbsp;&nbsp;') + htmlspecialchars(toolStruc.taxaList[i].taxon);\n\t\t  \t\t}\n\t  \t\t\tif(resultsIDs.length>1 || resultsIDs[0] != '')\n\t\t\t\t\tjQuery('#'+toolStruc.type+'_taxa_list').append(resultsText+ ' }');\n\t\t\t}\n\t\t\ttoolStruc.storedTaxaList = resultsIDs;\n  \t\t}\n\t} else {\n\t\tjQuery('#id-'+toolStruc.type+'-later').attr('checked', 'checked');\n\t}\n};\n// Flowers no longer uses the taxa_taxon_list_id, but instead uses its list equivalent for known species.\n// the flower identification is not held with the cc-2-floral-station form.\nloadFlowerDetermination = function(detData){\n  jQuery('form#cc-2-floral-station input[name=determination\\:id]').val('').attr('disabled', 'disabled');\n  jQuery('#id-flower-later').removeAttr('checked').removeAttr('disabled');\n  jQuery('#id-flower-unknown').removeAttr('checked').removeAttr('disabled');\n  jQuery('[name=flower\\:determination_type]').val('A'); // hidden\n  jQuery('form#cc-2-floral-station input[name=determination\\:determination_type]').val('A');// hidden\n  jQuery('.flower-species-list-entry').remove();\n  jQuery('[name=flower\\:taxon_details],[name=flower\\:taxa_taxon_list_id],[name=flower\\:comment],[name=flower\\:taxon_extra_info]').val('');\n\n  if (detData.length>0) {\n    jQuery('#id-flower-later').attr('disabled', 'disabled');\n    jQuery('form#cc-2-floral-station input[name=determination\\:id]').val(detData[0].id).removeAttr('disabled');\n    jQuery('[name=flower\\:taxon_details]').val(detData[0].taxon_details == null ? '' : detData[0].taxon_details); // stores details from tool.\n    jQuery('[name=flower\\:determination_type]').val(detData[0].determination_type);\n    jQuery('[name=flower\\:comment]').val(detData[0].comment == null ? '' : detData[0].comment);\n    jQuery('[name=flower\\:taxon_extra_info]').val(detData[0].taxon_extra_info == null ? '' : detData[0].taxon_extra_info);\n    if(detData[0].determination_type == 'X') {\n      jQuery('#id-flower-unknown').attr('checked', 'checked');\n    } else if(detData[0].taxa_taxon_list_id != null) { // already set blank up above for null\n      // copy existing data forward to array.\n      for(i = 0; i< flowerTaxa.length; i++)\n        if(flowerTaxa [i].id == detData[0].taxa_taxon_list_id) {\n          jQuery('<tr class=\"flower-species-list-entry\"><td><input type=\"hidden\" name=\"flower:taxa_taxon_list_id_list[]\" value=\"'+flowerTaxa [i].id+'\"\\>'+htmlspecialchars(flowerTaxa[i].taxon)+'<td><img  class=\"removeRow\" src=\"/misc/watchdog-error.png\" alt=\"" . lang::get('Remove this entry') . "\" title=\"" . lang::get('Remove this entry') . "\"/></td></tr>').insertBefore('#flowerAutocompleteRow');\n          break;\n        }\n    } else {\n      if(detData[0].taxa_taxon_list_id_list != null && detData[0].taxa_taxon_list_id_list != ''){\n        var resultsIDs = detData[0].taxa_taxon_list_id_list.substring(1, detData[0].taxa_taxon_list_id_list.length - 1).split(','); // stringified array\n        for(var j=0; j < resultsIDs.length; j++)\n          for(i = 0; i< flowerTaxa.length; i++)\n            if(flowerTaxa[i].id == resultsIDs[j])\n              jQuery('<tr class=\"flower-species-list-entry\"><td><input type=\"hidden\" name=\"flower:taxa_taxon_list_id_list[]\" value=\"'+flowerTaxa [i].id+'\"\\>'+htmlspecialchars(flowerTaxa[i].taxon)+'<td><img class=\"removeRow\" src=\"/misc/watchdog-error.png\" alt=\"" . lang::get('Remove this entry') . "\" title=\"" . lang::get('Remove this entry') . "\"/></td></tr>').insertBefore('#flowerAutocompleteRow');\n      }\n    }\n  } else {\n    jQuery('#id-flower-later').attr('checked', 'checked');\n  }\n};\n\n// load in any existing incomplete collection.\n// general philosophy is that you are taken back to the stage last verified.\n// Load in the first if there are more than one. Use the internal report which provides my collections.\n// Requires that there is an attribute for completeness, and one for the CMS\n// load the data in the order it is entered, so can stop when get to the point where the user finished.\n// have to reset the entire form first...\njQuery('.poll-section').resetPanel();\n// Default state: hide everything except the collection details block.\njQuery('.poll-section').hidePanel();\njQuery('#cc-1').showPanel();\njQuery('.reinit-button').hide();\naddSession();\njQuery('.flower-species-list-entry').remove();\njQuery('#insect_taxa_list').empty();\npreloading=true;\npreloadIDs={location_loaded : false,\n\t\t\tsessions: []};\nsetPreloadStage = function(stage){\n\tpreloadStage=stage;\n\t\$('.poll-loading-extras').empty().text(stage);\n};\nsetPreloadStage(1);\n\njQuery('#cc-1').ajaxStop(function(){\n\tif(!preloading) return;\n\tswitch(preloadStage){\n\t\tcase 1: // just finished the report request\n\t\t\tif(typeof preloadIDs.sample_id == 'undefined' || typeof preloadIDs.location_id == 'undefined'){\n\t\t\t\t\$('.loading-panel').remove();\n\t\t\t\t\$('.poll-loading-hide').show();\n\t\t\t\tpreloading=false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetPreloadStage(2);\n\t\t\t// main sample date is only set when collection is completed, so don't need to load collection sample itself, and keep date as default \n\t\t\tloadAttributes('#cc-1-collection-details,#cc-5-collection', 'sample_attribute_value', 'sample_attribute_id', 'sample_id', preloadIDs.sample_id, 'smpAttr', false, true);\n  \t\t\tjQuery.getJSON('" . $svcUrl . "/data/location/' + preloadIDs.location_id +\n          \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n          \t\t\t\t\t\"&callback=?\", \n\t\t\t\t\tfunction(locationdata) {\n\t\t    \t\t  if(!(locationdata instanceof Array)){\n   \t\t\t\t\t\talertIndiciaError(locationdata);\n   \t\t\t\t\t  } else if (locationdata.length>0) {\n\t    \t\t\t\tjQuery('input[name=location\\:name]').val(locationdata[0].name);\n       \t\t\t\t\tjQuery('input[name=sample\\:location_name]').val(locationdata[0].name); // make sure the 2 coincide\n\t    \t\t\t\tjQuery('input[name=locations_website\\:website_id]').attr('disabled', 'disabled');\n\t\t\t\t\t\t// The location only holds a valid place if the floral station has been saved: otherwise it holds a default value.\n\t\t\t\t\t\t// we use the centroid_sref_system to indicate this: when the initial save is done the system is 900913,\n\t\t\t\t\t\t// but when a user has loaded one it is in 4326\n\t\t\t\t\t\t// NB the location geometry is stored in centroid, due to restrictions in location model.\n\t\t\t\t\t\tif(locationdata[0].centroid_sref_system == 4326 && locationdata[0].centroid_sref != oldDefaultSref){\n\t\t\t\t\t\t\tjQuery('input[name=location\\:centroid_sref]').val(locationdata[0].centroid_sref);\n\t\t\t\t\t\t\tjQuery('input[name=location\\:centroid_sref_system]').val(locationdata[0].centroid_sref_system); // note this will change the 900913 in cc-1 to 4326\n\t\t\t\t\t\t\tjQuery('input[name=location\\:centroid_geom]').val(locationdata[0].centroid_geom);\n\t\t\t\t\t\t\tvar parts=locationdata[0].centroid_sref.split(' ');\n\t\t\t\t\t\t\tvar refx = parts[0].split(',');\n\t\t\t\t\t\t\tjQuery('input[name=place\\:lat]').val(refx[0]);\n\t\t\t\t\t\t\tjQuery('input[name=place\\:long]').val(parts[1]);\n  \t\t\t\t\t\t}\n  \t\t\t\t\t\tpreloadIDs.location_loaded=true;\n\t\t\t\t\t  } else {\n\t\t\t\t\t\talertIndiciaError({error : \"" . lang::get('Internal Error 18: could not load data for location ') . "\"+data[i].location_id});\n\t\t\t\t\t  }});\n\t\t\tbreak;\n\t\tcase 2: // just finished the collection attributes and the location.\n\t\t\tif(preloadIDs.location_loaded==false)\n\t\t\t\treturn alertIndiciaError({error : \"" . lang::get('Internal Error 19: could not load data for location ') . "\"+preloadIDs.location_id});\n\t\t\tif(jQuery('[name=smpAttr\\:" . $args['protocol_attr_id'] . "]').length > 0)\n\t\t\t\treturn alertIndiciaError({error : \"" . lang::get('Internal Error 20: could not load attributes for sample ') . "\"+preloadIDs.sample_id});\n\t\t\t\$('#cc-1').foldPanel();\n\t\t\tcheckProtocolStatus(true);\n\t\t\t\$('#cc-2').showPanel();\n\t\t\tsetPreloadStage(3);\n\t\t\t// now load floral station stuff.\n\t\t\tloadAttributes('#cc-2-floral-station', 'location_attribute_value', 'location_attribute_id', 'location_id', preloadIDs.location_id, 'locAttr', false, false);\n\t\t\tloadImage('location_image', 'location_id', 'location\\:id', preloadIDs.location_id, '#cc-2-environment-image', " . $args['Environment_Image_Ratio'] . ", false);\n\t\t\tjQuery.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n          \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n          \t\t\t\t\t\"&sample_id=\"+preloadIDs.sample_id+\"&deleted=f&callback=?\", \n\t\t\t\t\tfunction(flowerData) {\n          \t\t\t  // there will only be an occurrence if the floral station panel has previously been displayed & validated. \n\t\t    \t\t  if(!(flowerData instanceof Array)){\n\t\t\t\t\t\talertIndiciaError(flowerData);\n\t\t\t\t\t  } else if (flowerData.length>0) { // do we need another >1 check as well?\n\t\t\t\t\t\tpreloadIDs.flower_id = flowerData[0].id;\n\t\t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence\\:sample_id]').val(preloadIDs.sample_id);\n\t\t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence\\:id]').val(flowerData[0].id).removeAttr('disabled');\n    \t   \t\t\t  }});\n\t\t\tbreak;\n\t\tcase 3: // just finished the location attributes, location image and flower.\n\t\t\t// all must be present or none at all: but location_attributes are all optional.\n\t\t\tif(typeof preloadIDs.flower_id == 'undefined' &&\n\t\t\t\t\tjQuery('[name=location_image\\:id]').val() == '') {\n\t\t\t\t\$('.loading-panel').remove();\n\t\t\t\t\$('.poll-loading-hide').show();\n\t\t\t\tbuildMap();\n\t\t\t\tpreloading=false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(typeof preloadIDs.flower_id == 'undefined')\n\t\t\t\treturn alertIndiciaError({error : \"" . lang::get('Internal Error 21: could not load flower data for collection ') . "\"+preloadIDs.sample_id});\n\t\t\tif(jQuery('[name=location_image\\:id]').val() == '')\n\t\t\t\treturn alertIndiciaError({error : \"" . lang::get('Internal Error 23: could not load environment image for location ') . "\"+preloadIDs.location_id});\n\t\t\tsetPreloadStage(4);\n\t\t\tloadAttributes('#cc-2-floral-station', 'occurrence_attribute_value', 'occurrence_attribute_id', 'occurrence_id', preloadIDs.flower_id, 'occAttr', false, true);\n\t\t\tloadImage('occurrence_image', 'occurrence_id', 'occurrence\\:id', preloadIDs.flower_id, '#cc-2-flower-image', " . $args['Flower_Image_Ratio'] . ", true);\n\t\t\tjQuery.getJSON(\"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&occurrence_id=\"+preloadIDs.flower_id+\"&orderby=id&deleted=f&callback=?\", \n\t\t\t\tfunction(detData) {\n\t\t\t\t\tif(!(detData instanceof Array)){\n   \t\t\t\t\t\talertIndiciaError(detData);\n   \t\t\t\t\t } else loadFlowerDetermination(detData, flowerIDstruc);\n  \t\t\t\t});\n\t\t\tbreak;\n\t\tcase 4: // just finished the flower attributes, flower image and optional flower determination. Attrs and image mandatory at this point.\n\t\t\tif(jQuery('#cc-2-floral-station > input[name=occurrence_image\\:id]').val() == '')\n\t\t\t\treturn alertIndiciaError({error : \"" . lang::get('Internal Error 24: could not load image for flower ') . "\"+preloadIDs.flower_id});\n\t\t\tif(jQuery('[name=occAttr\\:" . $args['flower_type_attr_id'] . "]').length>0)\n\t\t\t\treturn alertIndiciaError({error : \"" . lang::get('Internal Error 25: could not load attributes for flower ') . "\"+preloadIDs.flower_id});\n\t\t\tsetPreloadStage(5);\n\t\t\tjQuery('#cc-2').foldPanel();\n\t\t\tjQuery('#cc-3').showPanel();\n\t\t\tjQuery.getJSON(\"" . $svcUrl . "/data/sample\" + \n\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&parent_id=\"+preloadIDs.sample_id+\"&callback=?\", \n\t\t\t\tfunction(sessiondata) {\n\t\t\t\t\tif(!(sessiondata instanceof Array)){\n\t\t\t\t\t\talertIndiciaError(sessiondata);\n\t\t\t\t\t} else if (sessiondata.length>0) { // may have zero sessions\n\t\t\t\t\t\tsessionCounter = 0;\n\t\t\t\t\t\tjQuery('#cc-3-body').empty();\n\t\t\t\t\t\tfor (var i=0;i<sessiondata.length;i++){\n\t\t\t\t\t\t\tvar thisSession = addSession();\n\t\t\t\t\t\t\tpreloadIDs.sessions.push({id : sessiondata[i].id, div : thisSession});\n\t\t\t\t\t\t\tjQuery('input[name=sample\\:id]', thisSession).val(sessiondata[i].id).removeAttr('disabled');\n\t\t\t\t\t\t\tjQuery('input[name=sample\\:date]', thisSession).val(sessiondata[i].date_start);\n\t\t\t\t\t\t\tjQuery('input[name=dummy_date]', thisSession).datepicker('disable').datepicker('setDate', new Date(convertDate(sessiondata[i].date_start))).datepicker('enable');\n\t\t\t\t\t\t\t// fold this session.\n\t\t\t\t\t\t\tthisSession.show();\n\t\t\t\t\t\t\tthisSession.children(':first').show().children().show();\n\t\t\t\t\t\t\tthisSession.children().not(':first').hide();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpopulateSessionSelect();\n\t\t\t\t\t}});\n\t\t\tbreak;\n\t\tcase 5: // just finished the sessions. no error situations\n\t\t\tif(preloadIDs.sessions.length == 0){\n\t\t\t\t\$('.loading-panel').remove();\n\t\t\t\t\$('.poll-loading-hide').show();\n\t\t\t\tpreloading=false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetPreloadStage(6);\n\t\t\t\$('#cc-3').foldPanel();\n\t\t\t\$('#cc-4').showPanel();\n\t\t\tpopulateSessionSelect();\n\t\t\tvar sessionIDs = [];\n\t\t\tfor (var i=0;i<preloadIDs.sessions.length;i++){\n\t\t\t\tloadAttributes(preloadIDs.sessions[i].div, 'sample_attribute_value', 'sample_attribute_id', 'sample_id', preloadIDs.sessions[i].id, 'smpAttr', false, true);\n\t\t\t\tsessionIDs.push(preloadIDs.sessions[i].id);\n\t\t\t}\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n\t\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&orderby=id\" +\n\t\t\t\t\t\t\"&deleted=f&callback=?&query=\"+escape(escape(JSON.stringify({'in': {'sample_id': sessionIDs}}))),\n\t\t\t\tfunction(insectData) {\n\t\t\t\t\tif(!(insectData instanceof Array)) return alertIndiciaError(insectData);\n\t\t\t\t\tif (insectData.length>0)\n\t\t\t\t\t\tfor (var j=0;j<insectData.length;j++)\n\t\t\t\t\t\t\taddExistingToPhotoReel(insectData[j].id);\n\t\t\t});\n\t\t\tbreak;\n\t\tcase 6: // just finished the session attributes and insects.\n\t\t\t// at this point the insects are optional, as are their determinations, so can't check for their presence.\n\t\t\tfor (var i=0;i<preloadIDs.sessions.length;i++){ // check attributes loaded for each session\n\t\t\t\tif(jQuery('[name=smpAttr\\:" . $args['start_time_attr_id'] . "]', preloadIDs.sessions[i].div).length>0)\n\t\t\t\t\treturn alertIndiciaError({error : \"" . lang::get('Internal Error 26: could not load attributes for session ') . "\"+preloadIDs.sessions[i].id});\n\t\t\t}\n\t\t\t\$('.loading-panel').remove();\n\t\t\t\$('.poll-loading-hide').show();\n\t\t\tpreloading=false;\n\t\t\tbreak;\n  }\n});\njQuery.getJSON(\"" . $svcUrl . "\" + \"/report/requestReport?report=reports_for_prebuilt_forms/poll_my_collections.xml&reportSource=local&mode=json\" +\n\t\t\t\"&auth_token=" . $readAuth['auth_token'] . "&reset_timeout=true&nonce=" . $readAuth["nonce"] . "\" + \n\t\t\t\"&survey_id=" . $args['survey_id'] . "&userID_attr_id=" . $args['uid_attr_id'] . "&userID=" . $uid . "&complete_attr_id=" . $args['complete_attr_id'] . "&callback=?\", \n\tfunction(data) {\n\tif(!(data instanceof Array)){\n   \t\talertIndiciaError(data);\n   \t  } else if (data.length>0) { // could have zero length\n\t\tvar i;\n       \tfor ( i=0;i<data.length;i++) {\n       \t\tif(data[i].completed == '0'){\n       \t\t\tjQuery('#cc-1-collection-details,#cc-1-delete-collection,#cc-2').find('[name=sample\\:id]').val(data[i].id).removeAttr('disabled');\n\t\t    \tjQuery('[name=location\\:id],[name=sample\\:location_id]').val(data[i].location_id).removeAttr('disabled');\n       \t\t\tjQuery('#cc-6-consult-collection').attr('href', '" . url('node/' . $args['gallery_node']) . "'+'?collection_id='+data[i].id);\n       \t\t\tpreloadIDs.sample_id = data[i].id;\n       \t\t\tpreloadIDs.location_id = data[i].location_id;\n\t\t\t\t// only use the first one which is not complete..\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n      }\n    });\n  ";
        // because of the use of getJson to retrieve the data - which is asynchronous, the use of the normal loading_block_end
        // is not practical - it will do its stuff before the data is loaded, defeating the purpose. Also it uses hide (display:none)
        // which is a no-no in relation to the map. This means we have to dispense with the slow fade in.
        // it is also complicated by the attibutes and images being loaded asynchronously - and non-linearly.
        // Do the best we can!
        //    data_entry_helper::$onload_javascript = "jQuery('.my-loading-hide').addClass('loading-hide').removeClass('my-loading-hide');\n".data_entry_helper::$onload_javascript."\nbuildMap();";
        data_entry_helper::$onload_javascript .= "\nbuildMap();";
        return $r;
    }
Exemplo n.º 23
0
    control.find('a').css('display','none');
    control.find('.handle').css('display','none');
    control.find('.caption').css('text-decoration', 'line-through');	
    $('#layout-change-form').show();
  });
  
  makeControlsDragDroppable();
  makeBlocksDragDroppable();
});

</script>
<form action="" method="get">
<fieldset>
<?php 
require_once DOCROOT . 'client_helpers/data_entry_helper.php';
echo data_entry_helper::select(array('fieldname' => 'type', 'label' => 'Display attributes for', 'lookupValues' => array('sample' => 'Samples', 'occurrence' => 'Occurrences', 'location' => 'Locations'), 'default' => $_GET['type'], 'suffixTemplate' => 'nosuffix', 'class' => 'line-up'));
?>
<input type="submit" class="button ui-state-default ui-widget-content ui-corner-all line-up" id="change-type" value="Go" />
</fieldset>
</form>
<ul id="top-blocks" class="block-list">
<?php 
foreach ($top_blocks as $block) {
    echo '<li class="block-drop"></li>';
    echo '<li id="block-' . $block->id . '" class="ui-widget draggable-block">';
    echo "<div class=\"ui-helper-clearfix\">\n";
    echo "<span class=\"handle\">&nbsp;</span>\n";
    echo '<span class="caption">' . $block->name . "</span>\n";
    echo '<a href="" class="block-delete">Delete</a>';
    echo '<a href="" class="block-rename">Rename</a>';
    echo "</div>\n";
Exemplo n.º 24
0
 protected static function get_control_transectgrid($auth, $args, $tabalias, $options)
 {
     /* We will make the assumption that only one of these will be put onto a form.
      * A lot of this is copied from the species control and has the same features. */
     $extraParams = $auth['read'] + array('view' => 'detail', 'reset_timeout' => 'true');
     if ($args['species_names_filter'] == 'preferred') {
         $extraParams += array('preferred' => 't');
     }
     if ($args['species_names_filter'] == 'language') {
         $extraParams += array('language_iso' => iform_lang_iso_639_2($user->lang));
     }
     // A single species entry control of some kind
     if ($args['extra_list_id'] == '') {
         $extraParams['taxon_list_id'] = $args['list_id'];
     } elseif ($args['species_ctrl'] == 'autocomplete') {
         $extraParams['taxon_list_id'] = $args['extra_list_id'];
     } else {
         $extraParams['taxon_list_id'] = array($args['list_id'], $args['extra_list_id']);
     }
     $species_list_args = array_merge(array('label' => lang::get('transectgrid:taxa_taxon_list_id'), 'fieldname' => 'transectgrid_taxa_taxon_list_id', 'id' => 'transectgrid_taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'taxon_meaning_id', 'columns' => 2, 'parentField' => 'parent_id', 'extraParams' => $extraParams, 'numValues' => $args['max_species_ids']), $options);
     // do not allow tree browser
     if ($args['species_ctrl'] == 'tree_browser') {
         return '<p>Can not use tree browser in this context</p>';
     }
     // this termlist is language independant so ignore language
     $detail_args = array('label' => '{LABEL}', 'fieldname' => '{FIELDNAME}', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $auth['read'] + array('termlist_id' => $args['qual_dist_term_id']), 'suffixTemplate' => 'zilch', 'optionSeparator' => '', 'labelClass' => 'narrow', 'size' => 4);
     data_entry_helper::$javascript .= "\nbuild_empty_transectgrid = function(speciesID){\n  // at this point the species ID should be the preferred one.\n  // first check if already set up. If yes do nothing.\n  if(jQuery('.transectgrid').find('[taxonID='+speciesID+']').length > 0) return;\n  var container = jQuery('<div class=\"trSpeciesContainer\" ></div>').prependTo('.transectgrid');\n  jQuery('<span class=\"right\"><img src=\"/misc/watchdog-error.png\" alt=\"Delete\"/></span>').attr('taxonID',speciesID).appendTo(container).click(function(){\n    if(confirm(\"" . lang::get('transectgrid:confirmremove') . "\"+jQuery(this).parent().find('.trgridspecname')[0].textContent+\"?\")){\n     jQuery(this).parent().find('select').each(function(){\n      var parts = jQuery(this).attr('name').split(':');\n      if(parts[5] != '-'){\n        var delList = jQuery('#TGDEL').val();\n        jQuery('#TGDEL').val((delList == '' ? '' : delList+',')+parts[5]);\n      }\n     });\n     jQuery(this).parent().remove();\n    }\n  });\n  jQuery('<span class=\"trgridspecname\"></span>').attr('taxonID',speciesID).appendTo(container);\n  jQuery('<br /><span class=\"trgridothernames\"></span>').attr('taxonID',speciesID).appendTo(container);\n  var table = jQuery('<table border=\"1\"></table>').appendTo(container);\n  var sel = '" . data_entry_helper::select($detail_args) . "';\n  for(var i=0; i<5; i++) {\n    var row = jQuery('<tr></tr>').appendTo(table);\n    // Fieldname is TG:speciesID:gridX:gridY:GridsampleID:OccID:AttrID\n    for(var j=0; j<5; j++)\n      jQuery('<td><span>'+((sel.replace(/{LABEL}/g, (j*2).toString()+((4-i)*2).toString())).replace(/{FIELDNAME}/g, 'TG:'+speciesID+':'+(j*2)+':'+(4-i)*2+':-:-:-'))+'</td>').appendTo(row);\n  }\n  jQuery.getJSON(\"" . self::$svcUrl . "/data/taxa_taxon_list/\"+speciesID +\n\t\t\"?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "\" +\n\t\t\t\"&callback=?\", function(data) {\n        if (data.length>0) {\n          jQuery('.trgridspecname').filter('[taxonID='+data[0].id+']').empty().attr('meaningID', data[0].taxon_meaning_id).append('<b>'+data[0].taxon+'</b>');\n          jQuery('.trgridothernames').filter('[taxonID='+data[0].id+']').empty().attr('meaningID', data[0].taxon_meaning_id);\n          jQuery.getJSON(\"" . self::$svcUrl . "/data/taxa_taxon_list/\"+\n              \"?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&preferred=false&taxon_meaning_id=\" + data[0].taxon_meaning_id +\n              \"&callback=?\", function(data) {\n            if (data.length>0) {\n              for(var i = 0; i<data.length; i++)\n                jQuery('.trgridothernames').filter('[meaningID='+data[i].taxon_meaning_id+']').append(data[i].taxon+', ');\n            }});\n        }});\n};\n\nbuild_transectgrid = function(speciesID, X, Y, gridSampleID, occurrenceID, attributeID, value){\n  // at this point the species ID should be the preferred one.\n  build_empty_transectgrid(speciesID);\n  var sel=jQuery('[name^=TG\\:'+speciesID+'\\:'+X+'\\:'+Y+'\\:]').attr('name','TG:'+speciesID+':'+X+':'+Y+':'+gridSampleID+':'+occurrenceID+':'+attributeID).val(value);\n};\n\njQuery('#transectgrid_taxa_taxon_list_id').change(function(){\n  // when this is called the value stored is the taxon_meaning_id: .\n  // Initially check that row does not already exist:\n  var existRows = jQuery('.trgridspecname').filter('[meaningID='+jQuery('#transectgrid_taxa_taxon_list_id').val()+']');\n  if(existRows.length>0)\n    alert(\"" . lang::get('transectgrid:rowexists') . "\"+existRows[0].textContent);\n  else\n    // Next convert to the preferred ID\n    jQuery.getJSON(\"" . self::$svcUrl . "/data/taxa_taxon_list\" +\n\t\t\"?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&preferred=true&taxon_meaning_id=\" + jQuery('#transectgrid_taxa_taxon_list_id').val() +\n\t\t\t\"&callback=?\", function(data) {\n        if (data.length>0) {\n  \t\t\tbuild_empty_transectgrid(data[0].id);\n        }});\n  jQuery('#transectgrid_taxa_taxon_list_id\\\\:taxon').val('');\n});\n\n\n";
     $myHidden = '';
     // here put in a load of JS calls to build the grids
     if (isset(data_entry_helper::$entity_to_load['auth_token'])) {
         // post failed
         foreach (data_entry_helper::$entity_to_load as $key => $value) {
             $parts = explode(':', $key);
             if ($parts[0] == 'TG' && $value != $args['ignore_qual_dist_id']) {
                 data_entry_helper::$javascript .= "build_transectgrid(" . $parts[1] . "," . $parts[2] . "," . $parts[3] . ",\"" . $parts[4] . "\",\"" . $parts[5] . "\",\"" . $parts[6] . "\"," . $value . ");\n";
             } else {
                 if ($parts[0] == 'TGS' || $parts[0] == 'TGDEL') {
                     $myHidden .= '<input type="hidden" name="' . $key . '" value="' . $value . '">';
                 }
             }
         }
     } else {
         $myHidden = '<input type="hidden" id="TGDEL" name="TGDEL" value="" >';
         data_entry_helper::$javascript .= "jQuery('#TGDEL').val('');";
         if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
             //sample specified
             $url = self::$svcUrl . '/data/sample?parent_id=' . data_entry_helper::$entity_to_load['sample:id'];
             $url .= "&mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"];
             $session = curl_init($url);
             curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
             $entities = json_decode(curl_exec($session), true);
             foreach ($entities as $entity) {
                 if (substr($entity['location_name'], 0, 3) == 'GR ') {
                     $X = substr($entity['location_name'], -2, 1);
                     $Y = substr($entity['location_name'], -1);
                     $myHidden .= '<input type="hidden" name="TGS:' . $X . ':' . $Y . '" value="' . $entity['id'] . '">';
                     $url = self::$svcUrl . '/data/occurrence?sample_id=' . $entity['id'];
                     $url .= "&mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"];
                     $session = curl_init($url);
                     curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
                     $OCCentities = json_decode(curl_exec($session), true);
                     foreach ($OCCentities as $OCCentity) {
                         $url = self::$svcUrl . '/data/occurrence_attribute_value?mode=json&view=list&nonce=' . $auth['read']["nonce"] . '&auth_token=' . $auth['read']['auth_token'] . '&deleted=f&occurrence_id=' . $OCCentity['id'] . '&occurrence_attribute_id=' . $args['qual_dist_attr_id'];
                         $session = curl_init($url);
                         curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
                         $ATTRentities = json_decode(curl_exec($session), true);
                         foreach ($ATTRentities as $ATTRentity) {
                             data_entry_helper::$javascript .= "\nbuild_transectgrid(" . $OCCentity['taxa_taxon_list_id'] . "," . $X . "," . $Y . "," . $OCCentity['sample_id'] . "," . $ATTRentity['occurrence_id'] . "," . $ATTRentity['id'] . "," . $ATTRentity['raw_value'] . ");";
                         }
                     }
                 }
             }
         }
     }
     $retVal = $myHidden . '<div>' . call_user_func(array('data_entry_helper', $args['species_ctrl']), $species_list_args) . '</div><p>' . lang::get('transectgrid:bumpf1') . '</p><p>' . lang::get('transectgrid:bumpf2') . '</p><div class="transectgrid"></div>';
     data_entry_helper::$javascript .= "\n// override the default results function - doesn't seem to use value field.\njQuery('input#transectgrid_taxa_taxon_list_id\\\\:taxon').unbind(\"result\");\njQuery('input#transectgrid_taxa_taxon_list_id\\\\:taxon').result(function(event, data, value) {\n      jQuery('input#transectgrid_taxa_taxon_list_id').attr('value', value);\n      jQuery('input#transectgrid_taxa_taxon_list_id').change();\n});\n";
     return $retVal;
 }
Exemplo n.º 25
0
<form action="" method="post">
<?php 
require_once DOCROOT . 'client_helpers/data_entry_helper.php';
if (isset($_POST['from']) && !preg_match('/^[0-2][0-9]:[0-5][0-9](:[0-5][0-9])?$/', $_POST['from'])) {
    echo '<p>The start time you entered was not recognised.</p>';
    unset($_POST['from']);
}
if (isset($_POST['to']) && !preg_match('/^[0-2][0-9]:[0-5][0-9](:[0-5][0-9])?$/', $_POST['to'])) {
    echo '<p>The end time you entered was not recognised.</p>';
    unset($_POST['to']);
}
echo data_entry_helper::select(array('label' => 'Select the log date', 'lookupValues' => $files, 'fieldname' => 'file', 'labelClass' => 'auto', 'suffixTemplate' => 'nosuffix', 'default' => isset($_POST['file']) ? $_POST['file'] : null));
echo data_entry_helper::text_input(array('label' => 'between', 'labelClass' => 'auto', 'fieldname' => 'from', 'suffixTemplate' => 'nosuffix', 'default' => isset($_POST['from']) ? $_POST['from'] : '00:00:00'));
echo data_entry_helper::text_input(array('label' => 'and', 'labelClass' => 'auto', 'fieldname' => 'to', 'suffixTemplate' => 'nosuffix', 'default' => isset($_POST['to']) ? $_POST['to'] : '24:00:00'));
echo data_entry_helper::select(array('label' => 'level', 'labelClass' => 'auto', 'fieldname' => 'level', 'suffixTemplate' => 'nosuffix', 'default' => isset($_POST['level']) ? $_POST['level'] : 'debug', 'lookupValues' => array('4' => 'All messages', '3' => 'Errors, warnings and notices', '2' => 'Errors and warnings', '1' => 'Errors only')));
?>
<input type="submit" value="Go" />
</form>
<?php 
if (isset($_POST['file'])) {
    // A file has been selected, so output the filtered log content.
    $filename = DOCROOT . 'application/logs/' . $_POST['file'];
    if (file_exists($filename)) {
        $file = fopen($filename, 'r');
        if ($file === FALSE) {
            echo '<p class="page-notice">The log file could not be opened.</p>';
        } else {
            echo '<br/><h2>Showing log file for ' . str_replace('.log.php', '', $_POST['file']) . '</h2>';
            $time = '00:00:00';
            $threshold = 4;
Exemplo n.º 26
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     // Do they have expert access?
     $expert = function_exists('user_access') && user_access($args['permission']);
     $conn = iform_get_connection_details($node);
     $readAuth = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']);
     // Find out which types of filters and formats are available to the user
     $filters = self::get_filters($args, $readAuth);
     $formats = array();
     if ($args['csv_format'] === 'yes' || $args['csv_format'] === 'expert' && $expert) {
         $formats[] = 'csv';
     }
     if ($args['tsv_format'] === 'yes' || $args['tsv_format'] === 'expert' && $expert) {
         $formats[] = 'tsv';
     }
     if ($args['kml_format'] === 'yes' || $args['kml_format'] === 'expert' && $expert) {
         $formats[] = 'kml';
     }
     if ($args['gpx_format'] === 'yes' || $args['gpx_format'] === 'expert' && $expert) {
         $formats[] = 'gpx';
     }
     if ($args['nbn_format'] === 'yes' || $args['nbn_format'] === 'expert' && $expert) {
         $formats[] = 'nbn';
     }
     if (count($filters) === 0) {
         return 'This download page is configured so that no filter options are available.';
     }
     if (count($formats) === 0) {
         return 'This download page is configured so that no download format options are available.';
     }
     if (!empty($_POST)) {
         self::do_download($args, $filters);
     }
     iform_load_helpers(array('data_entry_helper'));
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         $reloadPath .= '?' . helper_base::array_to_query_string($reload['params']);
     }
     $r = '<form method="POST" action="' . $reloadPath . '">';
     $r .= '<fieldset><legend>' . lang::get('Filters') . '</legend>';
     if (count($filters) === 0) {
         return 'This download page is configured so that no filter options are available.';
     } elseif (count($filters) === 1) {
         $r .= '<input type="hidden" name="user-filter" value="' . implode('', array_keys($filters)) . '"/>';
         // Since there is only one option, we may as well tell the user what it is.
         drupal_set_title(implode('', array_values($filters)));
         if (implode('', array_keys($filters)) === 'mine') {
             $r .= '<p>' . lang::get('Use this form to download your own records.') . '</p>';
         }
     } else {
         $r .= data_entry_helper::radio_group(array('label' => lang::get('User filter'), 'fieldname' => 'user-filter', 'lookupValues' => $filters, 'default' => empty($_POST['user-filter']) ? 'mine' : $_POST['user-filter']));
     }
     if (empty($args['survey_id'])) {
         // A survey picker when downloading my data
         $r .= '<div id="survey_all">';
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id_all', 'label' => lang::get('Survey to include'), 'table' => 'survey', 'valueField' => 'id', 'captionField' => 'title', 'helpText' => 'Choose a survey, or <all> to not filter by survey.', 'blankText' => '<all>', 'class' => 'control-width-4', 'extraParams' => $readAuth + array('sharing' => 'data_flow', 'orderby' => 'title')));
         $r .= '</div>';
         // A survey picker when downloading data you are an expert for
         $surveys_expertise = hostsite_get_user_field('surveys_expertise');
         if ($surveys_expertise) {
             $surveys_expertise = unserialize($surveys_expertise);
             $surveysFilter = array('query' => json_encode(array('in' => array('id' => $surveys_expertise))));
         } else {
             // no filter as there are no specific surveys this user is an expert for
             $surveysFilter = array();
         }
         $r .= '<div id="survey_expertise">';
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id_expert', 'label' => lang::get('Survey to include'), 'table' => 'survey', 'valueField' => 'id', 'captionField' => 'title', 'helpText' => 'Choose a survey, or <all> to not filter by survey.', 'blankText' => '<all>', 'class' => 'control-width-4', 'extraParams' => $readAuth + array('sharing' => 'verification', 'orderby' => 'title') + $surveysFilter));
         $r .= '</div>';
     }
     // Let the user pick the date range to download.
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_from', 'label' => lang::get('Start Date'), 'helpText' => 'Leave blank for no start date filter', 'class' => 'control-width-4'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_to', 'label' => lang::get('End Date'), 'helpText' => 'Leave blank for no end date filter', 'class' => 'control-width-4'));
     $r .= '</fieldset>';
     $r .= '<fieldset><legend>' . lang::get('Downloads') . '</legend>';
     $r .= '<label>Download options:</label>';
     if (in_array('csv', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('Spreadsheet (CSV)') . '"/>';
     }
     if (in_array('tsv', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('Tab Separated File (TSV)') . '"/>';
     }
     if (in_array('kml', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('Google Earth File') . '"/>';
     }
     if (in_array('gpx', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('GPS Track File') . '"/>';
     }
     if (in_array('nbn', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('NBN Format') . '"/>';
         $r .= '<p class="helpText">' . lang::get('Note that the NBN format download will only include verified data and excludes records where the date or spatial reference is not compatible with the NBN Gateway.') . '</p>';
     }
     $r .= '</fieldset></form>';
     return $r;
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     $form = '<form action="#" method="POST" id="entry_form">';
     if ($_POST) {
         $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
         self::subscribe($args, $auth);
     } else {
         // don't bother with write auth for initial form load, as read auth is cached and faster
         $auth = array('read' => data_entry_helper::get_read_auth($args['website_id'], $args['password']));
     }
     if (!empty($_GET['id'])) {
         data_entry_helper::load_existing_record($auth['read'], 'species_alert', $_GET['id']);
         // enforce permissions
         if (data_entry_helper::$entity_to_load['species_alert:user_id'] != hostsite_get_user_field('indicia_user_id')) {
             return lang::get('You cannot modify a species alert subscription created by someone else');
         }
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:id', 'default' => $_GET['id']));
     }
     // if not logged in, then ask for details to register against
     global $user;
     if (!hostsite_get_user_field('id') || !isset($user) || empty($user->mail) || !hostsite_get_user_field('last_name')) {
         $form .= "<fieldset><legend>" . lang::get('Your details') . ":</legend>\n";
         $default = empty($_POST['first_name']) ? hostsite_get_user_field('first_name', '') : $_POST['first_name'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('First name'), 'fieldname' => 'first_name', 'validation' => array('required'), 'default' => $default, 'class' => 'control-width-4'));
         $default = empty($_POST['surname']) ? hostsite_get_user_field('last_name', '') : $_POST['surname'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('Last name'), 'fieldname' => 'surname', 'validation' => array('required'), 'default' => $default, 'class' => 'control-width-4'));
         $default = empty($_POST['email']) ? empty($user->mail) ? '' : $user->mail : $_POST['email'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('Email'), 'fieldname' => 'email', 'validation' => array('required', 'email'), 'default' => $default, 'class' => 'control-width-4'));
         $form .= "</fieldset>\n";
     } else {
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'first_name', 'default' => hostsite_get_user_field('first_name')));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'surname', 'default' => hostsite_get_user_field('last_name')));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'email', 'default' => $user->mail));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'user_id', 'default' => hostsite_get_user_field('indicia_user_id')));
     }
     $form .= "<fieldset><legend>" . lang::get('Alert criteria') . ":</legend>\n";
     // Output the species selection control
     // Default after saving with a validation failure can be pulled direct from the post, but
     // when reloading we don't need a default taxa taxon list ID since we already know the meaning
     // ID or external key.
     $default = empty($_POST['taxa_taxon_list_id']) ? '' : $_POST['taxa_taxon_list_id'];
     if (empty($_POST['taxa_taxon_list_id:taxon'])) {
         $defaultCaption = empty(data_entry_helper::$entity_to_load['species_alert:preferred_taxon']) ? '' : data_entry_helper::$entity_to_load['species_alert:preferred_taxon'];
     } else {
         $defaultCaption = $_POST['taxa_taxon_list_id:taxon'];
     }
     $form .= data_entry_helper::species_autocomplete(array('label' => lang::get('Alert species'), 'helpText' => lang::get('Select the species you are interested in receiving alerts in ' . 'relation to if you want to receive alerts on a single species.'), 'fieldname' => 'taxa_taxon_list_id', 'cacheLookup' => true, 'extraParams' => $auth['read'] + array('taxon_list_id' => $args['list_id']), 'class' => 'control-width-4', 'default' => $default, 'defaultCaption' => $defaultCaption));
     if (empty($default)) {
         // Unless we've searched for the species name then posted (and failed), then the
         // default will be empty. We might therefore be reloading existing data which has
         // a meaning ID or external key.
         if (!empty(data_entry_helper::$entity_to_load['species_alert:external_key'])) {
             $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:external_key', 'default' => data_entry_helper::$entity_to_load['species_alert:external_key']));
         } elseif (!empty(data_entry_helper::$entity_to_load['species_alert:taxon_meaning_id'])) {
             $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:taxon_meaning_id', 'default' => data_entry_helper::$entity_to_load['species_alert:taxon_meaning_id']));
         }
     }
     if (!empty($args['full_lists'])) {
         $form .= data_entry_helper::select(array('label' => lang::get('Select full species lists'), 'helpText' => lang::get('If you want to restrict the alerts to records of any ' . 'species within a species list, then select the list here.'), 'fieldname' => 'species_alert:taxon_list_id', 'blankText' => lang::get('<Select a species list>'), 'table' => 'taxon_list', 'valueField' => 'id', 'captionField' => 'title', 'extraParams' => $auth['read'] + array('id' => $args['full_lists'], 'orderby' => 'title'), 'class' => 'control-width-4'));
     }
     $form .= data_entry_helper::location_select(array('label' => lang::get('Select location'), 'helpText' => lang::get('If you want to restrict the alerts to records within a certain boundary, select it here.'), 'fieldname' => 'species_alert:location_id', 'id' => 'imp-location', 'blankText' => lang::get('<Select boundary>'), 'extraParams' => $auth['read'] + array('location_type_id' => $args['location_type_id'], 'orderby' => 'name'), 'class' => 'control-width-4'));
     $form .= data_entry_helper::checkbox(array('label' => lang::get('Alert on initial entry'), 'helpText' => lang::get('Tick this box if you want to receive a notification when the record is first input into the system.'), 'fieldname' => 'species_alert:alert_on_entry'));
     $form .= data_entry_helper::checkbox(array('label' => lang::get('Alert on verification as correct'), 'helpText' => lang::get('Tick this box if you want to receive a notification when the record has been verified as correct.'), 'fieldname' => 'species_alert:alert_on_verify'));
     $form .= "</fieldset>\n";
     $form .= '<input type="Submit" value="Subscribe" />';
     $form .= '</form>';
     data_entry_helper::enable_validation('entry_form');
     iform_load_helpers(array('map_helper'));
     $mapOptions = iform_map_get_map_options($args, $auth['read']);
     $map = map_helper::map_panel($mapOptions);
     global $indicia_templates;
     return str_replace(array('{col-1}', '{col-2}'), array($form, $map), $indicia_templates['two-col-50']);
 }
    /**
     * Return the generated form output.
     * @return Form HTML.
     */
    public static function get_form($args, $node)
    {
        $r = '';
        drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module');
        data_entry_helper::link_default_stylesheet();
        data_entry_helper::add_resource('jquery_ui');
        data_entry_helper::add_resource('openlayers');
        data_entry_helper::enable_validation('new-comments-form');
        // don't care about ID itself, just want resources
        data_entry_helper::add_resource('autocomplete');
        global $user;
        $uid = $user->uid;
        $email = $user->mail;
        $username = $user->name;
        // Get authorisation tokens to update and read from the Warehouse.
        $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
        $svcUrl = data_entry_helper::$base_url . '/index.php/services';
        // note we have to proxy the post. Every time a write transaction is carried out, the write nonce is trashed.
        // For security reasons we don't want to give the user the ability to generate their own nonce, so we use
        // the fact that the user is logged in to drupal as the main authentication/authorisation/identification
        // process for the user. The proxy also packages the post into the correct format
        // Two insect lists:
        // 1) list we are going to pick our old taxa from. This will only be those which data entry is no longer allowed.
        // 2) list of new taxa: This will only be those which data entry is allowed
        // the controls for the filter include all taxa, not just the ones allowed for data entry, just to be on the safe side.
        $source_insect_ctrl_args = array('label' => lang::get('Insect Species'), 'id' => 'insect-taxa-taxon-list-id', 'fieldname' => 'insect:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'listCaptionSpecialChars' => true, 'valueField' => 'id', 'columns' => 2, 'blankText' => lang::get('Choose Taxon'), 'extraParams' => $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order', 'allow_data_entry' => 'f'));
        $r .= '<h1 id="poll-banner"></h1>
<div id="refresh-message" style="display:none" ><p>' . lang::get('Please Refresh Page') . '</p></div>
<div id="filter" class="ui-accordion ui-widget ui-helper-reset">
	<div id="filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-accordion-content-active ui-corner-top">
	  	<div id="results-collections-title">
	  		<span>' . lang::get('Filter') . '</span>
    	</div>
	</div>
	<div id="filter-spec" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
	  <div class="ui-accordion ui-widget ui-helper-reset">
		<div id="insect-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
			<div id="insect-filter-title">
				<span>' . lang::get('Insect Filter') . '</span>
			</div>
		</div>
		<div id="insect-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all ui-accordion-content-active">
		  ' . data_entry_helper::select($source_insect_ctrl_args) . '
		  <label >' . lang::get('Status') . ':</label>
		  <span class="control-box "><nobr>
		    <span><input type="checkbox" value="X" id="insect_id_status:0" name="insect_id_status[]"><label for="insect_id_status:0">' . lang::get('Unidentified') . '</label></span></nobr> &nbsp; <nobr>
		    <span><input type="checkbox" value="A" id="insect_id_status:1" name="insect_id_status[]"><label for="insect_id_status:1">' . lang::get('Initial') . '</label></span></nobr> &nbsp; <nobr>
		    <span><input type="checkbox" value="B" id="insect_id_status:2" name="insect_id_status[]"><label for="insect_id_status:2">' . lang::get('Doubt') . '</label></span></nobr> &nbsp; <nobr>
		    <span><input type="checkbox" value="C" id="insect_id_status:3" name="insect_id_status[]"><label for="insect_id_status:3">' . lang::get('Validated') . '</label></span></nobr> &nbsp; 
		  </span>
		  <label >' . lang::get('Identification Type') . ':</label>
		  <span class="control-box "><nobr>
		    <span><input type="checkbox" value="seul" id="insect_id_type:0" name="insect_id_type[]"><label for="insect_id_type:0">' . lang::get('Single Taxon') . '</label></span></nobr> &nbsp; <nobr>
		    <span><input type="checkbox" value="multi" id="insect_id_type:1" name="insect_id_type[]"><label for="insect_id_type:1">' . lang::get('Multiple Taxa') . '</label></span></nobr> &nbsp; 
		  </span>
		</div>
	  </div>
	</div>
	<div id="filter-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
	  <div id="search-insects-button" class="ui-state-default ui-corner-all search-button">' . lang::get('Search Insects') . '</div>
	</div>
	<div id="results-reassignment-taxon-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	  <div id="results-reassignment-taxon-title">
	  	<span>' . lang::get('Actions To Be Taken') . '</span>
      </div>
	</div>
    <div id="results-reassignment-taxon" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-botton">
		<label >' . lang::get('Single?') . '</label><input type="checkbox" value="invalid" id="do-only-one" name="do-only-one"><br/>
		<label >' . lang::get('Becomes invalid?') . '</label><input type="checkbox" value="invalid" id="becomes-invalid" name="becomes-invalid"><br/>
		<label>New Taxa : </label><table id="new-insect-id-list"><thead><tr><th>Species</th><th>ID</th><th>Remove</th></tr></thead><tbody id="new-insect-id-list-body" class="new-id-list-body"><tr id="insectAutocompleteRow1" class="autocompleteRow"><td>' . lang::get('Add') . ' <input name="insectAutocomplete1" id="insectAutocomplete1" /></td><td><input name="insect2" id="insect2" /></td><td></td></tr></tbody></table>
    <form id="bulk-reassignment-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST" >
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
		<input type="hidden" name="determination:occurrence_id" value="" />
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />  
		<input type="hidden" name="determination:person_name" value="' . $username . '" />  
		<input type="hidden" name="determination:email_address" value="' . $email . '" />
		<input type="hidden" name="determination:determination_type" value="C" />
		<input type="hidden" name="determination:taxon_details" value="" />
		<input type="hidden" name="determination:taxa_taxon_list_id" value="" />
		<label >Comment : </label><textarea name="determination:comment" class=\\"taxon-comment\\" rows="3" style=\\"width: 480px;\\" />' . lang::get('Réaffectation majeure partie des taxons') . '</textarea>
		<input type="hidden" name="determination:taxon_extra_info" value="" />
	</form>
	  	<div id="reassign-button" class="ui-state-default ui-corner-all reassign-button">' . lang::get('Reassign Taxon') . '</div>
		<div id="reassign-progress"></div>
		<div id="reassign-message"></div>
		<div id="last-updated"></div>
	  	<div id="cancel-reassign-taxon" class="ui-state-default ui-corner-all cancel-reassign-button">' . lang::get('Cancel') . '</div>
	</div>
	<div id="results-insects-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	  <div id="results-insects-title">
	  	<span>' . lang::get('Search Results') . '</span>
      </div>
	</div>
	<div id="results-insects-results" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
    </div>
</div>
';
        $extraParams = $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'view' => 'list', 'allow_data_entry' => 't');
        $species_data_def = array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams);
        $taxa = data_entry_helper::get_population_data($species_data_def);
        data_entry_helper::$javascript .= "var insectTaxa = [";
        // No XPER ID here
        $taxa = data_entry_helper::get_population_data($species_data_def);
        $first = true;
        foreach ($taxa as $taxon) {
            data_entry_helper::$javascript .= ($first ? '' : ',') . '{id: ' . $taxon['id'] . ', taxon: "' . str_replace('"', '\\"', $taxon['taxon']) . '"}' . "\n";
            $first = false;
        }
        data_entry_helper::$javascript .= "];\nreplacechar = function(match){\n  switch(match) {\n    case '<':  return '&lt;';\n    case '>':  return '&gt;';\n    case '\"': return '&quot;';\n    case '\\'': return '&#039;';\n    case '&':  return '&amp;';\n    default: return match;\n  }\n};\n    \nhtmlspecialchars = function(value){ return value.replace(/[<>\"'&]/g, function(m){return replacechar(m)}) };\njQuery('#insect-taxa-taxon-list-id option').each(function(idx,elem){\n  jQuery(elem).html(jQuery(elem).html()+' ('+jQuery(elem).val()+')');\n});\n    \t\t\njQuery('input#insectAutocomplete1').autocomplete(insectTaxa,\n      { matchContains: true,\n        parse: function(data)\n        {\n          var results = [];\n          jQuery.each(data, function(i, item) {\n            results[results.length] = { 'data' : item, 'result' : item.id, 'value' : item.taxon };\n          });\n          return results;\n        },\n      formatItem: function(item) { return item.taxon; }\n      // {max}\n});\njQuery('input#insectAutocomplete1').result(function(event, data) {\n  jQuery('input#insectAutocomplete1').val('');\n  jQuery('input#insect2').val('');\n  if(jQuery('#new-insect-id-list-body input').filter('[value='+data.id+']').length == 0)\n    jQuery('#new-insect-id-list-body').find('.autocompleteRow').before('<tr class=\"new-id-list-entry\"><td>'+htmlspecialchars(data.taxon)+'</td><td><input type=\"hidden\" name=\"taxa_taxon_list_id_list\" value=\"'+data.id+'\"\\>'+data.id+'</td><td><img class=\"removeRow\" src=\"/misc/watchdog-error.png\" alt=\"" . lang::get('Remove this entry') . "\" title=\"" . lang::get('Remove this entry') . "\"/></td></tr>');\n  else\n    alert('" . lang::get('The chosen taxon is already in the replacement list.') . "');\n});\njQuery('input#insect2').change(function() {\n  jQuery('input#insectAutocomplete1').val('');\n  var value = jQuery('input#insect2').val();\n  jQuery('input#insect2').val('');\n  if(jQuery('#new-insect-id-list-body input').filter('[value='+value+']').length == 0)\n    for(var i=0; i<insectTaxa.length; i++){\n      if(value == insectTaxa[i].id){\n        jQuery('#new-insect-id-list-body').find('.autocompleteRow').before('<tr class=\"new-id-list-entry\"><td>'+htmlspecialchars(insectTaxa[i].taxon)+'</td><td><input type=\"hidden\" name=\"taxa_taxon_list_id_list\" value=\"'+value+'\"\\>'+value+'</td><td><img class=\"removeRow\" src=\"/misc/watchdog-error.png\" alt=\"" . lang::get('Remove this entry') . "\" title=\"" . lang::get('Remove this entry') . "\"/></td></tr>');\n        break;\n      }\n    }\n  else\n    alert('" . lang::get('The chosen taxon is already in the replacement list.') . "');\n});\njQuery('.removeRow').live('click', function (){ jQuery(this).closest('tr').remove(); });\nbulkAssigning=false;\nbulkCancel=false;\njQuery('#reassign-progress').progressbar({value: 0});\njQuery('form#bulk-reassignment-form').ajaxForm({\n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif(bulkCancel){\n\t\t\tbulkReassignFinish(\"" . lang::get('Bulk Reassignment Canceled') . "\");\n\t\t\treturn false;\n\t\t}\t\n\t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tvar form = jQuery('form#bulk-reassignment-form');\n\t\t\tvar dateObj = new Date();\n\t        var timeToday = dateObj.getHours() + ':' + dateObj.getMinutes() + ':' + dateObj.getSeconds();\n\t\t\tjQuery('.results-insects-record-'+form.find('[name=determination\\:occurrence_id]').val()).html(\"" . lang::get('Processed at ') . "\"+timeToday);\n\t\t\tjQuery('#last-updated').empty().append(\"" . lang::get('Last update at ') . "\"+timeToday);\n\t\t\tif(jQuery('#do-only-one').filter(':checked').length>0)\n\t\t\t\tbulkReassignFinish(\"" . lang::get('Bulk Reassignment Completed') . "\");\n\t\t\telse\n\t\t\t\tuploadReassignment();\n\t\t} else {\n\t\t\talert(data.error);\n\t\t\tbulkReassignFinish(\"" . lang::get('Bulk Reassignment Error') . "\");\n  \t\t}\n\t} \n});\n// Done: Convert single taxon\n// Done: allow filtering by single or multi taxa.\n// Done: Convert Multi taxa\n// Done: apply re-validation rule.\n// Done: allow single to multi explode.\n// Done: remove single at a time restriction.\n// Done: ensure no taxon duplication\n// Done: add value to end of taxon select options\n// Done: add second autocomplete to allow addition of row using id\n// Done: add timetag to processed text\n// TODO: Add counter to results list.\nuploadReassignment = function(){\n\tvar occID = false;\n\tvar max = jQuery('#reassign-progress').data('max');\n\tvar index = jQuery('#reassign-progress').data('index');\n\tjQuery('#reassign-progress').data('index',index+1);\n\tjQuery('#reassign-progress').progressbar('option','value',index*100/max);\n\tif(index<max){\n\t\toccID=searchResults.features[index].attributes.insect_id;\n\t\tjQuery('#reassign-message').html('<span>'+index+'/'+max+' : '+Math.round(index*100/max)+'%</span>');\n\t}\n\tif(occID && !bulkCancel){\n\t\t\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\"&reset_timeout=true&occurrence_id=\" + occID + \"&deleted=f&orderby=id&sortdir=DESC&REMOVEABLEJSONP&callback=?\", function(detData) {\n\t\t\tif(!(detData instanceof Array)){\n   \t\t\t\talertIndiciaError(detData);\n\t\t\t} else if (detData.length>0) {\n\t\t\t\t// only dealing with latest. no determination id as generating new record.\n\t\t\t\t// all reidentified taxon will have either a unidentified or Valid flag, so will not appear in this list, so doesn't matter if the taxon has changed.\n\t\t\t\tvar form = jQuery('form#bulk-reassignment-form');\n\t\t\t\tform.find('[name=determination\\:taxa_taxon_list_id_list\\[\\]]').remove();\n\t\t\t\tform.find('[name=determination\\:occurrence_id]').val(detData[0].occurrence_id);\n\t\t\t\tif(detData[0].taxa_taxon_list_id == jQuery('[name=insect\\:taxa_taxon_list_id]').val()) { // double check matches chosen taxa.\n\t\t\t\t\tif(jQuery('.new-id-list-entry').length == 1) // single->single replacement\n\t\t\t\t\t\tform.find('[name=determination\\:taxa_taxon_list_id]').val(jQuery('.new-id-list-entry input').val()); // only one\n\t\t\t\t\telse { // single->multiple replacement\n\t\t\t\t\t\tform.find('[name=determination\\:taxa_taxon_list_id]').val('');\n\t\t\t\t\t\tjQuery('.new-id-list-entry input').each(\n\t\t\t\t\t\t\tfunction(idx, elem){ // do not need to check for duplication here.\n\t\t\t\t\t\t\t\tjQuery('form#bulk-reassignment-form').append('<input type=\"hidden\" name=\"determination:taxa_taxon_list_id_list[]\" value=\"'+jQuery(elem).val()+'\" >');\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else\n\t\t\t\t\tform.find('[name=determination\\:taxa_taxon_list_id]').val(detData[0].taxa_taxon_list_id);\n\t\t\t\tform.find('[name=determination\\:taxon_details]').val(detData[0].taxon_details);\n\t\t\t\tform.find('[name=determination\\:taxon_extra_info]').val(detData[0].taxon_extra_info == null ? '' : detData[0].taxon_extra_info);\n\t\t\t\tif(jQuery('#becomes-invalid').filter(':checked').length>0 && detData[0].determination_type=='C')\n\t\t\t\t\tform.find('[name=determination\\:determination_type]').val('A');\n\t\t\t\telse\n\t\t\t\t\tform.find('[name=determination\\:determination_type]').val(detData[0].determination_type);\n\t\t\t\tvar decoded = (detData[0].taxa_taxon_list_id_list != null && detData[0].taxa_taxon_list_id_list != '' && detData[0].taxa_taxon_list_id_list != '{}') ? JSON.parse(detData[0].taxa_taxon_list_id_list.replace('{','[').replace('}',']')) : [];\n\t\t\t\tif(decoded.length>0)\n\t\t\t\t\tfor(var j=0; j < decoded.length; j++) {\n\t\t\t\t\t\tif(decoded[j] == jQuery('[name=insect\\:taxa_taxon_list_id]').val())\n\t\t\t\t\t\t\tjQuery('.new-id-list-entry input').each(\n\t\t\t\t\t\t\t\tfunction(idx, elem){\n\t\t\t\t\t\t\t\t\tif(jQuery('form#bulk-reassignment-form [name=determination\\:taxa_taxon_list_id_list\\[\\]]').filter('[value='+jQuery(elem).val()+']').length == 0)\n\t\t\t\t\t\t\t\t\t\tjQuery('form#bulk-reassignment-form').append('<input type=\"hidden\" name=\"determination:taxa_taxon_list_id_list[]\" value=\"'+jQuery(elem).val()+'\" >');\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tform.append('<input type=\"hidden\" name=\"determination:taxa_taxon_list_id_list[]\" value=\"'+decoded[j]+'\" >');\n\t\t\t\t\t}\n\t\t\t\tjQuery('form#bulk-reassignment-form').submit();\n\t\t\t}});\n\t} else {\n\t\tbulkReassignFinish(bulkCancel ? \"" . lang::get('Bulk Reassignment Canceled') . "\" : \"" . lang::get('Bulk Reassignment Completed') . "\");\n\t}\n}\nbulkReassignPrep=function(max){\n\tbulkAssigning=true; //switches off searches etc.\n\tbulkCancel=false;\n\tjQuery('#reassign-button').addClass('loading-button');\n\tjQuery('#reassign-progress,#cancel-reassign-taxon').show();\n\tjQuery('#reassign-message').empty();\n\tjQuery('#search-insects-button,#reassign-button').attr('disabled','disabled');\n\tjQuery('#reassign-message').html('<span>0/'+max+' : 0%</span>');\n\tjQuery('#reassign-progress').data('max',max).data('index',0).progressbar('option','value',0);\n}\nbulkReassignFinish=function(message){\n\tbulkCancel=false;\n\tbulkAssigning=false;\n\tjQuery('#reassign-button').removeClass('loading-button');\n\tjQuery('#reassign-progress,#cancel-reassign-taxon').hide();\n\tjQuery('#reassign-message').empty();\n\tif(message) jQuery('#reassign-message').html('<span>'+message+'</span>');\n\tjQuery('#search-insects-button,#reassign-button').removeAttr('disabled');\n}\nbulkReassignFinish(false);\njQuery('.cancel-reassign-button').click(function(){bulkCancel=true;});\njQuery('#reassign-button').click(function(){\n\tvar max=0;\n\tif(searchResults!= null) max=searchResults.features.length;\n\tbulkReassignPrep(max);\n\tif(jQuery('.new-id-list-entry').length==0) {\n\t\tbulkReassignFinish(\"" . lang::get('No replacement taxa defined.') . "\");\n\t} else if(max==0){\n\t\tbulkReassignFinish(\"" . lang::get('No identifications listed: nothing to do.') . "\");\n\t} else if(!confirm(\"" . lang::get('Are you sure you wish to carry out this bulk reassignment?') . "\")){\n\t\tbulkReassignFinish(false);\n\t\treturn;\n\t} else {\n\t\tuploadReassignment();\n\t}\n});\n\njQuery('#search-insects-button').click(function(){\n\tif(bulkAssigning) return; //prevent results changing underneath bulk reassignment\n\tjQuery('#results-insects-header').addClass('ui-state-active').removeClass('ui-state-default');\n\trunSearch();\n});\n\nfunction pad(number, length) {\n    var str = '' + number;\n    while (str.length < length) {\n        str = '0' + str;\n    }\n    return str;\n}\nrunSearch = function(){\n\tvar combineOR = function(ORgroup){ return (ORgroup.length > 1 ? new OpenLayers.Filter.Logical({type: OpenLayers.Filter.Logical.OR, filters: ORgroup}) : ORgroup[0]);};\n\n\tif(bulkAssigning) return; //prevent query changing underneath bulk reassignment\n  \tvar ORgroup = [];\n    jQuery('#results-insects-results,#reassign-message').empty();\n\tjQuery('#reassign-progress,#cancel-reassign-taxon').hide();\n\tjQuery('#results-reassign-taxon,#results-reassign-outer').hide();\n\tvar filters = [];\n\n  \t// filters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'survey_id', value: '" . $args['survey_id'] . "' }));\n \t\t\t\n\tvar insect = jQuery('select[name=insect\\:taxa_taxon_list_id]').val();\n\tif(insect == '') return;\n\tvar insect_taxon_filter = new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'insect_taxon_ids', value: '*|'+insect+'|*'});\n\tvar insect_statuses = jQuery('[name=insect_id_status\\[\\]]').filter('[checked]');\n  \tvar insect_taxon_types = jQuery('[name=insect_id_type\\[\\]]').filter('[checked]');\n\tfilters.push(insect_taxon_filter);\n\tORgroup = [];\n\tinsect_statuses.each(function(index, elem){\n\t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'status_insecte_code', value: elem.value}));\n\t});\n\tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n\tORgroup = [];\n\tinsect_taxon_types.each(function(index, elem){\n\t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'insect_taxon_type', value: elem.value}));\n\t});\n\tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n\t\n  \tfeature = '" . $args['search_insects_layer'] . "';\n  \tproperties = ['insect_id','collection_id','geom'];\n  \t\n\tsearchResults = null;  \n\tvar protocol = new OpenLayers.Protocol.WFS({\n              url: '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['search_url']) . "',\n              featurePrefix: '" . $args['search_prefix'] . "',\n              featureType: feature,\n              geometryName:'geom',\n              featureNS: '" . $args['search_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0',   \n              maxFeatures: " . $args['max_features'] . ",\n              propertyNames: properties,\n              callback: function(a1){\n                jQuery('#results-insects-results').empty();\n                if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n                  alert(\"" . lang::get('Insect search failed') . "\");\n                  return;\n                }\n                if(a1.features.length > 0) {\n                  jQuery('#results-insects-results').append('<p>" . lang::get('Number returned') . " : '+a1.features.length+'</p><table><thead><tr><th>#</th><th>" . lang::get('Collection') . "</th><th>" . lang::get('ID') . "</th><th>" . lang::get('Status') . "</th></tr></thead><tbody id=\"results-insects-table\"/></table>');\n                  for(var i=0; i<a1.features.length; i++){\n                    jQuery('#results-insects-table').append('<tr><td>'+(i+1)+'&nbsp; </td><td>'+a1.features[i].data.collection_id+'</td><td>'+a1.features[i].data.insect_id+'</td><td class=\"results-insects-record-'+a1.features[i].data.insect_id+'\">" . lang::get('Unprocessed') . "</td></tr>');\n                  }\n                  searchResults = a1;\n                } else\n                  jQuery('#results-insects-results').append('<p>" . lang::get('No species records returned') . "</p>');\n              }\n\t\t  });\n    jQuery('#results-insects-results').empty().append('<div class=\"insect-loading-panel\" ><img src=\"" . $base . drupal_get_path('module', 'iform') . "/media/images/ajax-loader2.gif\" />" . lang::get('Loading') . "...</div>');\n    protocol.read({filter: new OpenLayers.Filter.Logical({type: OpenLayers.Filter.Logical.AND, filters: filters})});\n};\n\nsearchResults = null;  \ncollection = '';\n";
        return $r;
    }
 private static function _build_package_control($args, &$packageAttr)
 {
     global $user;
     self::$multiPackageOptions = false;
     if (isset(data_entry_helper::$entity_to_load['sample:id']) && data_entry_helper::$entity_to_load['sample:id'] != "") {
         return '<input type="hidden" name="' . $packageAttr['fieldname'] . '" value="' . $packageAttr['default'] . '">';
     }
     $packageList = species_packages_get_packages($user->uid, $args['survey_id']);
     if ($packageList === false || !is_array($packageList) || count($packageList) == 0) {
         return '';
     }
     if (count($packageList) == 1) {
         // only one chosen, so no need to confuse the user by showing extra details.
         $packageAttr['default'] = $packageList[0];
         return '<input type="hidden" name="' . $packageAttr['fieldname'] . '" value="' . $packageList[0] . '">';
     } else {
         self::$multiPackageOptions = true;
         $options = array('blankText' => '<' . lang::get('Please select') . '>', 'fieldname' => $packageAttr['fieldname'], 'lookupValues' => array(), 'label' => lang::get('Species Package'), 'validation' => array('required'), 'helpText' => lang::get('You must select the species package, and then save the record, before you can enter data on the species tab.'));
         foreach ($packageList as $package) {
             $options['lookupValues'][$package] = species_packages_get_name($package);
         }
         return data_entry_helper::select($options);
     }
 }
echo data_entry_helper::hidden_text(array('fieldname' => 'location_medium:location_id', 'default' => html::initial_value($values, 'location_medium:location_id')));
?>
<legend>Media file details</legend>
<?php 
$mediaTypeId = html::initial_value($values, 'location_medium:media_type_id');
$mediaType = $mediaTypeId ? $other_data['media_type_terms'][$mediaTypeId] : 'Image:Local';
if ($mediaType === 'Image:Local') {
    echo '<label>Image:</label>';
    echo html::sized_image(html::initial_value($values, 'occurrence_medium:path')) . '</br>';
    echo data_entry_helper::hidden_text(array('fieldname' => 'location_medium:path', 'default' => html::initial_value($values, 'location_medium:path')));
    echo data_entry_helper::image_upload(array('label' => 'Upload image file', 'fieldname' => 'image_upload', 'default' => html::initial_value($values, 'location_medium:path')));
} else {
    echo data_entry_helper::text_input(array('label' => 'Path or URL', 'fieldname' => 'location_medium:path', 'default' => html::initial_value($values, 'location_medium:path'), 'class' => 'control-width-5'));
}
echo data_entry_helper::text_input(array('label' => 'Caption', 'fieldname' => 'location_medium:caption', 'default' => html::initial_value($values, 'location_medium:caption'), 'class' => 'control-width-5'));
if ($mediaTypeId && $mediaType !== 'Image:Local') {
    echo data_entry_helper::select(array('label' => 'Media type', 'fieldname' => 'location_medium:media_type_id', 'default' => $mediaTypeId, 'lookupValues' => $other_data['media_type_terms'], 'blankText' => '<Please select>', 'class' => 'control-width-5'));
}
?>

</fieldset>
<?php 
echo html::form_buttons($id != null, false, false);
data_entry_helper::$dumped_resources[] = 'jquery';
data_entry_helper::$dumped_resources[] = 'jquery_ui';
data_entry_helper::$dumped_resources[] = 'fancybox';
data_entry_helper::enable_validation('location-medium-edit');
data_entry_helper::link_default_stylesheet();
echo data_entry_helper::dump_javascript();
?>
</form>