Пример #1
0
 protected static function get_form_html($args, $auth, $attributes)
 {
     // @todo Process the available data to load subsamples (habitats) and associated records correctly.
     // toggle the checkboxes to after the label to match the form.
     global $indicia_templates;
     drupal_add_library('system', 'ui.tooltip', true);
     $indicia_templates['check_or_radio_group_item'] = '<li><label for="{itemId}">{caption}</label><input type="{type}" name="{fieldname}" id="{itemId}" value="{value}"{class}{checked}{title} {disabled}/></li>';
     // Create an array of custom attributes keyed by caption for easy lookup later
     foreach ($attributes as $attr) {
         self::$attrsByCaption[strtolower($attr['caption'])] = $attr;
     }
     // Build a list of the habitat-level attributes as well.
     $attributeOpts = array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $args['habitat_sample_method_id']);
     $habitatAttributes = data_entry_helper::getAttributes($attributeOpts, false);
     foreach ($habitatAttributes as $attr) {
         self::$habitatAttrsByCaption[strtolower($attr['caption'])] = $attr;
     }
     // load the habitat attribute values, if we have an existing sample
     if (!empty(self::$loadedSampleId)) {
         self::load_existing(self::$loadedSampleId, $auth);
     } else {
         data_entry_helper::$javascript .= "indiciaData.existingSubsampleData=[];\n";
     }
     // output some attribute info we can use for validation & business logic
     data_entry_helper::$javascript .= "indiciaData.depthMinLimitAttrNames = " . json_encode(array(self::$attrsByCaption['depth shallow bsl']['fieldname'], self::$attrsByCaption['depth shallow bcd']['fieldname'])) . ";\n";
     data_entry_helper::$javascript .= "indiciaData.depthMaxLimitAttrNames = " . json_encode(array(self::$attrsByCaption['depth deepest bsl']['fieldname'], self::$attrsByCaption['depth deepest bcd']['fieldname'])) . ";\n";
     data_entry_helper::$javascript .= "indiciaData.driftAttrId = " . self::$attrsByCaption['drift dive?']['attributeId'] . ";\n";
     data_entry_helper::$javascript .= "indiciaData.depthCDAttrName = '" . self::$attrsByCaption['tidal correction to chart datum']['fieldname'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.habitatMinDepthSLAttrId = " . self::$habitatAttrsByCaption['upper depth from sea level']['attributeId'] . ";\n";
     data_entry_helper::$javascript .= "indiciaData.habitatMaxDepthSLAttrId = " . self::$habitatAttrsByCaption['lower depth from sea level']['attributeId'] . ";\n";
     data_entry_helper::$javascript .= "indiciaData.habitatMinDepthCDAttrId = " . self::$habitatAttrsByCaption['upper depth from chart datum']['attributeId'] . ";\n";
     data_entry_helper::$javascript .= "indiciaData.habitatMaxDepthCDAttrId = " . self::$habitatAttrsByCaption['lower depth from chart datum']['attributeId'] . ";\n";
     return parent::get_form_html($args, $auth, $attributes);
 }
 /**
  * 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)
 {
     require_once drupal_get_path('module', 'iform') . '/client_helpers/map_helper.php';
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $settings = array('locationTypes' => helper_base::get_termlist_terms($auth, 'indicia:location_types', array('Transect Section')), 'locationId' => isset($_GET['section_id']) ? $_GET['section_id'] : null, 'parentId' => isset($_GET['transect_id']) ? $_GET['transect_id'] : null);
     if ($settings['parentId']) {
         $parent = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $settings['parentId'], 'deleted' => 'f'), 'nocache' => true));
         $settings['parent'] = $parent[0];
     } else {
         return 'This form must be called with a parent transect_id parameter.';
     }
     $settings['sections'] = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['parentId'], 'deleted' => 'f'), 'nocache' => true));
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
     } else {
         data_entry_helper::$entity_to_load['location:code'] = 'S' . (count($settings['sections']) + 1);
     }
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][0]['id']));
     if (data_entry_helper::$entity_to_load['location:code']) {
         $r = '<form method="post" id="input-form">';
     }
     $r .= $auth['write'];
     $r .= '<div id="controls">';
     $customAttributeTabs = array_merge(array('Section' => array('[*]')), get_attribute_tabs($settings['attributes']));
     if (count($customAttributeTabs) > 1) {
         $headerOptions = array('tabs' => array());
         foreach ($customAttributeTabs as $tab => $content) {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $headerOptions['tabs']['#' . $alias] = lang::get($tab);
         }
         $r .= data_entry_helper::tab_header($headerOptions);
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface'], 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
     }
     foreach ($customAttributeTabs as $tab => $content) {
         if ($tab == 'Section') {
             $r .= self::get_section_tab($auth, $args, $settings);
         } else {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $r .= "\n<div id=\"{$alias}\">\n";
             $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']), $tab);
             $r .= "</div>\n";
         }
     }
     $r .= '</div>';
     // controls
     $r .= '</form>';
     data_entry_helper::link_default_stylesheet();
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l('Home', '<front>');
         $breadcrumb[] = l('Sites', $args['sites_list_path']);
         $breadcrumb[] = l($settings['parent']['name'], $args['transect_edit_path'], array('query' => array('id' => $settings['parentId'])));
         $breadcrumb[] = $settings['locationId'] ? data_entry_helper::$entity_to_load['location:name'] : lang::get('new section');
         drupal_set_breadcrumb($breadcrumb);
     }
     return $r;
 }
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     if (empty($_GET['occurrence_id'])) {
         return 'This form requires an occurrence_id parameter in the URL.';
     }
     $r = "<form method=\"post\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     data_entry_helper::load_existing_record($auth['read'], 'occurrence', $_GET['occurrence_id']);
     data_entry_helper::load_existing_record($auth['read'], 'sample', data_entry_helper::$entity_to_load['occurrence:sample_id']);
     $r .= $auth['write'];
     $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . $_GET['occurrence_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"occurrence:sample_id\" name=\"occurrence:sample_id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
     $r .= "<div id=\"controls\">\n";
     $r .= "<table>\n";
     $r .= "<tr><td><strong>Date</strong></td><td>" . data_entry_helper::$entity_to_load['sample:date'] . "</td></tr>\n";
     $r .= "<tr><td><strong>Spatial Reference</strong></td><td>" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "</td></tr>\n";
     $siteLabels = array();
     if (!empty(data_entry_helper::$entity_to_load['sample:location'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location'];
     }
     if (!empty(data_entry_helper::$entity_to_load['sample:location_name'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location_name'];
     }
     $r .= "<tr><td><strong>Site</strong></td><td>" . implode(' | ', $siteLabels) . "</td></tr>\n";
     $smpAttrs = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'extraParams' => $auth['read'], 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $occAttrs = data_entry_helper::getAttributes(array('id' => $_GET['occurrence_id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'extraParams' => $auth['read'], 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $attributes = array_merge($smpAttrs, $occAttrs);
     foreach ($attributes as $attr) {
         $r .= "<tr><td><strong>" . $attr['caption'] . "</strong></td><td>" . $attr['displayValue'] . "</td></tr>\n";
     }
     $extraParams = $auth['read'] + array('taxon_list_id' => $args['list_id']);
     if ($args['preferred']) {
         $extraParams += array('preferred' => 't');
     }
     $species_list_args = array('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 .= '<tr/><td><strong>Species</strong></td><td>' . call_user_func(array('data_entry_helper', $args['species_ctrl']), $species_list_args) . "</td></tr>\n";
     $r .= "</table>\n";
     $r .= "</div>\n";
     $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     $r .= "</form>";
     return $r;
 }
Пример #4
0
 protected static function getAttributes($args, $auth)
 {
     $id = isset(data_entry_helper::$entity_to_load['location:id']) ? data_entry_helper::$entity_to_load['location:id'] : null;
     $attrOpts = array('id' => $id, 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
     $attributes = data_entry_helper::getAttributes($attrOpts, false);
     return $attributes;
 }
Пример #5
0
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     require_once drupal_get_path('module', 'iform') . '/client_helpers/map_helper.php';
     $hidden = str_replace("\r\n", "\n", $args['hide_fields']);
     $hidden = explode("\n", $hidden);
     if (empty($_GET['occurrence_id'])) {
         return 'This form requires an occurrence_id parameter in the URL.';
     }
     // Get authorisation tokens to update and read from the Warehouse.
     $auth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     data_entry_helper::load_existing_record($auth, 'occurrence', $_GET['occurrence_id']);
     data_entry_helper::load_existing_record($auth, 'sample', data_entry_helper::$entity_to_load['occurrence:sample_id']);
     $r .= "<div id=\"controls\">\n";
     $r .= "<table>\n";
     if (!in_array('Species', $hidden)) {
         $r .= "<tr><td><strong>" . lang::get('Species') . "</strong></td><td>" . data_entry_helper::$entity_to_load['occurrence:taxon'] . "</td></tr>\n";
     }
     if (!in_array('Date', $hidden)) {
         $r .= "<tr><td><strong>Date</strong></td><td>" . data_entry_helper::$entity_to_load['sample:date'] . "</td></tr>\n";
     }
     if (!in_array('Grid Reference', $hidden)) {
         $r .= "<tr><td><strong>Grid Reference</strong></td><td>" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "</td></tr>\n";
     }
     $siteLabels = array();
     if (!empty(data_entry_helper::$entity_to_load['sample:location'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location'];
     }
     if (!empty(data_entry_helper::$entity_to_load['sample:location_name'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location_name'];
     }
     if (!in_array('Site', $hidden) && !empty($siteLabels)) {
         $r .= "<tr><td><strong>Site</strong></td><td>" . implode(' | ', $siteLabels) . "</td></tr>\n";
     }
     $smpAttrs = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'extraParams' => $auth, 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $occAttrs = data_entry_helper::getAttributes(array('id' => $_GET['occurrence_id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'extraParams' => $auth, 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $attributes = array_merge($smpAttrs, $occAttrs);
     foreach ($attributes as $attr) {
         if (!in_array($attr['caption'], $hidden)) {
             $r .= "<tr><td><strong>" . lang::get($attr['caption']) . "</strong></td><td>" . $attr['displayValue'] . "</td></tr>\n";
         }
     }
     $r .= "</table>\n";
     $r .= "</div>\n";
     $options = iform_map_get_map_options($args, $readAuth);
     $olOptions = iform_map_get_ol_options($args);
     $options['initialFeatureWkt'] = data_entry_helper::$entity_to_load['occurrence:wkt'];
     $r .= map_helper::map_panel($options, $olOptions);
     return $r;
 }
Пример #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';
        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('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']));
        $defNRAttrOptions = array('extraParams' => $readAuth + array('orderby' => 'id'), 'lookUpListCtrl' => 'radio_group', 'lookUpKey' => 'meaning_id', 'language' => iform_lang_iso_639_2($args['language']), 'containerClass' => 'group-control-box', 'sep' => ' &nbsp; ', 'suffixTemplate' => 'nosuffix');
        $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>';
        $r .= data_entry_helper::loading_block_start();
        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 .= "];";
        // 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="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="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=""/>
 	' . 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 id="cc-1-valid-button" class="ui-state-default ui-corner-all save-button">' . lang::get('LANG_Validate') . '</div>
  </div>
  <div id="cc-1-trailer" class="poll-section-trailer">
    <div id="cc-1-trailer-image" ><img src="' . helper_config::$base_url . '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');\njQuery('.loading-hide').hide().addClass('my-loading-hide').removeClass('loading-hide');\n// can't use shuffle to side as dynamic generated code does like it in IE7\n\n\$.fn.foldPanel = function(){\n\tthis.children('.poll-section-body').hide();\n\tthis.children('.poll-section-footer,.poll-section-trailer').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').show();\n\tthis.children('.poll-section-footer,.poll-section-trailer').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\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').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\t// TODO Map\n\tthis.find('.thumb').filter('not(.blankPhoto)').remove();\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('.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');\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  };\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\$('.loading-hide').removeClass('loading-hide');\n\tjQuery('#cc-1').hide();\n\tjQuery('#refresh-message').show();\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};\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 = '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['ID_tool_insect_poll_dir']) . "'+insectSess;\n\tvar flowerURL = '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['ID_tool_flower_poll_dir']) . "'+flowerSess;\n\tif(settings.url != flowerURL && settings.url != insectURL){\n\t   alert(\"" . lang::get('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_date') . "');\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        \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[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  \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('#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 instanceof Array)){\n   \t\t\t\t\t\talertIndiciaError(data);\n   \t\t\t\t\t} else if (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', true);\n\t\t\t\t\t\t}\n\t\t\t\t});\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[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  \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(flowerIDstruc);\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\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';
        $options['suffixTemplate'] = 'nosuffix';
        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('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' => $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>
          <input type="hidden" id="flower:taxon_details" name="flower:taxon_details" />
          <input type="hidden" name="flower:determination_type" value="A" />  
   	      <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>
 	      <p id="flower_taxa_list"></p>
 	    </div>
 	    <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>
 	    <div class="id-specified-group">
 	      ' . data_entry_helper::select($species_ctrl_args) . '
          <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" class="follow-on">' . lang::get('LANG_ID_Comment') . ' </label>
        <textarea id="flower:comment" name="flower:comment" class="taxon-comment" rows="5" columns="80"></textarea>
      </div>
    </div>
    <div class="poll-break"></div>
 	<div id="cc-2-environment">
	  <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" 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_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="" />
      ' . 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['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)) . '
    	<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="' . 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', 'suffixTemplate' => 'nosuffix')) . '
 	  </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 .= "\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});\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({filter: filter});\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\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\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\t\$.get(toolStruct.pollURL+toolStruct.pollFile, function(data){\n\t  pollReset(toolStruct);\n\t  var da = data.split('\\n');\n      jQuery(toolStruct.selector+' [name='+toolStruct.type+'\\: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('#'+toolStruct.type+'_taxa_list').append(\"" . lang::get('LANG_Taxa_Unknown_In_Tool') . "\");\n\t  \tjQuery(toolStruct.selector+' [name='+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\titemText = items[j].replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\t\t\tvar found = false;\n\t\t\tfor(i = 0; i< toolStruct.taxaList.length; i++){\n  \t\t\t\tif(toolStruct.taxaList[i].taxon == itemText){\n\t  \t\t\t\tresultsIDs.push(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('#'+toolStruct.type+'_taxa_list').append(resultsText+ ' }');\n\t\tjQuery('#'+toolStruct.type+'-id-button').data('toolRetValues', resultsIDs);\n\t  \tif(notFound != ''){\n\t\t\tvar comment = jQuery(toolStruct.selector+' [name='+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\tjQuery('#'+toolStruct.type+'-id-button').data('toolRetValues', []);\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_details]').val('');\n\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\ttoolStruct.pollFile='';\n\ttoolStruct.timeOutTimer = null;\n\ttoolStruct.pollTimer = null;\n};\n\nidButtonPressed = function(toolStruct){\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:determination_type]').val('A');\n\tjQuery('#id-'+toolStruct.type+'-later').removeAttr('checked');\n\tjQuery('#'+toolStruct.type+'-id-button').data('toolRetValues', []);\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.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('#id-'+toolStruct.type+'-later').removeAttr('checked');\n\tjQuery('#'+toolStruct.type+'-id-button').data('toolRetValues', []);\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_details]').val('');\n\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:comment]').val('');\n  \tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:determination_type]').val('A');\n};\njQuery('#cc-2-flower-identify select[name=flower\\:taxa_taxon_list_id]').change(function(){\n\tpollReset(flowerIDstruc);\n\ttaxonChosen(flowerIDstruc);\n});\n\nidLater = function (toolStruct){\n\tif (jQuery('#id-'+toolStruct.type+'later').attr('checked') != '') {\n\t  \tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:determination_type]').val('A');\n\t\tjQuery('#'+toolStruct.type+'-id-button').data('toolRetValues', []);\n\t\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_details]').val('');\n\t\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\t\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxa_taxon_list_id]').val('');\n\t\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:taxon_extra_info]').val(''); // more precise info\n\t\tjQuery(toolStruct.selector+' [name='+toolStruct.type+'\\:comment]').val('');\n\t}\n};\njQuery('#id-flower-later').change(function (){\n\tpollReset(flowerIDstruc);\n\tidLater(flowerIDstruc);\n});\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    });\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\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('#cc-2-flower-identify select[name=flower\\:taxa_taxon_list_id]').val() == '' &&\n\t\t\tjQuery('[name=flower\\:taxon_details]').val() == '' &&\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\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') == '' &&\t jQuery('[name=flower\\:taxon_details]').val() == ''){\n\t\tif(!validateRequiredField('flower\\:taxa_taxon_list_id', '#cc-2-flower-identify')) { valid = 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 (!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   \t\t\t\treturn false;\n   \t\t\t}\n        \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]);\n\t        \tinsertImage('med-'+data.files[0], jQuery('#cc-2-flower-image'), " . $args['Flower_Image_Ratio'] . ");\n\t\t\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]);\n\t        \tinsertImage('med-'+data.files[0], 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 (!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\tdata[findID('determination:taxa_taxon_list_id', data)].value = jQuery('#cc-2-flower-identify select[name=flower\\:taxa_taxon_list_id]').val();\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 (jQuery('#cc-2-flower-identify [name=flower\\:taxon_details]').val() == ''){\n\t\t\t\tif (!validateRequiredField('flower\\:taxa_taxon_list_id', '#cc-2-flower-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 = jQuery('#flower-id-button').data('toolRetValues');\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\tdata.splice(10,8); // remove determination entries.\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    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', true);\n       \t\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+\"&deleted=f&callback=?\", function(occdata) {\n\t\t\t\tif(!(occdata instanceof Array)){\n   \t\t\t\t\talertIndiciaError(occdata);\n   \t\t\t\t} else if (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', false);\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 instanceof Array)){\n   \t\t\t\t\t\t\talertIndiciaError(imgdata);\n   \t\t\t\t\t\t} else 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\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 instanceof Array)){\n   \t\t\t\t\talertIndiciaError(data);\n   \t\t\t\t} else if (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        }  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        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        \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}\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    if (!jQuery(this).children('input').valid()) { valid = false; }\n   \t\tif (!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 (!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) {\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);";
        }
        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']], $defNRAttrOptions)) . "').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\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\t// shade is a boolean, and will always have one set, default no\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('sample_attribute_value', 'sample_attribute_id', 'sample_id', 'sample\\:id', data.outer_id, 'smpAttr', 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    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\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\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', 'valueField' => 'id', 'columns' => 2, '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 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" class="follow-on">' . lang::get('LANG_ID_Comment') . ' </label>
        <textarea id="insect:comment" name="insect:comment" class="taxon-desc" rows="5" columns="80" ></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" />
	    <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')) . 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']], $defNRAttrOptions)) . '
    </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 .= "\n\ninsectIDstruc = {\n\ttype: 'insect',\n\tselector: '#cc-4-insect-identify',\n\tmainForm: '#cc-4-main-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\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('#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]);\n\t        \tinsertImage('med-'+data.files[0], 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\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 = jQuery('#insect-id-button').data('toolRetValues');\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\tdata.splice(4,8); // remove determination entries.\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\tupdatePhotoReel(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\tjQuery('#insect-id-button').data('toolRetValues',[]);\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\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    populateSessionSelect();\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('occurrence_attribute_value', 'occurrence_attribute_id', 'occurrence_id', 'occurrence\\:id', id, 'occAttr', true);\n\tloadImage('occurrence_image', 'occurrence_id', 'occurrence\\:id', id, '#cc-4-insect-image', " . $args['Insect_Image_Ratio'] . ");\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}\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\nupdatePhotoReel = 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 () {setInsect(occId)});\n\telse\n\t\tcontainer.empty();\n\tjQuery('<span>?</span>').addClass('thumb-text').appendTo(container);\n\t// the picture can be async but the determination can'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        data: {}, \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\tcontainer.find('.thumb-text').remove();\n\t    \t}\n  \t\t}, \n    \tdataType: 'json', \n\t    async: false \n    });\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\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}\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\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\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(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\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('.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="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-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 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  \t\t\tjQuery('#cc-5-complete-collection').addClass('loading-button');\n        \tdata[2].value = jQuery('#cc-1-collection-details input[name=sample\\:id]').val();\n\t\t\tdata[3].value = '';\n\t\t\tdata[4].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(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[3].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[4].value = sessDate;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(data[3].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\tif(data[3].value == data[4].value){\n\t       \t\tdata[5].value = 'D';\n\t       \t} else {\n\t       \t\tdata[5].value = 'DD';\n  \t\t\t}\n\t       \tjQuery('#cc-1-collection-details,#cc-2').find('[name=sample\\:date]:hidden').val(data[3].value);\n  \t\t\tdata[6].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>';
        data_entry_helper::$javascript .= "\n \t\t\t\nloadAttributes = function(attributeTable, attributeKey, key, keyName, keyValue, prefix, reset_timeout){\n\tvar form = jQuery('input[name='+keyName+'][value='+keyValue+']').parents('form');\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    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        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\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\t  checkProtocolStatus('leave');\n\t\t  populateSessionSelect();\n\t\t},\n\t\tdataType: 'json', \n\t    async: false  \n\t});\n}\n\nloadImage = function(imageTable, key, keyName, keyValue, target, ratio){\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}\n\t});\n}\n\nloadDetermination = function(detData, toolStruc){\n\tjQuery('#'+toolStruc.type+'_taxa_list').empty();\n\tjQuery('#'+toolStruc.type+'-id-button').data('toolRetValues', []);\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);\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;') + 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\tjQuery('#'+toolStruc.type+'-id-button').data('toolRetValues', resultsIDs);\n  \t\t}\n\t} else {\n\t\tjQuery('#id-'+toolStruc.type+'-later').attr('checked', 'checked');\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();\njQuery('#flower-id-button').data('toolRetValues',[]);\njQuery('#insect-id-button').data('toolRetValues',[]);\njQuery('#flower_taxa_list').empty();\njQuery('#insect_taxa_list').empty();\n\t\njQuery.ajax({ \n    type: 'GET', \n    url: \"" . $svcUrl . "\" + \"/report/requestReport?report=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    dataType: 'json', \n    success: function(data) {\n\t  if(!(data instanceof Array)){\n   \t\talertIndiciaError(data);\n   \t  } else if (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', false);\n  \t\t\t\tvar locData = [];\n  \t\t\t\tjQuery.ajax({ \n\t\t\t\t\ttype: 'GET', \n\t\t\t\t\turl: \"" . $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=?\", \n\t\t\t\t\tdataType: 'json', \n\t\t\t\t\tsuccess: function(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\t    locData = locationdata;\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\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', " . $args['Environment_Image_Ratio'] . ", false);\n  \t\t\t\t\t  }\n  \t\t\t\t\t}, \n\t\t\t\t\tdata: {}, \n\t\t\t\t\tasync: false \n\t\t\t\t});\n  \t\t\t\tjQuery.ajax({ \n\t\t\t\t\ttype: 'GET', \n\t\t\t\t\turl: \"" . $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+\"&deleted=f&callback=?\", \n\t\t\t\t\tdataType: 'json', \n\t\t\t\t\tsuccess: 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\t  if(!(flowerData instanceof Array)){\n\t\t\t\t\t\talertIndiciaError(flowerData);\n\t\t\t\t\t  } else if (flowerData.length>0) {\n\t\t\t\t\t\t// The location only holds a valid place if the floral station has been saved: because \n\t\t\t\t\t\t// the location is saved on cc-1 (due to FK constraints), we use the presence of the flower\n\t\t\t\t\t\t// occurrence as the indicator of FS saving. Only load location location at this point.\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\tjQuery('input[name=location\\:centroid_sref]').val(locData[0].centroid_sref);\n\t\t\t\t\t\tjQuery('input[name=location\\:centroid_sref_system]').val(locData[0].centroid_sref_system);\n\t\t\t\t\t\tjQuery('input[name=location\\:centroid_geom]').val(locData[0].centroid_geom);\n\t\t\t\t\t\tjQuery('#imp-sref').change();\n\t\t\t\t\t\tvar parts=locData[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\n\t\t\t\t\t\t\$('#cc-1').foldPanel();\n\t\t\t\t\t\tcheckProtocolStatus(true);\n\t\t\t\t\t\t\$('#cc-2').showPanel();\n\t\t\t\t\t\tjQuery('form#cc-2-floral-station > input[name=occurrence\\:sample_id]').val(data[i].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\t\tloadAttributes('occurrence_attribute_value', 'occurrence_attribute_id', 'occurrence_id', 'occurrence\\:id', flowerData[0].id, 'occAttr', false);\n\t\t\t\t\t\tloadImage('occurrence_image', 'occurrence_id', 'occurrence\\:id', flowerData[0].id, '#cc-2-flower-image', " . $args['Flower_Image_Ratio'] . ");\n\n\t\t\t\t\t\tjQuery.ajax({ \n\t\t\t\t\t\t\ttype: 'GET', \n\t\t\t\t\t\t\turl: \"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&occurrence_id=\"+flowerData[0].id+\"&orderby=id&deleted=f&callback=?\", \n\t\t\t\t\t\t\tdataType: 'json', \n\t\t\t\t\t\t\tsuccess: function(detData) {\n\t\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 loadDetermination(detData, flowerIDstruc);\n  \t\t\t\t\t\t\t}, \n\t\t\t\t\t\t\tdata: {}, \n\t\t\t\t\t\t\tasync: false \n\t\t\t\t\t\t});\n    \t      \t\t\t\t  \n    \t   \t\t\t\tjQuery.ajax({ \n\t\t\t\t\t\t\ttype: 'GET', \n\t\t\t\t\t\t\turl: \"" . $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=?\", \n\t\t\t\t\t\t\tdataType: 'json', \n\t\t\t\t\t\t\tsuccess: function(sessiondata) {\n\t    \t\t\t  \t\t  if(!(sessiondata instanceof Array)){\n   \t\t\t\t\t\t\t\talertIndiciaError(sessiondata);\n   \t\t\t\t\t  \t\t  } else if (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\t\tjQuery('input[name=dummy_date]', thisSession).datepicker('disable').datepicker('setDate', new Date(sessiondata[i].date_start)).datepicker('enable');\n\t\t\t\t\t\t\t\t\tloadAttributes('sample_attribute_value', 'sample_attribute_id', 'sample_id', 'sample\\:id', sessiondata[i].id, 'smpAttr', false);\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+\"&deleted=f&callback=?\", function(insectData) {\n\t\t    \t\t\t\t\t\t\tif(!(insectData instanceof Array)){\n   \t\t\t\t\t\t\t\t\t\t\talertIndiciaError(insectData);\n   \t\t\t\t\t  \t\t  \t\t\t} else if (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\tupdatePhotoReel(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}, \n\t\t\t\t\t\t\tdata: {}, \n\t\t\t\t\t\t\tasync: false \n\t\t\t\t\t\t});\n    \t   \t\t\t  }\n  \t\t\t\t\t}, \n\t\t\t\t\tdata: {}, \n\t\t\t\t\tasync: false \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  }}, \n    data: {}, \n    async: false \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::loading_block_end();
        data_entry_helper::$onload_javascript = "jQuery('.my-loading-hide').addClass('loading-hide').removeClass('my-loading-hide');\n" . data_entry_helper::$onload_javascript . "\nbuildMap();";
        return $r;
    }
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values.
  * @param array $args iform parameters.
  * @return array Submission structure.
  * @todo: Implement this method
  */
 public static function get_submission($values, $args)
 {
     $subsampleModels = array();
     if (isset($values['page']) && $values['page'] == 'speciesmap') {
         $submission = data_entry_helper::build_sample_subsamples_occurrences_submission($values);
     } else {
         if (!isset($values['page']) || $values['page'] == 'mainSample') {
             // submitting the first page, with top level sample details
             $read = array('nonce' => $values['read_nonce'], 'auth_token' => $values['read_auth_token']);
             if (!isset($values['sample:entered_sref'])) {
                 // the sample does not have sref data, as the user has just picked a transect site at this point. Copy the
                 // site's centroid across to the sample. Should this be cached?
                 $site = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $read + array('view' => 'detail', 'id' => $values['sample:location_id'], 'deleted' => 'f')));
                 $site = $site[0];
                 $values['sample:entered_sref'] = $site['centroid_sref'];
                 $values['sample:entered_sref_system'] = $site['centroid_sref_system'];
             }
             // Build the subsamples
             $sections = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $read + array('view' => 'detail', 'parent_id' => $values['sample:location_id'], 'deleted' => 'f'), 'nocache' => true));
             if (isset($values['sample:id'])) {
                 $existingSubSamples = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $read + array('view' => 'detail', 'parent_id' => $values['sample:id'], 'deleted' => 'f'), 'nocache' => true));
             } else {
                 $existingSubSamples = array();
             }
             $sampleMethods = helper_base::get_termlist_terms(array('read' => $read), 'indicia:sample_methods', array('Transect Section'));
             $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $read, 'survey_id' => $values['sample:survey_id'], 'sample_method_id' => $sampleMethods[0]['id'], 'multiValue' => false));
             $smpDate = self::parseSingleDate($values['sample:date']);
             foreach ($sections as $section) {
                 $smp = false;
                 $exists = false;
                 foreach ($existingSubSamples as $existingSubSample) {
                     if ($existingSubSample['location_id'] == $section['id']) {
                         $exists = $existingSubSample;
                         break;
                     }
                 }
                 if (!$exists) {
                     $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('survey_id' => array('value' => $values['sample:survey_id']), 'website_id' => array('value' => $values['website_id']), 'date' => array('value' => $values['sample:date']), 'location_id' => array('value' => $section['id']), 'entered_sref' => array('value' => $section['centroid_sref']), 'entered_sref_system' => array('value' => $section['centroid_sref_system']), 'sample_method_id' => array('value' => $sampleMethods[0]['id']))), 'copyFields' => array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'));
                     foreach ($attributes as $attr) {
                         foreach ($values as $key => $value) {
                             $parts = explode(':', $key);
                             if (count($parts) > 1 && $parts[0] == 'smpAttr' && $parts[1] == $attr['attributeId']) {
                                 $smp['model']['fields']['smpAttr:' . $attr['attributeId']] = array('value' => $value);
                             }
                         }
                     }
                 } else {
                     // need to ensure any date change is propagated: only do if date has changed for performance reasons.
                     $subSmpDate = self::parseSingleDate($exists['date_start']);
                     if (strcmp($smpDate, $subSmpDate)) {
                         $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('survey_id' => array('value' => $values['sample:survey_id']), 'website_id' => array('value' => $values['website_id']), 'id' => array('value' => $exists['id']), 'date' => array('value' => $values['sample:date']), 'location_id' => array('value' => $exists['location_id']))), 'copyFields' => array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'));
                     }
                 }
                 if ($smp) {
                     $subsampleModels[] = $smp;
                 }
             }
         }
         $submission = submission_builder::build_submission($values, array('model' => 'sample'));
         if (count($subsampleModels) > 0) {
             $submission['subModels'] = $subsampleModels;
         }
     }
     return $submission;
 }
 public static function mnhnl_reptiles_species_checklist()
 {
     global $indicia_templates;
     $options = data_entry_helper::check_arguments(func_get_args(), array('listId', 'occAttrs', 'readAuth', 'extraParams', 'lookupListId'));
     $options = data_entry_helper::get_species_checklist_options($options);
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     $occAttrControls = array();
     $occAttrs = array();
     // Load any existing sample's occurrence data into $entity_to_load
     $subSamples = array();
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         data_entry_helper::preload_species_checklist_occurrences(data_entry_helper::$entity_to_load['sample:id'], $options['readAuth'], false, array(), $subSamples, false);
     }
     // load the full list of species for the grid, including the main checklist plus any additional species in the reloaded occurrences.
     $options['extraParams']['view'] = 'detail';
     $occList = self::get_species_checklist_occ_list($options);
     // If we managed to read the species list data we can proceed
     if (!array_key_exists('error', $occList)) {
         $attributes = data_entry_helper::getAttributes(array('id' => null, 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => "{fieldname}", 'extraParams' => $options['readAuth'], 'survey_id' => array_key_exists('survey_id', $options) ? $options['survey_id'] : null));
         // Get the attribute and control information required to build the custom occurrence attribute columns
         data_entry_helper::species_checklist_prepare_attributes($options, $attributes, $occAttrControls, $occAttrs);
         $grid = "<p>" . lang::get('LANG_SpeciesInstructions') . "</p>\n";
         if (isset($options['lookupListId'])) {
             $grid .= self::get_species_checklist_clonable_row($options, $occAttrControls, $attributes);
         }
         $grid .= '<table class="ui-widget ui-widget-content mnhnl-species-grid ' . $options['class'] . '" id="' . $options['id'] . '">';
         $grid .= self::get_species_checklist_header($options, $occAttrs);
         $rows = array();
         $rowIdx = 0;
         foreach ($occList as $occ) {
             $ttlid = $occ['taxon']['id'];
             $firstCell = data_entry_helper::mergeParamsIntoTemplate($occ['taxon'], 'taxon_label', false, true);
             if ($options['PHPtaxonLabel']) {
                 $firstCell = eval($firstCell);
             }
             $colspan = ' colspan="' . count($attributes) . '"';
             // assume always removeable and presence is hidden.
             $firstrow = '<td class="ui-state-default remove-row" style="width: 1%" rowspan="' . ($options['occurrenceComment'] ? "3" : "2") . '" >X</td>';
             $firstrow .= str_replace('{content}', $firstCell, str_replace('{colspan}', $colspan, $indicia_templates['taxon_label_cell']));
             $existing_record_id = $occ['id'];
             $hidden = $options['rowInclusionCheck'] == 'checkbox' ? '' : ' style="display:none"';
             if ($options['rowInclusionCheck'] == 'alwaysFixed' || $options['rowInclusionCheck'] == 'alwaysRemovable' || data_entry_helper::$entity_to_load != null && array_key_exists("sc:{$ttlid}:{$existing_record_id}:present", data_entry_helper::$entity_to_load)) {
                 $checked = ' checked="checked"';
             } else {
                 $checked = '';
             }
             $secondrow = "<td class=\"scPresenceCell\"{$hidden}>" . ($options['rowInclusionCheck'] != 'hasData' ? "<input type=\"hidden\" class=\"scPresence\" name=\"sc:{$ttlid}:{$existing_record_id}:present\" value=\"0\"/><input type=\"checkbox\" class=\"scPresence\" name=\"sc:{$ttlid}:{$existing_record_id}:present\" {$checked} />" : '') . "</td>";
             foreach ($occAttrControls as $attrId => $control) {
                 if ($existing_record_id) {
                     $search = preg_grep("/^sc:" . $ttlid . "[_[0-9]*]?:{$existing_record_id}:occAttr:{$attrId}" . '[:[0-9]*]?$/', array_keys(data_entry_helper::$entity_to_load));
                     $ctrlId = count($search) === 1 ? implode('', $search) : "sc:{$ttlid}:{$existing_record_id}:occAttr:{$attrId}";
                 } else {
                     $ctrlId = "sc:{$ttlid}:x{$rowIdx}:occAttr:{$attrId}";
                 }
                 if (isset(data_entry_helper::$entity_to_load[$ctrlId])) {
                     $existing_value = data_entry_helper::$entity_to_load[$ctrlId];
                 } elseif (array_key_exists('default', $attributes[$attrId])) {
                     $existing_value = $attributes[$attrId]['default'];
                 } else {
                     $existing_value = '';
                 }
                 $oc = str_replace('{fieldname}', $ctrlId, $control);
                 if (!empty($existing_value)) {
                     // For select controls, specify which option is selected from the existing value
                     if (substr($oc, 0, 7) == '<select') {
                         $oc = str_replace('value="' . $existing_value . '"', 'value="' . $existing_value . '" selected="selected"', $oc);
                     } else {
                         if (strpos($oc, 'checkbox') !== false) {
                             if ($existing_value == "1") {
                                 $oc = str_replace('type="checkbox"', 'type="checkbox" checked="checked"', $oc);
                             }
                         } else {
                             $oc = str_replace('value=""', 'value="' . $existing_value . '"', $oc);
                         }
                     }
                     // assume all error handling/validation done client side
                 }
                 $secondrow .= str_replace(array('{label}', '{content}'), array(lang::get($attributes[$attrId]['caption']), $oc), $indicia_templates[$options['attrCellTemplate']]);
             }
             $thirdrow = "";
             if ($options['occurrenceComment']) {
                 $thirdrow .= "\n<td class=\"ui-widget-content scCommentCell\" {$colspan}><label for=\"sc:{$ttlid}:{$existing_record_id}:occurrence:comment\" class=\"auto-width\" >" . lang::get("Comment") . " : </label><input class=\"scComment\" type=\"text\" name=\"sc:{$ttlid}:{$existing_record_id}:occurrence:comment\" " . "id=\"sc:{$ttlid}:{$existing_record_id}:occurrence:comment\" value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load["sc:{$ttlid}:{$existing_record_id}:occurrence:comment"]) . "\" /></td>";
             }
             $rows[] = '<tr>' . $firstrow . '</tr>';
             $rows[] = '<tr class="scMeaning-' . $occ['taxon']['taxon_meaning_id'] . ' scDataRow">' . $secondrow . '</tr>';
             // no images.
             if ($thirdrow != "") {
                 $rows[] = '<tr class="scMeaning-' . $occ['taxon']['taxon_meaning_id'] . ' scDataRow">' . $thirdrow . '</tr>';
             }
             // no images.
             $rowIdx++;
         }
         $grid .= "\n<tbody>\n";
         if (count($rows) > 0) {
             $grid .= implode("\n", $rows) . "\n";
         } else {
             $grid .= "<tr style=\"display: none\"><td></td></tr>\n";
         }
         $grid .= "</tbody>\n</table>\n";
         if ($options['rowInclusionCheck'] == 'hasData') {
             $grid .= '<input name="rowInclusionCheck" value="hasData" type="hidden" />';
         }
         // If the lookupListId parameter is specified then the user is able to add extra rows to the grid,
         // selecting the species from this list. Add the required controls for this.
         if (isset($options['lookupListId'])) {
             $grid .= "<label for=\"taxonLookupControl\" class=\"auto-width\">" . lang::get('Add species to list') . " : </label> <input id=\"taxonLookupControl\" name=\"taxonLookupControl\" >";
             // Javascript to add further rows to the grid
             data_entry_helper::$javascript .= "var formatter = function(rowData,taxonCell) {\r\n  taxonCell.html(\"" . lang::get('loading') . "\");\r\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/taxa_taxon_list/' + rowData.id +\r\n            '?mode=json&view=detail&auth_token=" . $options['readAuth']['auth_token'] . "&nonce=" . $options['readAuth']["nonce"] . "&callback=?', function(mdata) {\r\n    if(mdata instanceof Array && mdata.length>0){\r\n      jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/taxa_taxon_list' +\r\n            '?mode=json&view=detail&auth_token=" . $options['readAuth']['auth_token'] . "&nonce=" . $options['readAuth']["nonce"] . "&taxon_meaning_id='+mdata[0].taxon_meaning_id+'&taxon_list_id=" . $options["extra_list_id"] . "&callback=?', function(data) {\r\n        var taxaList = '';\r\n         if(data instanceof Array && data.length>0){\r\n          for (var i=0;i<data.length;i++){\r\n            if(data[i].preferred == 'f')\r\n              taxaList += (taxaList == '' ? '' : ', ')+data[i].taxon;\r\n            else\r\n              taxaList = '<em>'+data[i].taxon+'</em>'+(taxaList == '' ? '' : ', '+taxaList);\r\n            }\r\n          }\r\n          taxonCell.html(taxaList).removeClass('extraCommonNames');\r\n        });\r\n    }})\r\n}  \r\nbindSpeciesAutocomplete(\"taxonLookupControl\",\"" . data_entry_helper::$base_url . "index.php/services/data\", \"" . $options['id'] . "\", \"" . $options['lookupListId'] . "\", {\"auth_token\" : \"" . $options['readAuth']['auth_token'] . "\", \"nonce\" : \"" . $options['readAuth']['nonce'] . "\"}, formatter);\r\n";
         }
         // No help text
         return $grid;
     } else {
         return $taxalist['error'];
     }
 }
 /**
  * Get the block of sample custom attributes for the recorder
  */
 private static function get_control_recorderdetails($auth, $args, $tabalias, $options)
 {
     // get the sample attributes
     $attrOpts = array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
     // select only the custom attributes that are for this sample method or all sample methods, if this
     // form is for a specific sample method.
     if (!empty($args['sample_method_id'])) {
         $attrOpts['sample_method_id'] = $args['sample_method_id'];
     }
     $attributes = data_entry_helper::getAttributes($attrOpts, false);
     // load values from profile. This is Drupal specific code, so degrade gracefully.
     if (function_exists('profile_load_profile')) {
         global $user;
         profile_load_all_profile($user);
         foreach ($attributes as &$attribute) {
             if (!isset($attribute['default'])) {
                 $attrPropName = 'profile_' . strtolower(str_replace(' ', '_', $attribute['caption']));
                 if (isset($user->{$attrPropName})) {
                     $attribute['default'] = $user->{$attrPropName};
                 } elseif (strcasecmp($attribute['caption'], 'email') === 0 && isset($user->mail)) {
                     $attribute['default'] = $user->mail;
                 }
             }
         }
     }
     $defAttrOptions = array('extraParams' => $auth['read'], 'class' => "required");
     $attrHtml = '';
     // Drupal specific code
     if (!user_access('IForm n' . self::$node->nid . ' enter data by proxy')) {
         if (isset($options['lockable'])) {
             unset($options['lockable']);
         }
         $defAttrOptions += array('readonly' => 'readonly="readonly"');
         $attrHtml .= '<div class="readonlyFieldset">';
     }
     $defAttrOptions += $options;
     $blockOptions = array();
     $attrHtml .= get_attribute_html($attributes, $args, $defAttrOptions, 'Enter data by proxy', $blockOptions);
     if (!user_access('IForm n' . self::$node->nid . ' enter data by proxy')) {
         $attrHtml .= '</div>';
     }
     return $attrHtml;
 }
Пример #10
0
 protected static function get_control_sectionlist($auth, $args, $tabalias, $options)
 {
     $numAttrs = count($options['smpAttr']);
     $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']));
     /* 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('fieldname' => 'sectionlist_taxa_taxon_list_id', 'id' => 'sectionlist_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);
     $defNRAttrOptions = array('extraParams' => $auth['read'] + array('orderby' => 'id'), 'lookUpKey' => 'meaning_id', 'suffixTemplate' => 'nosuffix');
     $defAttrOptions = $defNRAttrOptions;
     $defAttrOptions['validation'] = array('required');
     // do not allow tree browser
     if ($args['species_ctrl'] == 'tree_browser') {
         return '<p>Can not use tree browser in this context</p>';
     }
     data_entry_helper::$javascript .= "\nvar numAttrs = " . $numAttrs . ";\ndelete_section_species_row = function(row){\n  if(confirm(\"" . lang::get('sectionlist:confirmremove') . "\"+row.find('.seclistspecname')[0].textContent+\"?\")){\n    row.find('input').each(function(){\n      // Fieldname is SL:speciesID:section:SectionsampleID:OccID:AttrValID\n      var parts = jQuery(this).attr('name').split(':');\n      if(parts[4] != '-'){\n        var delList = jQuery('#SLDEL').val();\n        jQuery('#SLDEL').val((delList == '' ? '' : delList+',')+parts[4]);\n      }\n    });\n    row.remove();\n    // recalc the aucune checkboxes.\n    for(var i=1; i<= " . $args['max_number_sections'] . "; i++){\n      if(jQuery('.sectionlist').find('[section='+i+']').length > 0) {\n        section_column_changed(i);\n      }\n    }\n  }\n};\nremove_section_columns = function(from, to){\n  var rows=jQuery('.sectionlist').find('tr');\n  for(var i=0; i< rows.length; i++){\n    for(var j=to; j>= from; j--){\n      var cell = jQuery(rows[i]).children(':eq('+j+')');\n      cell.find('input').each(function(){\n        // Fieldname is SL:speciesID:section:SectionsampleID:OccID:AttrValID\n        var parts = jQuery(this).attr('name').split(':');\n        if(parts[4] != '-'){\n          var delList = jQuery('#SLDEL').val();\n          jQuery('#SLDEL').val((delList == '' ? '' : delList+',')+parts[4]);\n        }\n      });\n      cell.remove();\n    }\n  }\n};\n// at this point, the species ID should hold the preferred taxon id.\nadd_section_species_row = function(speciesID){\n  // first check if already set up. If yes do nothing.\n  if(jQuery('.sectionlist').find('[taxonID='+speciesID+']').length > 0) return;\n  var remButton = jQuery('<img src=\"/misc/watchdog-error.png\" alt=\"Delete\"/>').click(function(){\n    delete_section_species_row(jQuery(this).parent().parent()); // image, td, tr\n  });\n  var name = jQuery('<span class=\"seclistspecname\"></span>').attr('taxonID',speciesID);\n  var cell = jQuery('<td></td>').append(remButton).append(name);\n  var row = jQuery('<tr></tr>').data('taxonID',speciesID).insertBefore('.seclistspecrow').append(cell);\n  for(var i=1; i<= " . $args['max_number_sections'] . "; i++){\n    if(jQuery('.sectionlist').find('[section='+i+']').length > 0) {\n      var sampleID = jQuery('.sectionlist').find('tr:eq(0)').find('th:eq('+i+')').data('sampleID');\n      add_section_value(row, i, sampleID);  // these are all empty, so aucune value stays unchanged.\n    }\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          // we are assuming that this is the preferred ID\n          jQuery('.seclistspecname').filter('[taxonID='+data[0].id+']').empty().attr('meaningID', data[0].taxon_meaning_id).append('<b>'+data[0].taxon+'</b>');\n        }}\n  );\n};\nsection_column_changed = function(column){\n  var aucuneControl = jQuery(':checkbox[name^=\"SLA\\:'+column+'\\:\"]').filter('[name\$=\"\\:" . $args['aucune_attr_id'] . "\"]').attr('disabled', false);\n  var rows = jQuery('.sectionlist').find('tr');\n  for(var j = 1; j < (rows.length-" . ($numAttrs + 1) . "); j++){\n    if(jQuery(rows[j]).find('td').filter(':eq('+column+')').find('[value!=\"\"]').length > 0)\n      aucuneControl.attr('checked', false).attr('disabled', true);\n  };\n};\nsection_data_changed = function(){\n  section_column_changed(jQuery(this).attr('name').split(':')[2]);\n};\n\nadd_section_value = function(row, column, sampleID){\n  // Fieldname is SL:speciesID:section:SectionsampleID:OccID:AttrID\n  var taxonID = jQuery(row).find('.seclistspecname').attr('taxonID');\n  var ctrl = jQuery('<input type=\"text\" name=\"SL:'+taxonID+':'+column+':'+sampleID+':-:-\" class=\"sl-input digits\" value=\"\" />').change(section_data_changed);\n  jQuery('<td></td>').append(ctrl).appendTo(row);\n};\n\nadd_section_column = function(column, sampleID){\n  var rows=jQuery('.sectionlist').find('tr');\n  for(var i=1; i<= column; i++){\n    if(jQuery('.sectionlist').find('[section='+i+']').length == 0) {\n    \tfor(var j = 0; j < rows.length; j++){\n    \t\tif(j==0){ //header\n    \t\t  var header = jQuery('<span class=\"sectionlist-column-header\">" . lang::get('sectionlist:section') . " '+i+'</span>').attr('section',i);\n    \t\t  jQuery('<th></th>').data('sampleID', i==column ? sampleID : '-').append(header).appendTo(rows[j]);\n    \t\t} else if(j == (rows.length-" . (1 + $numAttrs) . ")) {// species selection row has no data.\n    \t\t  jQuery('<td></td>').appendTo(rows[j]);";
     global $indicia_templates;
     $tempLabel = $indicia_templates['label'];
     $indicia_templates['label'] = '';
     // we don't want labels in the cell
     // Fieldname is SLA:section:SectionsampleID:AttrValID:AttrID
     for ($i = 0; $i < $numAttrs; $i++) {
         data_entry_helper::$javascript .= "\n    \t\t} else if(j == (rows.length-" . ($numAttrs - $i) . ")) { // section sample attribute rows.\n    \t\t  var newName = 'SLA:'+i+':'+(i==column ? sampleID : '-')+':-'; //this will replace the smpAttr, so the AttrID is left alone at the end.\n    \t\t  var attr = '" . str_replace("\n", "", data_entry_helper::outputAttribute($attributes[$options['smpAttr'][$i]], $attributes[$options['smpAttr'][$i]]['data_type'] == 'Boolean' || $attributes[$options['smpAttr'][$i]]['data_type'] == 'B' ? $defNRAttrOptions : $defAttrOptions)) . "';\n    \t\t  jQuery('<td>'+attr.replace(/smpAttr/g, newName)+'</td>').appendTo(rows[j]);";
     }
     $indicia_templates['label'] = $tempLabel;
     data_entry_helper::$javascript .= "\n            } else\n              add_section_value(rows[j], i, (i==column ? sampleID : '-'));\n    \t}\n    } else if (i==column && jQuery(rows[0]).find('th:eq('+i+')').data('sampleID') == '-' && sampleID != '-'){\n      jQuery(rows[0]).find('th:eq('+i+')').data('sampleID', sampleID);\n      for(var j = 1; j < rows.length; j++){\n        var input = jQuery(rows[j]).find('td:eq('+i+')').find('input,select');\n        if(input.length > 0) {\n          var parts = input.attr('name').split(':');\n          if(parts[0]=='SL')\n            input.attr('name','SL:'+parts[1]+':'+i+':'+sampleID+':'+parts[4]+':'+parts[5]);\n          else if(parts[0]=='SLA')\n            input.attr('name','SLA:'+i+':'+sampleID+':'+parts[3]+':'+parts[4]);\n        }\n      }\n    }\n  }\n  if(jQuery('#sectionlist_number').val() < column) jQuery('#sectionlist_number').val(column);\n  section_column_changed(column);\n};\njQuery('#sectionlist_number').change(function(){\n  // initially we put in the restriction that it is only possible to increase the number of sections.\n  var currentCols = jQuery('.sectionlist-column-header').length;\n  if(currentCols > jQuery('#sectionlist_number').val()){\n    if(!confirm(\"" . lang::get('sectionlist:confirmremovecolumns') . "\")) return;\n    remove_section_columns(parseInt(jQuery('#sectionlist_number').val())+1, currentCols);\n  }\n  add_section_column(jQuery('#sectionlist_number').val(),'-');\n});\nadd_section_species = function(speciesID, section, sectionSampleID, occurrenceID, attributeID, value){\n  add_section_column(section, sectionSampleID);\n  add_section_species_row(speciesID);\n  jQuery('[name^=\"SL\\:'+speciesID+'\\:'+section+'\\:\"]').attr('name','SL:'+speciesID+':'+section+':'+sectionSampleID+':'+occurrenceID+':'+attributeID).val(value).change()\n  section_column_changed(section);\n};\nadd_section_attribute = function(section, sectionSampleID, attrValID, attributeID, value){\n  // Fieldname is SLA:section:SectionsampleID:AttrValID:AttrID\n  add_section_column(section, sectionSampleID);\n  jQuery('[name^=\"SLA\\:'+section+'\\:\"]').each(function(){\n    var parts = jQuery(this).attr('name').split(':');\n    if(attributeID == parts[4]) {\n      var myName = jQuery(this).attr('name');\n      var checkboxes = jQuery('[name=\"'+myName+'\"]:checkbox');\n      if(checkboxes.length > 0){\n        checkboxes.attr('checked', value == '1' ? true : false);\n      } else {\n        jQuery(this).val(value);\n      }\n      jQuery(this).attr('name','SLA:'+section+':'+sectionSampleID+':'+attrValID+':'+attributeID);\n    }\n  });\n};\njQuery('#sectionlist_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('.seclistspecname').filter('[meaningID='+jQuery('#sectionlist_taxa_taxon_list_id').val()+']');\n  if(existRows.length>0)\n    alert(\"" . lang::get('sectionlist: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('#sectionlist_taxa_taxon_list_id').val() +\n\t\t\t\"&callback=?\", function(data) {\n        if (data.length>0) {\n  \t\t\tadd_section_species_row(data[0].id);\n        }});\n  jQuery('#sectionlist_taxa_taxon_list_id\\\\:taxon').val('');\n});\njQuery('#sectionlist_number').change();\n";
     if ($args['init_species_ids'] != '') {
         $init_species = explode(',', $args['init_species_ids']);
         foreach ($init_species as $toAdd) {
             data_entry_helper::$javascript .= "add_section_species_row(" . $toAdd . ");\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] == 'SL' && $value != '') {
                 data_entry_helper::$javascript .= "add_section_species(" . $parts[1] . "," . $parts[2] . ",\"" . $parts[3] . "\",\"" . $parts[4] . "\",\"" . $parts[5] . "\",\"" . $value . "\");\n";
             } else {
                 if ($parts[0] == 'SLS' || $parts[0] == 'SLDEL') {
                     $myHidden .= '<input type="hidden" name="' . $key . '" value="' . $value . '">';
                 } else {
                     if ($parts[0] == 'SLA' && $value != '') {
                         data_entry_helper::$javascript .= "add_section_attribute(" . $parts[1] . "," . $parts[2] . ",\"" . $parts[3] . "\",\"" . $parts[4] . "\",\"" . $value . "\");\n";
                     }
                 }
             }
         }
     } else {
         if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
             //sample specified
             $myHidden = '<input type="hidden" id="SLDEL" name="SLDEL" value="" >';
             data_entry_helper::$javascript .= "jQuery('#SLDEL').val('');";
             $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) == 'SL ') {
                     $section = explode(' ', $entity['location_name']);
                     $section = $section[2];
                     $myHidden .= '<input type="hidden" name="SLS:' . $section . '" 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['quant_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 .= "\nadd_section_species(" . $OCCentity['taxa_taxon_list_id'] . "," . $section . "," . $OCCentity['sample_id'] . "," . $ATTRentity['occurrence_id'] . "," . (isset($ATTRentity['id']) ? $ATTRentity['id'] : "\"-\"") . "," . ($ATTRentity['raw_value'] == '' ? "\"\"" : $ATTRentity['raw_value']) . ");";
                         }
                     }
                     // TBS SLA
                     $url = self::$svcUrl . '/data/sample_attribute_value?mode=json&view=list&nonce=' . $auth['read']["nonce"] . '&auth_token=' . $auth['read']['auth_token'] . '&deleted=f&sample_id=' . $entity['id'];
                     $session = curl_init($url);
                     curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
                     $ATTRentities = json_decode(curl_exec($session), true);
                     foreach ($ATTRentities as $ATTRentity) {
                         // Fieldname is SLA:section:SectionsampleID:AttrValID:AttrID
                         if ($ATTRentity['id'] != '') {
                             data_entry_helper::$javascript .= "\nadd_section_attribute(" . $section . "," . $entity['id'] . "," . $ATTRentity['id'] . "," . $ATTRentity['sample_attribute_id'] . "," . $ATTRentity['raw_value'] . ");";
                         }
                     }
                 }
             }
         }
     }
     $retVal = $myHidden . '<div class="sectionlist"><table border="1" ><tr><th>' . lang::get('sectionlist:species') . '</th></tr><tr class="seclistspecrow" ><td>' . call_user_func(array('data_entry_helper', $args['species_ctrl']), $species_list_args) . '</td></tr>';
     for ($i = 0; $i < $numAttrs; $i++) {
         $retVal .= '<tr><td>' . $attributes[$options['smpAttr'][$i]]['caption'] . '</td></tr>';
     }
     $retVal .= '</table></div>';
     data_entry_helper::$javascript .= "\n// override the default results function - doesn't seem to use value field.\njQuery('input#sectionlist_taxa_taxon_list_id\\\\:taxon').unbind(\"result\");\njQuery('input#sectionlist_taxa_taxon_list_id\\\\:taxon').result(function(event, data, value) {\n      jQuery('input#sectionlist_taxa_taxon_list_id').attr('value', value);\n      jQuery('input#sectionlist_taxa_taxon_list_id').change();\n});\n";
     return $retVal;
 }
Пример #11
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;
    }
 /**
  * Load the list of occurrence attributes into a static variable.
  * By maintaining a single list of attributes we can track which have already
  * been output.
  * @param array $readAuth Read authorisation tokens.
  * @param integer $surveyId ID of the survey to load occurrence attributes for.
  */
 protected static function loadOccAttrs($readAuth, $surveyId)
 {
     if (!isset(self::$occAttrs)) {
         $attrArgs = array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth, 'survey_id' => $surveyId);
         self::$occAttrs = data_entry_helper::getAttributes($attrArgs, false);
     }
 }
Пример #13
0
 public static function get_occurrences_form($args, $node, $response)
 {
     global $user;
     data_entry_helper::add_resource('jquery_form');
     data_entry_helper::add_resource('jquery_ui');
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // did the parent sample previously exist? Default is no.
     $parentSampleId = null;
     $existing = false;
     if (isset($_POST['sample:id'])) {
         // have just posted an edit to the existing parent sample, so can use it to get the parent location id.
         $parentSampleId = $_POST['sample:id'];
         $existing = true;
     } else {
         if (isset($response['outer_id'])) {
             // have just posted a new parent sample, so can use it to get the parent location id.
             $parentSampleId = $response['outer_id'];
         } else {
             $parentSampleId = $_GET['sample_id'];
             $existing = true;
         }
     }
     if (!$parentSampleId || $parentSampleId == '') {
         return 'Could not determine the parent sample.';
     }
     // find any attributes that apply to Timed Count Count samples.
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Timed Count Count'));
     if (count($sampleMethods) == 0) {
         return 'The sample method "Timed Count Count" must be defined in the termlist in order to use this form.';
     }
     $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id'], 'multiValue' => false));
     if (!isset(data_entry_helper::$validation_errors)) {
         // the parent sample and at least one sub-sample have already been created: can't cache in case a new subsample (Count) added.
         data_entry_helper::load_existing_record($auth['read'], 'sample', $parentSampleId);
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('Y');
         // using the report returns the attributes as well.
         $subSamples = data_entry_helper::get_population_data(array('report' => 'library/samples/samples_list_for_parent_sample', 'extraParams' => $auth['read'] + array('sample_id' => $parentSampleId, 'date_from' => '', 'date_to' => '', 'sample_method_id' => '', 'smpattrs' => implode(',', array_keys($attributes))), 'nocache' => true));
         // subssamples ordered by id desc, so reorder by date asc.
         usort($subSamples, "iform_timed_count_subsample_cmp");
         for ($i = 0; $i < count($subSamples); $i++) {
             data_entry_helper::$entity_to_load['C' . ($i + 1) . ':sample:id'] = $subSamples[$i]['sample_id'];
             data_entry_helper::$entity_to_load['C' . ($i + 1) . ':sample:date'] = $subSamples[$i]['date'];
             // this is in correct format
             foreach ($subSamples[$i] as $field => $value) {
                 if (preg_match('/^attr_sample_/', $field)) {
                     $parts = explode('_', $field);
                     if ($subSamples[$i]['attr_id_sample_' . $parts[2]] != null) {
                         data_entry_helper::$entity_to_load['C' . ($i + 1) . ':smpAttr:' + $parts[2] + ':' + $subSamples[$i]['attr_id_sample_' . $parts[2]]] = $value;
                     }
                 }
             }
         }
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList = " . $args['taxon_list_id'] . ";\n";
     if (!empty($args['taxon_filter_field']) && !empty($args['taxon_filter'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesListFilterField = '" . $args['taxon_filter_field'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter']);
         data_entry_helper::$javascript .= "indiciaData.speciesListFilterValues = '" . json_encode($filterLines) . "';\n";
     }
     data_entry_helper::$javascript .= "\r\nindiciaData.indiciaSvc = '" . data_entry_helper::$base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.readAuth = {nonce: '" . $auth['read']['nonce'] . "', auth_token: '" . $auth['read']['auth_token'] . "'};\n";
     data_entry_helper::$javascript .= "indiciaData.parentSample = " . $parentSampleId . ";\n";
     data_entry_helper::$javascript .= "indiciaData.occAttrId = " . $args['occurrence_attribute_id'] . ";\n";
     if ($existing) {
         // Only need to load the occurrences for a pre-existing sample
         $o = data_entry_helper::get_population_data(array('report' => 'library/occurrences/occurrences_list_for_parent_sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'sample_id' => $parentSampleId, 'survey_id' => '', 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => $args['occurrence_attribute_id']), 'nocache' => true));
         // the report is ordered id desc. REverse it
         $o = array_reverse($o);
     } else {
         $o = array();
     }
     // empty array of occurrences when no creating a new sample.
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call.
     // pass a param that sets the next page to display
     $r = "<form method='post' id='subsamples'>" . $auth['write'] . "\r\n<input type='hidden' name='page' value='occurrences'/>\r\n<input type='hidden' name='read_nonce' value='" . $auth['read']['nonce'] . "'/>\r\n<input type='hidden' name='read_auth_token' value='" . $auth['read']['auth_token'] . "'/>\r\n<input type='hidden' name='website_id' value='" . $args['website_id'] . "'/>\r\n<input type='hidden' name='sample:id' value='" . data_entry_helper::$entity_to_load['sample:id'] . "'/>\r\n<input type='hidden' name='sample:survey_id' value='" . $args['survey_id'] . "'/>\r\n<input type='hidden' name='sample:date' value='" . data_entry_helper::$entity_to_load['sample:date'] . "'/>\r\n<input type='hidden' name='sample:entered_sref' value='" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "'/>\r\n<input type='hidden' name='sample:entered_sref_system' value='" . data_entry_helper::$entity_to_load['sample:entered_sref_system'] . "'/>\r\n<input type='hidden' name='sample:geom' value='" . data_entry_helper::$entity_to_load['sample:geom'] . "'/>\r\n";
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     for ($i = 0; $i < $args['numberOfCounts']; $i++) {
         $subSampleId = isset($subSamples[$i]) ? $subSamples[$i]['sample_id'] : null;
         $r .= "<fieldset id=\"count-{$i}\"><legend>" . lang::get('Count ') . ($i + 1) . "</legend>";
         if ($subSampleId) {
             $r .= "<input type='hidden' name='C" . ($i + 1) . ":sample:id' value='" . $subSampleId . "'/>";
         }
         $r .= '<input type="hidden" name="C' . ($i + 1) . ':sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
         if ($subSampleId || isset(data_entry_helper::$entity_to_load['C' . ($i + 1) . ':sample:date']) && data_entry_helper::$entity_to_load['C' . ($i + 1) . ':sample:date'] != '') {
             $dateValidation = array('required', 'date');
         } else {
             $dateValidation = array('date');
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'C' . ($i + 1) . ':sample:date', 'validation' => $dateValidation));
         data_entry_helper::$javascript .= "\$('#C" . ($i + 1) . "\\\\:sample\\\\:date' ).datepicker( 'option', 'minDate', new Date(" . data_entry_helper::$entity_to_load['sample:date'] . ", 1 - 1, 1) );\r\n\$('#C" . ($i + 1) . "\\\\:sample\\\\:date' ).datepicker( 'option', 'maxDate', new Date(" . data_entry_helper::$entity_to_load['sample:date'] . ", 12 - 1, 31) );\n";
         if (!$subSampleId && $i) {
             $r .= "<p>" . lang::get('You must enter the date before you can enter any further information.') . '</p>';
             data_entry_helper::$javascript .= "\$('#C" . ($i + 1) . "\\\\:sample\\\\:date' ).change(function(){\r\n  myFieldset = \$(this).addClass('required').closest('fieldset');\r\n  myFieldset.find('.smp-input,[name=taxonLookupControl]').removeAttr('disabled'); // leave the count fields as are.\r\n});\n";
         }
         if ($subSampleId && $i) {
             $r .= "<label for='C" . ($i + 1) . ":sample:deleted'>Delete this count:</label>\r\n<input id='C" . ($i + 1) . ":sample:deleted' type='checkbox' value='t' name='C" . ($i + 1) . ":sample:deleted'><br />\r\n<p>" . lang::get('Setting this will delete this count when the page is saved.') . '</p>';
         }
         foreach ($attributes as $attr) {
             if (strcasecmp($attr['untranslatedCaption'], 'Unconfirmed Individuals') == 0) {
                 continue;
             }
             // output the attribute - tag it with a class & id to make it easy to find from JS.
             $attrOpts = array_merge(isset($blockOptions[$attr['fieldname']]) ? $blockOptions[$attr['fieldname']] : array(), array('class' => 'smp-input smpAttr-' . ($i + 1), 'id' => 'C' . ($i + 1) . ':' . $attr['fieldname'], 'fieldname' => 'C' . ($i + 1) . ':' . $attr['fieldname'], 'extraParams' => $auth['read']));
             // we need process validation specially: deh expects an array, we have a string...
             if (isset($attrOpts['validation']) && is_string($attrOpts['validation'])) {
                 $attrOpts['validation'] = explode(';', $attrOpts['validation']);
             }
             // if there is an existing value, set it and also ensure the attribute name reflects the attribute value id.
             if (isset($subSampleId)) {
                 // but have to take into account possibility that this field has been blanked out, so deleting the attribute.
                 if (isset($subSamples[$i]['attr_id_sample_' . $attr['attributeId']]) && $subSamples[$i]['attr_id_sample_' . $attr['attributeId']] != '') {
                     $attrOpts['fieldname'] = 'C' . ($i + 1) . ':' . $attr['fieldname'] . ':' . $subSamples[$i]['attr_id_sample_' . $attr['attributeId']];
                     $attr['default'] = $subSamples[$i]['attr_sample_' . $attr['attributeId']];
                 }
             } else {
                 if ($i) {
                     $attrOpts['disabled'] = "disabled=\"disabled\"";
                 }
             }
             $r .= data_entry_helper::outputAttribute($attr, $attrOpts);
         }
         $r .= '<table id="timed-counts-input-' . $i . '" class="ui-widget">';
         $r .= '<thead><tr><th class="ui-widget-header">' . lang::get('Species') . '</th><th class="ui-widget-header">' . lang::get('Count') . '</th><th class="ui-widget-header"></th></tr></thead>';
         $r .= '<tbody class="ui-widget-content">';
         $occs = array();
         // not very many occurrences so no need to optimise.
         if (isset($subSampleId) && $existing && count($o) > 0) {
             foreach ($o as $oc) {
                 if ($oc['sample_id'] == $subSampleId) {
                     $occs[] = $oc;
                 }
             }
         }
         for ($j = 0; $j < $args['numberOfSpecies']; $j++) {
             $rowClass = '';
             // O<i>:<j>:<ttlid>:<occid>:<attrid>:<attrvalid>
             if (isset($occs[$j])) {
                 $taxon = $occs[$j]['common'] . ' (' . $occs[$j]['taxon'] . ')';
                 $fieldname = 'O' . ($i + 1) . ':' . ($j + 1) . ':' . $occs[$j]['taxa_taxon_list_id'] . ':' . $occs[$j]['occurrence_id'] . ':' . $args['occurrence_attribute_id'] . ':' . $occs[$j]['attr_id_occurrence_' . $args['occurrence_attribute_id']];
                 $value = $occs[$j]['attr_occurrence_' . $args['occurrence_attribute_id']];
             } else {
                 $taxon = '';
                 $fieldname = 'O' . ($i + 1) . ':' . ($j + 1) . ':--ttlid--:--occid--:' . $args['occurrence_attribute_id'] . ':--valid--';
                 $value = '';
             }
             $r .= '<tr ' . $rowClass . '>' . '<td><input id="TLC-' . ($i + 1) . '-' . ($j + 1) . '" name="taxonLookupControl" value="' . $taxon . '" ' . (!$j && (!$i || $subSampleId) || $taxon ? 'class="required"' : '') . ' ' . (!$subSampleId && $i ? 'disabled="disabled"' : '') . '>' . (!$j && (!$i || $subSampleId) || $taxon ? '<span class="deh-required">*</span>' : '') . '</td>' . '<td><input name="' . $fieldname . '" id="occ-' . ($i + 1) . '-' . ($j + 1) . '" value="' . $value . '" class="occValField integer ' . (!$j && (!$i || $subSampleId) || $taxon ? 'required' : '') . '" ' . (!$subSampleId && $i || $taxon == '' && ($i || $j) ? 'disabled="disabled"' : '') . ' min=0 >' . (!$j && (!$i || $subSampleId) || $taxon ? '<span class="deh-required">*</span>' : '') . '</td>' . '<td>' . (!$j ? '' : '<div class="ui-state-default remove-button">' . lang::get('Remove this Species entry') . '</div>') . '</td>' . '</tr>';
             $rowClass = $rowClass == '' ? 'class="alt-row"' : '';
             data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"TLC-" . ($i + 1) . "-" . ($j + 1) . "\",\"occ-" . ($i + 1) . "-" . ($j + 1) . "\",\"" . data_entry_helper::$base_url . "index.php/services/data\", \"" . $args['taxon_list_id'] . "\",\r\n  indiciaData.speciesListFilterField, indiciaData.speciesListFilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"}, 25);\n";
         }
         foreach ($attributes as $attr) {
             if (strcasecmp($attr['untranslatedCaption'], 'Unconfirmed Individuals')) {
                 continue;
             }
             // output the attribute - tag it with a class & id to make it easy to find from JS.
             $attrOpts = array('class' => 'smp-input smpAttr-' . ($i + 1), 'id' => 'C' . ($i + 1) . ':' . $attr['fieldname'], 'fieldname' => 'C' . ($i + 1) . ':' . $attr['fieldname'], 'extraParams' => $auth['read']);
             // if there is an existing value, set it and also ensure the attribute name reflects the attribute value id.
             if (isset($subSampleId)) {
                 // but have to take into account possibility that this field has been blanked out, so deleting the attribute.
                 if (isset($subSamples[$i]['attr_id_sample_' . $attr['attributeId']]) && $subSamples[$i]['attr_id_sample_' . $attr['attributeId']] != '') {
                     $attrOpts['fieldname'] = 'C' . ($i + 1) . ':' . $attr['fieldname'] . ':' . $subSamples[$i]['attr_id_sample_' . $attr['attributeId']];
                     $attr['default'] = $subSamples[$i]['attr_sample_' . $attr['attributeId']];
                 }
             } else {
                 if ($i) {
                     $attrOpts['disabled'] = "disabled=\"disabled\"";
                 }
             }
             $r .= '<tr ' . $rowClass . '>' . '<td>' . $attr['caption'] . '</td>';
             unset($attr['caption']);
             $r .= '<td>' . data_entry_helper::outputAttribute($attr, $attrOpts) . '</td>' . '<td></td>' . '</tr>';
         }
         $r .= '</tbody></table>';
         if ($i && !$subSampleId) {
             $r .= '<button type="button" class="clear-button ui-state-default ui-corner-all smp-input" disabled="disabled" />' . lang::get('Clear this count') . '</button>';
         }
         $r .= '</fieldset>';
     }
     $r .= '<input type="submit" value="' . lang::get('Save') . '" />';
     $r .= '<a href="' . $args['summary_page'] . '"><button type="button" class="ui-state-default ui-corner-all" />' . lang::get('Cancel') . '</button></a></form>';
     data_entry_helper::enable_validation('subsamples');
     data_entry_helper::$javascript .= "initButtons();\n";
     return $r;
 }
Пример #14
0
 public static function mnhnl_bats2_species_checklist($args, $options)
 {
     global $indicia_templates;
     //    $options = data_entry_helper::check_arguments($options, array('listId', 'occAttrs', 'readAuth', 'extraParams', 'lookupListId'));
     $options = data_entry_helper::get_species_checklist_options($options);
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     $occAttrControls = array();
     $occAttrs = array();
     $retVal = '';
     // Load any existing sample's occurrence data into $entity_to_load: first have to load the survey method subsamples.
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $subSamplesAttrs = array();
         $smpOptions = array('table' => 'sample', 'nocache' => true, 'extraParams' => $options['readAuth'] + array('view' => 'detail', 'parent_id' => data_entry_helper::$entity_to_load['sample:id']));
         $subSamples = data_entry_helper::get_population_data($smpOptions);
         foreach ($subSamples as $sample) {
             $subSamplesAttrs[$sample['id']] = data_entry_helper::getAttributes(array('attrtable' => 'sample_attribute', 'valuetable' => 'sample_attribute_value', 'id' => $sample['id'], 'key' => 'sample_id', 'fieldprefix' => '{MyPrefix}:smpAttr', 'extraParams' => $options['readAuth'], 'survey_id' => $args['survey_id']), true);
             $subSamplesAttrs[$sample['id']][$visitAttr]['validation_rules'] = 'required';
         }
         foreach ($options['surveyMethods'] as $i => $method) {
             $smpID = false;
             foreach ($subSamples as $subSample) {
                 foreach ($subSamplesAttrs[$subSample['id']] as $attr) {
                     if ($attr['attributeId'] == $options['surveyMethodAttrId'] && $attr['default'] == $method['meaning_id']) {
                         $smpID = $subSample['id'];
                         $options['surveyMethods'][$i]['smpID'] = $smpID;
                     }
                 }
             }
             if ($smpID) {
                 self::preload_species_checklist_occurrences($smpID, $method['meaning_id'], $options['readAuth']);
             }
         }
     }
     // load the full list of species for the grid, including the main checklist plus any additional species in the reloaded occurrences.
     $options['extraParams']['view'] = 'detail';
     $occList = self::get_species_checklist_occ_list($options);
     // If we managed to read the species list data we can proceed
     if (!array_key_exists('error', $occList)) {
         $attributes = data_entry_helper::getAttributes(array('id' => null, 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => "{fieldname}", 'extraParams' => $options['readAuth'], 'survey_id' => array_key_exists('survey_id', $options) ? $options['survey_id'] : null));
         foreach ($attributes as $idx => $attr) {
             $attributes[$idx]['class'] = "scCheckTaxon";
         }
         // this allows extra validation
         // Get the attribute and control information required to build the custom occurrence attribute columns
         self::species_checklist_prepare_attributes($options, $attributes, $occAttrControls, $occAttrs);
         $retVal = "<p>" . lang::get('LANG_SpeciesInstructions') . "</p>\n";
         if (isset($options['lookupListId'])) {
             self::$cloneableTable = self::get_species_checklist_clonable_row($options, $occAttrControls, $attributes);
         }
         $retVal .= '<table class="ui-widget ui-widget-content mnhnl-species-grid ' . $options['class'] . '" id="' . $options['id'] . '">';
         $retVal .= self::get_species_checklist_header($options, $attributes) . '<tbody>';
         $attrsPerRow = array();
         foreach ($attributes as $attrId => $attr) {
             $row = substr($attr['inner_structure_block'], 3);
             if (!isset($attrsPerRow[$row])) {
                 $attrsPerRow[$row] = array();
             }
             $attrsPerRow[$row][] = $attr["attributeId"];
         }
         $rows = array();
         $rowIdx = 0;
         // each row grouping is driven by the ttlid, not the occurrence, as there is a different occurrence for each survey method.
         // that said we want it to be in general occurrence order so it matches the order in which the occurrences are created
         // i.e. in order of first occurrence in ttl group
         $ttlidList = array();
         $ttlList = array();
         foreach ($occList as $occ) {
             $ttlid = $occ['taxon']['id'];
             if (!in_array($ttlid, $ttlidList)) {
                 $ttlidList[] = $ttlid;
                 $ttlList[$ttlid] = $occ['taxon'];
             }
         }
         foreach ($ttlidList as $ttlid) {
             $id = 1;
             foreach ($options['surveyMethods'] as $method) {
                 $existing_record_id = '';
                 foreach ($occList as $occIt) {
                     // get the occurrence for this method/ttl combination
                     if ($occIt['taxon']['id'] == $ttlid && $occIt['method'] == $method['meaning_id']) {
                         $occ = $occIt;
                         $existing_record_id = $occ['id'];
                     }
                 }
                 $retVal .= '<tr class="scMeaning-' . $ttlList[$ttlid]['taxon_meaning_id'] . ' scDataRow sg-tr-' . $method['meaning_id'] . ' ' . ($id == '1' ? 'scFirstRow' : '') . '">';
                 if ($id == '1') {
                     $firstCell = data_entry_helper::mergeParamsIntoTemplate($ttlList[$ttlid], 'taxon_label', false, true);
                     if ($options['PHPtaxonLabel']) {
                         $firstCell = eval($firstCell);
                     }
                     // assume always removeable and scPresence is hidden.
                     $retVal .= '<td class="ui-state-default remove-row" style="width: 1%" rowspan="' . count($attrsPerRow) . '">X</td>';
                     $retVal .= str_replace('{content}', $firstCell, str_replace('{colspan}', 'rowspan="' . count($attrsPerRow) . '"', $indicia_templates['taxon_label_cell']));
                 }
                 $ctrlId = "sc:" . $method['meaning_id'] . ":{$ttlid}:" . ($existing_record_id ? $existing_record_id : "x" . $rowIdx) . ":present";
                 $retVal .= '<td>' . $method['term'] . ':</td><td class="scPresenceCell" style="display:none"><input type="hidden" class="scPresence" name="' . $ctrlId . '" value="1" /></td><td><span>';
                 foreach ($attrsPerRow[$id] as $attrId) {
                     // no complex values in checkboxes as the controls are vanilla
                     if ($existing_record_id) {
                         $search = preg_grep("/^sc:" . $method['meaning_id'] . ":{$ttlid}:{$existing_record_id}:occAttr:{$attrId}" . '[:[0-9]*]?$/', array_keys(data_entry_helper::$entity_to_load));
                         $ctrlId = count($search) === 1 ? implode('', $search) : "sc:" . $method['meaning_id'] . ":{$ttlid}:{$existing_record_id}:occAttr:{$attrId}";
                     } else {
                         $ctrlId = "sc:" . $method['meaning_id'] . ":{$ttlid}:x{$rowIdx}:occAttr:{$attrId}";
                     }
                     if (isset(data_entry_helper::$entity_to_load[$ctrlId])) {
                         $existing_value = data_entry_helper::$entity_to_load[$ctrlId];
                     } elseif (array_key_exists('default', $attributes[$attrId])) {
                         $existing_value = $attributes[$attrId]['default'];
                     } else {
                         $existing_value = '';
                     }
                     $control = $occAttrControls[$attrId];
                     $oc = str_replace('{fieldname}', $ctrlId, $control);
                     if (!empty($existing_value)) {
                         // TBD selects
                         if (strpos($oc, 'checkbox') !== false) {
                             if ($existing_value == "1") {
                                 $oc = str_replace('type="checkbox"', 'type="checkbox" checked="checked"', $oc);
                             }
                         } else {
                             $oc = str_replace('value=""', 'value="' . $existing_value . '"', $oc);
                         }
                         // assume all error handling/validation done client side
                     }
                     $retVal .= '<span class="scKeepTogether">' . $oc . '</span> ';
                 }
                 $retVal .= '</span></td></tr>';
                 $id++;
                 $rowIdx++;
             }
         }
         if ($rowIdx == 0) {
             $retVal .= "<tr style=\"display: none\"><td></td></tr>\n";
         }
         $retVal .= "</tbody></table>\n";
         data_entry_helper::$javascript .= "\njQuery('#species,.scClonableRow').find(':checkbox').addClass('sgCheckbox');\n";
         if ($options['rowInclusionCheck'] == 'hasData') {
             $r .= '<input name="rowInclusionCheck" value="hasData" type="hidden" />';
         }
         // If the lookupListId parameter is specified then the user is able to add extra rows to the grid,
         // selecting the species from this list. Add the required controls for this.
         if (isset($options['lookupListId'])) {
             $retVal .= "<label for=\"taxonLookupControl\" class=\"auto-width\">" . lang::get('Add species to list') . " : </label><input id=\"taxonLookupControl\" name=\"taxonLookupControl\" >";
             // Javascript to add further rows to the grid
             data_entry_helper::$javascript .= "var formatter = function(rowData,taxonCell) {\n  taxonCell.html(\"" . lang::get('loading') . "\");\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/taxa_taxon_list/' + rowData.id +\n            '?mode=json&view=detail&auth_token=" . $options['readAuth']['auth_token'] . "&nonce=" . $options['readAuth']["nonce"] . "&callback=?', function(mdata) {\n    if(mdata instanceof Array && mdata.length>0){\n      jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/taxa_taxon_list' +\n            '?mode=json&view=detail&auth_token=" . $options['readAuth']['auth_token'] . "&nonce=" . $options['readAuth']["nonce"] . "&taxon_meaning_id='+mdata[0].taxon_meaning_id+'&taxon_list_id=" . $options["extra_list_id"] . "&callback=?', function(data) {\n        var taxaList = '';\n         if(data instanceof Array && data.length>0){\n          for (var i=0;i<data.length;i++){\n            if(data[i].preferred == 'f')\n              taxaList += (taxaList == '' ? '' : '<br/>')+data[i].taxon;\n            else\n              taxaList = '<em>'+data[i].taxon+'</em>'+(taxaList == '' ? '' : '<br/>'+taxaList);\n            }\n          }\n          taxonCell.html(taxaList).removeClass('extraCommonNames');\n        });\n    }})\n}  \nbindSpeciesAutocomplete(\"taxonLookupControl\",\"" . data_entry_helper::$base_url . "index.php/services/data\", \"" . $options['id'] . "\", \"" . $options['lookupListId'] . "\", {\"auth_token\" : \"" . $options['readAuth']['auth_token'] . "\", \"nonce\" : \"" . $options['readAuth']['nonce'] . "\"}, formatter, \"" . lang::get('LANG_Duplicate_Taxon') . "\", " . $options['max_species_ids'] . ");\n";
         }
         // No help text
         return $retVal;
     } else {
         return $occList['error'];
     }
 }
Пример #15
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('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']));
        $language = iform_lang_iso_639_2($args['language']);
        $defAttrOptions = array('extraParams' => $readAuth, 'lookUpListCtrl' => 'checkbox_group', 'booleanCtrl' => 'checkbox', '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 packages the post into the correct format
        $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'], 'orderby' => 'taxon'), 'suffixTemplate' => 'nosuffix');
        $focus_flower_ctrl_args = $flower_ctrl_args;
        $focus_flower_ctrl_args['fieldname'] = 'determination:taxa_taxon_list_id';
        $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'], 'orderby' => 'taxon'), 'suffixTemplate' => 'nosuffix');
        $focus_insect_ctrl_args = $insect_ctrl_args;
        $focus_insect_ctrl_args['fieldname'] = 'determination:taxa_taxon_list_id';
        $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';
        $options2 = $options;
        $options['searchLayer'] = 'true';
        $options['editLayer'] = 'false';
        $options['layers'] = array('polygonLayer');
        $options2['divId'] = "map2";
        $options2['layers'] = array('locationLayer');
        // TBD Breadcrumb
        $r .= '
<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>
	<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-active ui-corner-all">
	  		<div id="fold-name-button" class="ui-state-default ui-corner-all fold-button">&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-accordion-content-active 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-active ui-corner-all">
	  		<div id="fold-date-button" class="ui-state-default ui-corner-all fold-button">&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-accordion-content-active 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') . '" />
       		<label for="start_date" >' . lang::get('LANG_And') . ':</label>
  			<input type="text" size="10" id="end_date" name="end_date" value="' . lang::get('click here') . '" />
  		</div>
  		<div id="flower-filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  		<div id="fold-flower-button" class="ui-state-default ui-corner-all fold-button">&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-accordion-content-active ui-corner-all">
		  ' . data_entry_helper::select($flower_ctrl_args) . data_entry_helper::outputAttribute($occurrence_attributes[$args['flower_type_attr_id']], $defAttrOptions) . 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-active ui-corner-all">
	  		<div id="fold-insect-button" class="ui-state-default ui-corner-all fold-button">&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-accordion-content-active ui-corner-all">
		  ' . data_entry_helper::select($insect_ctrl_args) . data_entry_helper::outputAttribute($sample_attributes[$args['sky_state_attr_id']], $defAttrOptions) . data_entry_helper::outputAttribute($sample_attributes[$args['temperature_attr_id']], $defAttrOptions) . data_entry_helper::outputAttribute($sample_attributes[$args['wind_attr_id']], $defAttrOptions) . 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(array('label' => lang::get('LANG_Georef_Label'), 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'suffixTemplate' => 'nosuffix')) . '
 	        <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" />
 	      </div>
	  		' . data_entry_helper::map_panel($options, $olOptions) . '
		</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="collection-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  <div id="collection-title">
	  	<span> </span>
      </div>
	</div>
	<div id="collection-details" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-top">
	  <div id="flower-image">
      </div>
	  <div id="collection-description">
	    <p id="collection-date"></p>
	    <p id="collection-name"></p>
	    <p id="collection-flower-name"></p>
	    <p>' . $occurrence_attributes[$args['flower_type_attr_id']]['caption'] . ': <span id="collection-flower-type"></span></p>
	    <p>' . $location_attributes[$args['habitat_attr_id']]['caption'] . ': <span id="collection-habitat"></span></p>
	    <p id="collection-locality"></p>
	    <p id="collection-user-name"></p>
	  </div>
	  <div id="environment-image">
      </div>
      <div id="map2_container">' . data_entry_helper::map_panel($options2, $olOptions) . '
      </div>
    </div>
	<div id="collection-insects" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
    </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">
	<h1 id="fo-taxon"></h1>
	<div id="fo-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  <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>
	  </div>
	  <div id="fo-breadcrumb">
	  	<span> </span>
      </div>
	</div>
	<div id="fo-warning" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-top ui-accordion-content-active"></div>
	<div id="fo-picture" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
	  <div id="fo-image">
      </div>
    </div>
	<div id="fo-identification" class="ui-accordion-header ui-helper-reset ui-state-active">';
        if (user_access('IForm n' . $node->nid . ' insect expert')) {
            $r .= '<div id="fo-new-insect-id-button" class="ui-state-default ui-corner-all new-id-button">' . lang::get('LANG_New_ID') . '</div>';
        }
        if (user_access('IForm n' . $node->nid . ' flower expert')) {
            $r .= '<div id="fo-new-flower-id-button" class="ui-state-default ui-corner-all new-id-button">' . lang::get('LANG_New_ID') . '</div>';
        }
        $r .= ' 
	  <div id="fo-doubt-button" class="ui-state-default ui-corner-all doubt-button">' . lang::get('LANG_Doubt') . '</div>
	  <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>';
        if (user_access('IForm n' . $node->nid . ' insect expert')) {
            $r .= '
	<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 . '" />
		' . ($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($focus_insect_ctrl_args) . '
        <input type="submit" id="id_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>';
        }
        if (user_access('IForm n' . $node->nid . ' flower expert')) {
            $r .= '
    <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 . '" />
		' . ($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($focus_flower_ctrl_args) . '
        <input type="submit" id="id_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>';
        }
        $r .= '
	<div id="fo-id-history" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	</div>
	<div id="fo-addn-info-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  <div id="fo-addn-info-title">
	  	<span>' . lang::get('LANG_Additional_Info_Title') . '</span>
      </div>
	</div>
	<div id="fo-insect-addn-info" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all ui-accordion-content-active">
	    <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-date"></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-sahed"></span></p>
	</div>
	<div id="fo-flower-addn-info" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all 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-all">
	    <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-corner-all 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-all ui-accordion-content-active">
	</div>
	<div style="display:none" />
      <form id="fo-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:id" value="" />
    	<input type="hidden" name="determination:dubious" value="Y" />
      </form>
    </div>	
</div>
';
        data_entry_helper::$javascript .= "\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";\njQuery('#start_date').datepicker({\n  dateFormat : 'yy-mm-dd',\n  constrainInput: false,\n  maxDate: '0'\n});\njQuery('#end_date').datepicker({\n  dateFormat : 'yy-mm-dd',\n  constrainInput: false,\n  maxDate: '0'\n});\n  \njQuery('#filter-header').click(function(){\n    jQuery('#filter-header').addClass('ui-state-active').removeClass('ui-state-default').addClass('ui-corner-top').removeClass('ui-corner-all');\n\tjQuery('#filter-spec,#filter-footer').removeClass('filter-hide');\n    jQuery('#results-collections-header,#results-insects-header').removeClass('ui-state-active').addClass('ui-state-default');\n    jQuery('#focus-occurrence,#focus-flower,#focus-collection,#results-insects-results,#results-collections-results').addClass('filter-hide');\n});\njQuery('#results-collections-header').click(function(){\n    jQuery('#results-collections-header').addClass('ui-state-active').removeClass('ui-state-default');\n\tjQuery('#results-collections-results').removeClass('filter-hide');\n    jQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n\tjQuery('#filter-spec,#filter-footer,#focus-occurrence,#focus-flower,#focus-collection,#results-insects-results').addClass('filter-hide');\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('filter-hide');\n});\njQuery('#reset-date-button').click(function(){\n\tjQuery('[name=start_date]').val('" . lang::get('click here') . "');\n\tjQuery('[name=end_date]').val('" . lang::get('click here') . "');\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('filter-hide');\n});\n\njQuery('#reset-flower-button').click(function(){\n\tjQuery('[name=flower\\:taxa_taxon_list_id]').val('');\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('filter-hide');\n});\n\njQuery('#reset-insect-button').click(function(){\n\tjQuery('[name=insect\\:taxa_taxon_list_id]').val('');\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('filter-hide');\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});\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('filter-hide');\n});\n\njQuery('#flower-image').click(function(){\n\tif(jQuery('#flower-image').attr('occID') != 'none'){\n\t\tloadFlower(jQuery('#flower-image').attr('occID'));\n\t}\n});\n\njQuery('#fo-doubt-button').click(function(){\n\tif(confirm(\"" . lang::get('LANG_Confirm_Express_Doubt') . "\")){\n\t\tjQuery('#fo-doubt-form').submit();\n\t}\n});\n\n\n\nloadCollection = function(id){\n    jQuery('[name=sample_comment\\:sample_id]').val(id);\n    locationLayer.destroyFeatures();\n\tjQuery('#fc-new-comment-button')." . (user_access('IForm n' . $node->nid . ' create collection comment') ? "show()" : "hide()") . ";\n    jQuery('#focus-occurrence,#filter-spec,#filter-footer,#results-insects-header,#results-insects-results,#results-collections-results').addClass('filter-hide');\n    jQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n    jQuery('#focus-collection').removeClass('filter-hide');\n\tjQuery('#map2').width(jQuery('#map2_container').width());\n\tjQuery('#flower-image').attr('occID', 'none');\n\tjQuery('#collection-insects,#collection-date,#collection-name,#collection-flower-name,#collection-flower-type,#collection-habitat,#collection-user-name').empty();\n\t// this has a fixed target so can be done asynchronously.\n\t\$.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+\"&callback=?\", function(flowerData) {\n   \t\tif (flowerData.length>0) {\n\t\t\tloadImage('occurrence_image', 'occurrence_id', flowerData[0].id, '#flower-image');\n\t\t\tjQuery('#flower-image').attr('occID', flowerData[0].id);\n\t\t\t\$.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&callback=?\", function(detData) {\n   \t\t\t\tif (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 = string + detData[i].taxon + ', ';\n\t\t\t\t\t}\n\t\t\t\t\tif(detData[i].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\t\t\tstring = string + detData[i].taxon_text_description + ', ';\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 + detData[i].taxon_extra_info;\n\t\t\t\t\t}\n\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Flower_Name') . ": '+string+'</span>').appendTo('#collection-flower-name');\n\t\t\t\t}});\n\t\t\t\$.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 . "&callback=?\", function(attrdata) {\n\t\t\t\tif (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\t\$.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 + \"&callback=?\", function(attrdata) {\n\t\tif (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}}}}});\n  \t\n\t// this has a fixed target so can be done asynchronously.\n\t\$.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\"&callback=?\", function(collectionData) {\n   \t\tif (collectionData.length>0) {\n\t\t\tif(collectionData[0].date_start == collectionData[0].date_end){\n\t  \t\t\tjQuery('<span>'+collectionData[0].date_start.substring(0,10)+'</span>').appendTo('#collection-date');\n    \t\t} else {\n\t  \t\t\tjQuery('<span>'+collectionData[0].date_start+' - '+collectionData[0].date_end+'</span>').appendTo('#collection-date');\n    \t\t}\n\t  \t\tjQuery('<span>'+collectionData[0].location_name+'</span>').appendTo('#collection-name');\n   \t\t    \$.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\"&callback=?\", function(locationData) {\n   \t\t\t\tif (locationData.length>0) {\n\t\t\t\t\tloadImage('location_image', 'location_id', locationData[0].id, '#environment-image');\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        locationLayer.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: test, scope: scope, async: false});\n\t\t\t\t}\n\t\t\t});\n\t\t\t\$.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 . "&callback=?\", function(attrdata) {\n\t\t\t\tif (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\$.getJSON(\"" . $svcUrl . "/data/sample\" + \n\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&parent_id=\"+id+\"&callback=?\", function(sessiondata) {\n  \t\tif (sessiondata.length>0) {\n\t\t\tfor (var i=0;i<sessiondata.length;i++){\n\t\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'] . "\" +\n\t\t\t\t\t\t\"&sample_id=\"+sessiondata[i].id+\"&orderby=id&callback=?\", function(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\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\tjQuery('<p class=\"insect-tag insect-unknown\" />').appendTo(insect);\n\t\t\t\t\t\t\tvar image = jQuery('<div class=\"insect-image\" />').appendTo(insect);\n\t\t\t\t\t\t\tjQuery('<p class=\"insect-determination\" />').appendTo(insect);\n\t\t\t\t\t\t\tvar displayButton = jQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>')\n\t\t\t\t\t\t\t\t.appendTo(insect).attr('value',insectData[j].id);\n\t\t\t\t\t\t\tdisplayButton.click(function(){\n\t\t\t\t\t\t\t\tloadInsect(jQuery(this).attr('value'));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tloadImage('occurrence_image', 'occurrence_id', insectData[j].id, image);\n\t\t\t\t\t\t\t// have to do this synchronously due to multiple targets\n\t\t\t\t\t\t\t\$.getJSON(\"" . $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&callback=?\", function(detData) {\n   \t\t\t\t\t\t\t\tif (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 = string + 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].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\t\t\t\t\t\t\tstring = string + detData[i].taxon_text_description + ', ';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\t\t\t\t\t\t\tstring = string + detData[i].taxon_extra_info;\n\t\t\t\t\t\t\t\t\t}\n\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].dubious == 'Y'){\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}});  \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}\n\t});\n\tloadComments(id, '#fc-comment-list', 'sample_comment', 'sample_id', 'sample-comment-block', 'sample-comment-body');\n};\ntest = function(a1)\n{\n\tjQuery(this.target).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(this.target);\n}\naddCollection = function(attributes, geom){\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\" />').attr('occID', attributes.flower_id).click(function(){\n\t\tloadFlower(jQuery(this).attr('occID'));\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\tvar img = new Image();\n\t\$(img).load(function () {flower.append(this);})\n\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+attributes.flower_image_path)\n\t    .css('max-width', flower.width()).css('max-height', flower.height())\n\t    .css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\tvar location = jQuery('<div class=\"collection-image collection-environment\" />').appendTo(collection);\n\timg = new Image();\n\t\$(img).load(function () {location.append(this)})\n\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+attributes.location_image_path)\n\t    .css('max-width', location.width()).css('max-height', location.height())\n\t    .css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\tvar photoReel = jQuery('<div class=\"collection-photoreel\"></div>').appendTo(collection);\n\tvar displayButtonContainer = jQuery('<div class=\"collection-buttons\"></div>').appendTo(collection);\n\tvar displayButton = jQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>');\n\tdisplayButton.click(function(){\n\t\tloadCollection(jQuery(this).attr('value'));\n\t}).appendTo(displayButtonContainer).attr('value',attributes.collection_id);\n\tif(attributes.date_start == attributes.date_end){\n\t  jQuery('<p class=\"collection-date\">'+attributes.date_start.substring(0,10)+'</p>').appendTo(details);\n    } else {\n\t  jQuery('<p class=\"collection-date\">'+attributes.date_start+' - '+attributes.date_end+'</p>').appendTo(details);\n    }\n\tjQuery('<p class=\"collection-name\">'+attributes.location_name+'</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: test, scope: scope, async: false});\n    \$.getJSON(\"" . $svcUrl . "/data/sample\" + \n    \t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&parent_id=\"+attributes.collection_id+\"&callback=?\", function(sessiondata) {\n\t\tfor (var i=0;i<sessiondata.length;i++){\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+\"&callback=?\", function(insectData) {\n\t\t    \tif (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()).click(function () {loadInsect(jQuery(this).attr('occId'));});\n\t\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Unknown') . "</span>').addClass('thumb-text').appendTo(container);\n\t\t\t\t\t\tphotoReel.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.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\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 + \"&deleted=f&callback=?\", function(detData) {\n\t\t\t\t\t\t      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        container.find('.thumb-text').remove();\n\t\t\t\t\t\t        if(detData[detData.length-1].dubious == 'Y'){\n\t\t\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}\n  \t\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(attributes){\n\tvar container=jQuery('<div class=\"ui-widget-content ui-corner-all filter-insect\" />').appendTo('#results-insects-results');\n\tvar flag = jQuery('<div />').addClass('insect-ok').appendTo(container);\n\tvar insect = jQuery('<div class=\"insect-image\" />').attr('occID', attributes.insect_id).click(function(){\n\t\tloadInsect(jQuery(this).attr('occID'));\n\t});\n\tinsect.appendTo(container);\n\tvar img = new Image();\n\t\$(img).load(function () {insect.append(this);})\n\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+attributes.insect_image_path)\n\t\t.css('max-width', insect.width()).css('max-height', insect.width()*imageRatio)\n\t    .css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\t\$.getJSON(\"" . $svcUrl . "/data/determination\" +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&occurrence_id=\" + attributes.insect_id + \"&callback=?\", function(detData) {\n   \t\tif (detData.length>0) {\n\t\t\tvar i = detData.length-1;\n   \t\t\tvar string = '';\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].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\tstring = (string == '' ? '' : string + ', ') + detData[i].taxon_text_description;\n\t\t\t}\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('<p>'+string+'</p>').appendTo(container)\n\t\t\tif(detData[i].dubious == 'Y'){\n\t\t\t\tjQuery(flag).removeClass('insect-ok').addClass('insect-dubious');\n\t\t\t}\n\t\t} else {\n\t\t\tjQuery(flag).removeClass('insect-ok').addClass('insect-unknown');\n\t\t\tjQuery(\"<p>" . lang::get('LANG_No_Determinations') . "</p>\")\n\t\t\t\t\t.appendTo(container);\n\t\t}\n\t});\n\tvar displayButton = jQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>');\n\tdisplayButton.click(function(){\n\t\tloadInsect(jQuery(this).attr('value'));\n\t}).appendTo(container).attr('value',attributes.insect_id);\n};\n\n\nsetCollectionPage = function(pageNum){\n\tjQuery('#results-collections-results').empty();\n\tvar numPages = Math.ceil(searchResults.features.length/" . $args['collectionsPerPage'] . ");\n\tif(numPages > 1) {\n\t\tvar pageCtrl = jQuery('<div>').addClass('page-control').appendTo('#results-collections-results');\n\t\tvar pageCtrl2 = jQuery('<div>').addClass('page-control');\n\t\tvar first = true;\n\t\tfor (var j = (pageNum < 6  ? 1 : pageNum - 5); j <= numPages && j <= (pageNum + 5); j++){\n\t\t\tif (first != true){\n\t\t\t\tjQuery('<span>|</span>').appendTo(pageCtrl);\n\t\t\t\tjQuery('<span>|</span>').appendTo(pageCtrl2);\n  \t\t\t}\n  \t\t\tfirst = false;\n\t\t\tif( j != pageNum) {\n\t\t\t\tjQuery('<a>'+j+'</a>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a>'+j+'</a>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl2);\n  \t\t\t} else {\n\t\t\t\tjQuery('<span>'+j+'</span>').appendTo(pageCtrl);\n\t\t\t\tjQuery('<span>'+j+'</span>').appendTo(pageCtrl2);\n  \t\t\t}\n\t    }\n\t}\n    for (var i = (pageNum-1)*" . $args['collectionsPerPage'] . "; i < searchResults.features.length && i < pageNum*" . $args['collectionsPerPage'] . "; i++){\n\t\taddCollection(searchResults.features[i].attributes,searchResults.features[i].geometry);\n\t}\n\tif(numPages > 1) {\n\t\tpageCtrl2.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['insectsPerPage'] . ");\n\tif(numPages > 1) {\n\t\tvar pageCtrl = jQuery('<div>').addClass('page-control').appendTo('#results-insects-results');\n\t\tvar pageCtrl2 = jQuery('<div>').addClass('page-control');\n\t\tvar first = true;\n\t\tfor (var j = (pageNum < 6  ? 1 : pageNum - 5); j <= numPages && j <= (pageNum + 5); j++){\n\t\t\tif (first != true){\n\t\t\t\tjQuery('<span>|</span>').appendTo(pageCtrl);\n\t\t\t\tjQuery('<span>|</span>').appendTo(pageCtrl2);\n  \t\t\t}\n  \t\t\tfirst = false;\n\t\t\tif( j != pageNum) {\n\t\t\t\tjQuery('<a>'+j+'</a>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a>'+j+'</a>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl2);\n  \t\t\t} else {\n\t\t\t\tjQuery('<span>'+j+'</span>').appendTo(pageCtrl);\n\t\t\t\tjQuery('<span>'+j+'</span>').appendTo(pageCtrl2);\n  \t\t\t}\n\t    }\n\t}\n    for (var i = (pageNum-1)*" . $args['insectsPerPage'] . "; i < searchResults.features.length && i < pageNum*" . $args['insectsPerPage'] . "; i++){\n\t\taddInsect(searchResults.features[i].attributes);\n\t}\n\tif(numPages > 1) {\n\t\tpageCtrl2.appendTo('#results-insects-results');\n\t}\n}\n\n// searchLayer in map is used for georeferencing.\n// map editLayer is switched off.\nsearchLayer = null;\ninseeLayer = null;\npolygonLayer = new OpenLayers.Layer.Vector('Polygon Layer', {\n\tstyleMap: new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Red\",\n                    strokeColor: \"Red\",\n                    fillOpacity: 0,\n                    strokeWidth: 1\n                  })\n\t}),\n\tdisplayInLayerSwitcher: false\n});\npolygonLayer.events.register('featuresadded', {}, function(a1){\n\tpolygonLayer.map.searchLayer.destroyFeatures();\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroyFeatures();\n});          \nlocationLayer = new OpenLayers.Layer.Vector('Location Layer',\n\t{displayInLayerSwitcher: false});\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  \t\t\t});\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').addClass('filter-hide');\n\tjQuery('#results-collections-header,#results-collections-results').removeClass('filter-hide');\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').addClass('filter-hide');\n\tjQuery('#results-insects-header,#results-insects-results').removeClass('filter-hide');\n\tjQuery('#results-insects-header').addClass('ui-state-active').removeClass('ui-state-default');\n\trunSearch(false);\n});\n\nrunSearch = function(forCollections){\n  \tvar ORgroup = [];\n\t\n  \tif(searchLayer != null)\n\t\tsearchLayer.destroy();\n\t\t\n\tvar use_insects = false;\n    jQuery('#results-collections-results,#results-insects-results').empty();\n\tjQuery('#focus-occurrence,#focus-collection').addClass('filter-hide');\n\tvar filters = [];\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){\n\t  filters.push(new OpenLayers.Filter.Spatial({\n    \ttype: OpenLayers.Filter.Spatial.BBOX,\n    \tproperty: 'geom',\n    \tvalue: mapBounds\n  \t  }));\n  \t}\n  \tif(inseeLayer != null){\n  \t\tif(inseeLayer.features.length > 0){\n  \t\t\t// should only be one entry in the inseeLayer\n\t\t\tfilters.push(new OpenLayers.Filter.Spatial({\n    \t\t\ttype: OpenLayers.Filter.Spatial.WITHIN,\n    \t\t\tproperty: 'geom',\n    \t\t\tvalue: inseeLayer.features[0].geometry\n\t\t  \t}));\n  \t\t}\n  \t}\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({\n    \t\t\t\ttype: OpenLayers.Filter.Spatial.WITHIN,\n\t    \t\t\tproperty: 'geom',\n    \t\t\t\tvalue: polygonLayer.features[i].geometry\n\t\t  \t\t}));\n  \t\t\t}\n\t\t  \tif(ORgroup.length > 1){\n\t\t\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\t\t\tfilters: ORgroup\n\t\t\t\t}));\n\t\t\t} else {\n  \t\t\t\tif(ORgroup.length == 1){\n\t\t\t \t\tfilters.push(ORgroup[0]);\n\t \t\t\t}\n\t\t  \t} \t\n  \t\t}\n  \t}\n  \t// Only deal with completed collections on our survey.\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\ttype: OpenLayers.Filter.Comparison.LIKE,\n    \tproperty: 'collection_attributes',\n    \tvalue: '*{|" . $args['complete_attr_id'] . "|,1}*'\n  \t}));\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO,\n    \tproperty: 'survey_id',\n    \tvalue: '" . $args['survey_id'] . "'\n  \t}));\n  \t\n  \tvar user = jQuery('input[name=username]').val();\n  \tif(user != ''){\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE,\n    \t\tproperty: 'collection_attributes',\n    \t\tvalue: '*{|" . $args['username_attr_id'] . "|,'+user+'}*'\n  \t\t}));\n  \t}\n  \t\n  \tvar start_date = jQuery('input[name=start_date]').val();\n  \tvar end_date = jQuery('input[name=end_date]').val();\n  \tif(start_date != '" . lang::get('click here') . "' && start_date != ''){\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.GREATER_THAN  ,\n    \t\tproperty: 'date_end',\n    \t\tvalue: start_date\n  \t\t}));\n  \t}\n  \tif(end_date != '" . lang::get('click here') . "' && end_date != ''){\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LESS_THAN  ,\n    \t\tproperty: 'date_start',\n    \t\tvalue: end_date\n  \t\t}));\n  \t}\n  \t\n  \tvar flower = jQuery('select[name=flower\\:taxa_taxon_list_id]').val();\n  \tif(flower != ''){\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'flower_taxon',\n    \t\tvalue: '*|'+flower+'|*'\n  \t\t}));\n  \t}\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({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'flower_attributes',\n    \t\tvalue: '*{|" . $args['flower_type_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n \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({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'location_attributes',\n    \t\tvalue: '*{|" . $args['habitat_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n  \t\n  \tvar insect = jQuery('select[name=insect\\:taxa_taxon_list_id]').val();\n  \tif(insect != ''){\n  \t\tuse_insects = true;\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: forCollections ? 'insects' : 'insect_taxon',\n    \t\tvalue: '*|'+insect+'|*'\n  \t\t}));\n  \t}\n\n  \tORgroup = [];\n  \tjQuery('#insect-filter-body').find('[name^=smpAttr:" . $args['sky_state_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tuse_insects = true;\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'session_attributes',\n    \t\tvalue: '*{|" . $args['sky_state_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n\n  \tORgroup = [];\n  \tjQuery('#insect-filter-body').find('[name^=smpAttr:" . $args['temperature_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tuse_insects = true;\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'session_attributes',\n    \t\tvalue: '*{|" . $args['temperature_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n\n  \tORgroup = [];\n  \tjQuery('#insect-filter-body').find('[name^=smpAttr:" . $args['wind_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tuse_insects = true;\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'session_attributes',\n    \t\tvalue: '*{|" . $args['wind_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n\n\t// TODO need to do shade : this needs to be altered so that the attribute is a termlist\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: forCollections ? (use_insects ? 'poll_collection_insects' : 'poll_collections') : 'poll_insects',\n              geometryName:'geom',\n              featureNS: '" . $args['search_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0',   \n              maxFeatures: " . $args['max_features'] . ",               \n//      \t\t  propertyNames: forCollections ? ['collection_id','date_start','date_end','geom','location_name','location_image_path','flower_image_path','flower_id','flower_taxon','collection_attributes','location_attributes','flower_attributes']\n              propertyNames: forCollections ? ['collection_id','date_start','date_end','geom','location_name','location_image_path','flower_image_path','flower_id','flower_taxon','collection_attributes','location_attributes','flower_attributes']\n      \t\t  \t\t\t\t\t\t\t: ['insect_id','collection_id','geom','insect_image_path']\n\t\t  })\n\t});\n\tif(forCollections) {\n\t\tsearchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tsearchResults = a1;\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} else {\n\t\tsearchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tsearchResults = a1;\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}\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\njQuery('form#fo-doubt-form').ajaxForm({ \n\tdataType:  'json', \n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id');\n\t\t\tjQuery('[name=occurrence_comment\\:comment]').val(\"" . lang::get('LANG_Doubt_Comment') . "\");\n\t\t\tjQuery('#fo-new-comment-button').click();\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('form#fo-new-insect-id-form').ajaxForm({ \n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fo-new-insect-id-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=determination\\:taxa_taxon_list_id]').val('');\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');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('form#fo-new-flower-id-form').ajaxForm({ \n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fo-new-flower-id-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=determination\\:taxa_taxon_list_id]').val('');\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');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('#fo-new-comment-form').ajaxForm({ \n\t// dataType identifies the expected content type of the server response \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');\n  \t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('#fc-new-comment-form').ajaxForm({ \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');\n  \t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\n\nloadSampleAttributes = function(keyValue){\n\tjQuery('#fo-insect-start-time,#fo-insect-end-time,#fo-insect-sky,#fo-insect-temp,#fo-insect-wind,#fo-insect-shade').empty();\n\t\$.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 + \"&callback=?\", function(attrdata) {\n\t\tif (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\tjQuery('#fo-insect-shade').append(attrdata[i].value);\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\tjQuery('#focus-flower-type').empty();\n\t\$.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 . "&callback=?\", function(attrdata) {\n\t\tif (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\tjQuery('#focus-habitat').empty();\n\thabitat_string = '';\n\t\$.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 . "&callback=?\", function(attrdata) {\n\t\tif (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].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] : (habitat_string + ' | ' + attrdata[i]));\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}\nimageRatio = 3/4;\n\nloadImage = function(imageTable, key, keyValue, target){\n\tjQuery(target).empty();\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 img = new Image();\n\t\t\tjQuery(img)\n        \t\t.load(function () {\n        \t\t\tjQuery(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 . "'+imageData[0].path)\n\t\t\t\t.css('max-width', \$(target).width()).css('max-height', \$(target).width()*imageRatio)\n\t\t\t\t.css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\t\t}\n\t});\n}\n\nloadDeterminations = function(keyValue, historyID, currentID){\n\tjQuery(historyID).empty().append('<strong>" . lang::get('LANG_History_Title') . "</strong>');\n\tjQuery(currentID).empty();\n\tjQuery('#fo-taxon').empty();\n\tjQuery('#fo-warning').addClass('insect-ok').removeClass('insect-dubious').removeClass('insect-unknown');\n\t\$.getJSON(\"" . $svcUrl . "/data/determination\" +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&occurrence_id=\" + keyValue + \"&callback=?\", function(detData) {\n   \t\tif (detData.length>0) {\n\t\t\tvar i = detData.length-1;\n   \t\t\tjQuery('#fo-doubt-form').find('[name=determination\\:id]').val(detData[i].id);\n   \t\t\tjQuery('#fo-doubt-form').find('[name=determination\\:occurrence_id]').val(detData[i].occurrence_id);\n   \t\t\tvar string = '';\n\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\tstring = detData[i].taxon;\n\t\t\t\tjQuery('#fo-taxon').append(detData[i].taxon);\n  \t\t\t}\n\t\t\tif(detData[i].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\tstring = (string == '' ? '' : string + ', ') + detData[i].taxon_text_description;\n\t\t\t}\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_text_description;\n\t\t\t}\n\t\t\tjQuery('<p><strong>'+string+ '</strong> " . lang::get('LANG_Comment_By') . "' + detData[i].person_name + ' ' + detData[i].updated_on + '</p>').appendTo(currentID)\n\t\t\tif(detData[i].dubious == 'Y'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Doubt_Expressed') . "</p>\").appendTo(currentID)\n\t\t\t\tjQuery('#fo-warning').removeClass('insect-ok').addClass('insect-dubious');\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\tvar string = detData[i].updated_on + ' : ';\n\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\tstring = string + detData[i].taxon + ', ';\n\t\t\t\t}\n\t\t\t\tif(detData[i].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\t\tstring = string + detData[i].taxon_text_description + ', ';\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 + detData[i].taxon_text_description ;\n\t\t\t\t}\n\t\t\t\tjQuery('<p>'+string+ ' " . lang::get('LANG_Comment_By') . "' + detData[i].person_name+'</p>').appendTo(historyID)\n\t\t\t}\n\t\t} else {\n\t\t\tjQuery('#fo-doubt-button').hide();\n\t\t\tjQuery('#fo-warning').removeClass('insect-ok').addClass('insect-unknown');\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Determinations') . "</p>')\n\t\t\t\t\t.appendTo(historyID);\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Determinations') . "</p>')\n\t\t\t\t\t.appendTo(currentID);\n\t\t}\n\t});\n};\nloadComments = function(keyValue, block, table, key, blockClass, bodyClass){\n\tjQuery(block).empty();\n\t\$.getJSON(\"" . $svcUrl . "/data/\" + table +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\", function(commentData) {\n   \t\tif (commentData.length>0) {\n   \t\t\tfor(i=commentData.length - 1; i >= 0; i--){\n\t   \t\t\tvar newCommentDetails = jQuery('<div class=\"'+blockClass+'\"/>')\n\t\t\t\t\t.appendTo(block);\n\t\t\t\tjQuery('<span>" . lang::get('LANG_Comment_By') . "' + commentData[i].person_name + ' ' + commentData[i].updated_on + '</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(block);\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(block);\n\t\t}\n\t});\n};\n\nloadInsectAddnInfo = function(keyValue){\n\t// TODO convert buttons into thumbnails\n\tcollection = '';\n\tjQuery('#fo-prev-button,#fo-next-button').hide();\n\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\t\$.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\"&callback=?\", function(occData) {\n   \t\tif (occData.length > 0) {\n\t\t\t\$.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\"&callback=?\", function(smpData) {\n   \t\t\t\tif (smpData.length > 0) {\n   \t\t\t\t\tcollection = smpData[0].parent_id;\n\t\t\t\t\tjQuery('#fo-insect-date').empty().append(smpData[0].date_start);\n\t\t\t\t\tloadSampleAttributes(smpData[0].id);\n\t\t\t\t\tjQuery('#fo-collection-button').attr('smpID',smpData[0].parent_id).show();\n\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/sample/\" +\n   \t\t\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\t\t\"&parent_id=\" + smpData[0].parent_id + \"&callback=?\", function(smpList) {\n   \t\t\t\t\t\tif (smpList.length > 0) {\n   \t\t\t\t\t\t\tfor(j=0; j< smpList.length; j++){\n\t\t   \t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence\" +\n   \t\t\t\t\t\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\t\t\t\t\t\"&sample_id=\" + smpList[j].id + \"&orderby=id&callback=?\", function(occList) {\n\t   \t\t\t\t\t\t\t\tif(occList.length > 0){\n   \t\t\t\t\t\t\t\t\t\tfor(i=0; i< occList.length; i++){\n   \t\t\t\t\t\t\t\t\t\t\tif(parseInt(occList[i].id) == parseInt(keyValue)){\n   \t\t\t\t\t\t\t\t\t\t\t\tif(i>0){\n\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#fo-prev-button').attr('occID',occList[i-1].id).show();\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\tif(i< occList.length-1){\n\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#fo-next-button').attr('occID',occList[i+1].id).show();\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}\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}\n   \t\t   \t});\n   \t\t}\n   \t});\n}\nloadFlowerAddnInfo = function(keyValue){\n\t// fetch occurrence details first to get the collection id.\n\tloadOccurrenceAttributes(keyValue);\n\t\$.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\"&callback=?\", function(occData) {\n   \t\tif (occData.length > 0) {\n\t\t\tjQuery('#fo-collection-button').attr('smpID',occData[0].sample_id).show();\n   \t\t\t\$.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\"&callback=?\", function(collection) {\n   \t\t\t\tif (collection.length > 0) {\n\t\t\t\t\tloadLocationAttributes(collection.location_id);\n  \t\t\t\t}\n   \t\t   \t});\n   \t\t}\n   \t});\n}\n\nloadInsect = function(insectID){\n    jQuery('#focus-collection,#filter-spec,#filter-footer,#results-insects-header,#results-collections-header,#results-insects-header,#results-insects-results,#results-collections-results,#fo-flower-addn-info').addClass('filter-hide');\n    jQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n    jQuery('#focus-occurrence,#fo-addn-info-header,#fo-insect-addn-info').removeClass('filter-hide');\n\tjQuery('[name=determination\\:occurrence_id]').val(insectID);\n\tjQuery('[name=occurrence_comment\\:occurrence_id]').val(insectID);\n\tjQuery('#fo-new-comment,#fo-new-id').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-new-insect-id-button').show();\n\tjQuery('#fo-new-flower-id-button').hide();\n\tjQuery('#fo-doubt-button')." . (user_access('IForm n' . $node->nid . ' insect expert') || user_access('IForm n' . $node->nid . ' flag dubious insect') ? "show()" : "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\tloadImage('occurrence_image', 'occurrence_id', insectID, '#fo-image');\n\tloadDeterminations(insectID, '#fo-id-history', '#fo-current-id');\n\tloadInsectAddnInfo(insectID);\n\tloadComments(insectID, '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body');\n}\nloadFlower = function(flowerID){\n\tjQuery('#fo-prev-button,#fo-next-button').hide();\n\tjQuery('#focus-collection,#filter-spec,#filter-footer,#results-insects-header,#results-collections-header,#results-insects-header,#results-insects-results,#results-collections-results,#fo-insect-addn-info').addClass('filter-hide');\n    jQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n\tjQuery('#focus-occurrence,#fo-addn-info-header,#fo-flower-addn-info').removeClass('filter-hide');\n\tjQuery('#fo-new-comment,#fo-new-id').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-doubt-button')." . (user_access('IForm n' . $node->nid . ' flower expert') || user_access('IForm n' . $node->nid . ' flag dubious flower') ? "show()" : "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\tloadImage('occurrence_image', 'occurrence_id', flowerID, '#fo-image');\n\tloadDeterminations(flowerID, '#fo-id-history', '#fo-current-id');\n\tloadFlowerAddnInfo(flowerID);\n\tloadComments(flowerID, '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body');\n}\n\njQuery('#fo-new-comment-button').click(function(){ \n\tjQuery('#fo-new-comment').toggleClass('ui-accordion-content-active');\n});\njQuery('#fc-new-comment-button').click(function(){ \n\tjQuery('#fc-new-comment').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-insect-id-button').click(function(){ \n\tjQuery('#fo-new-insect-id').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-flower-id-button').click(function(){ \n\tjQuery('#fo-new-flower-id').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-collection-button').click(function(){\n\tloadCollection(jQuery(this).attr('smpID'));\n});\njQuery('#fo-prev-button').click(function(){\n\tloadInsect(jQuery(this).attr('occID'));\n});\njQuery('#fo-next-button').click(function(){\n\tloadInsect(jQuery(this).attr('occID'));\n});\n  ";
        data_entry_helper::$onload_javascript .= "\n\tfunction addDrawnGeomToSelection (geometry) {\n    \t// Create the polygon as drawn\n    \tvar feature = new OpenLayers.Feature.Vector(geometry, {});\n    \tpolygonLayer.addFeatures([feature]);\n\t};\n    \n\tpolygonControl = new OpenLayers.Control.DrawFeature(polygonLayer, OpenLayers.Handler.Polygon, {drawFeature: addDrawnGeomToSelection});\n\tpolygonLayer.map.addControl(this.polygonControl);\n\tpolygonControl.activate();\n\tpolygonLayer.map.searchLayer.events.register('featuresadded', {}, function(a1){\n\t\tif(inseeLayer != null)\n\t\t\tinseeLayer.destroyFeatures();\n\t\tpolygonLayer.destroyFeatures();\n\t});          \n";
        switch ($mode) {
            case 'INSECT':
                data_entry_helper::$onload_javascript .= "loadInsect(" . $occID . ");\n\t\t\t";
                break;
            case 'FLOWER':
                data_entry_helper::$onload_javascript .= "loadFlower(" . $occID . ");\n\t\t\t";
                break;
            case 'COLLECTION':
                data_entry_helper::$onload_javascript .= "\n    \t\tjQuery('#focus-occurrence,#filter-spec,#filter-footer,#results-insects-header,#results-collections-header,#results-insects-results,#results-collections-results').addClass('filter-hide');\n    \t\tjQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n    \t\tloadCollection(" . $smpID . ");\n    \t\t";
                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').addClass('filter-hide');\n    \t\t";
                if ($userID != '') {
                    $thisuser = user_load($userID);
                    data_entry_helper::$onload_javascript .= "\n    \t\t\tjQuery('[name=username]').val('" . $thisuser->name . "');\n    \t\t\tjQuery('#search-collections-button').click();\n    \t\t\t";
                }
                break;
        }
        return $r;
    }
Пример #16
0
 protected static function getAttributes($args, $auth)
 {
     //Always hide the preferred boundary textbox as the user shouldn't see it.
     //Only hide, don't remove it, as we still need the value from it.
     data_entry_helper::$javascript .= "\r\n      \$('#locAttr\\\\:" . $args['preferred_boundary_attribute_id'] . "').hide();\r\n      \$('[for=\"locAttr\\\\:" . $args['preferred_boundary_attribute_id'] . "\"]').hide();\n\r\n    ";
     //Get the preferred boundary id for use if we are viewing a count unit
     $preferredBoundaryLocationIdCalculatedFromCountUnit = self::getIdForCountUnitPreferredBoundaryIfApplicable($args, $auth);
     if (!empty($_GET['parent_id'])) {
         //If we are looking at a count unit boundary, then we have both the parent and boundary ids available to us
         $parentId = $_GET['parent_id'];
         $boundaryId = $_GET['location_id'];
     } else {
         //If we are looking at a count unit instead of a boundary, then we need to get the preferred boundary id
         $parentId = $_GET['location_id'];
         $boundaryId = $preferredBoundaryLocationIdCalculatedFromCountUnit;
     }
     //Get attributes associated with the parent
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $attrOpts = array('id' => $parentId, 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $args['count_unit_location_type_id']);
     $mainAttributes = data_entry_helper::getAttributes($attrOpts, false);
     //Get attributes associated with the boundary
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $attrOpts = array('id' => $boundaryId, 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $args['count_unit_boundary_location_type_id']);
     $boundaryAttributes = data_entry_helper::getAttributes($attrOpts, false);
     //Merge the parent and child boundary attributes if needed so we have both sets of attributes.
     if (empty($mainAttributes)) {
         $mainAttributes = array();
     }
     if (empty($boundaryAttributes)) {
         $boundaryAttributes = array();
     }
     $attributes = array_merge($mainAttributes, $boundaryAttributes);
     //Need to format any dates from the database manually.
     foreach ($attributes as $attributeNum => &$attributeData) {
         if ($attributeData['data_type'] === 'D' && !empty($attributeData['displayValue'])) {
             $d = new DateTime($attributeData['displayValue']);
             $attributeData['displayValue'] = $d->format('d/m/Y');
             $attributeData['default'] = $attributeData['displayValue'];
         }
     }
     //Disable Verified checkbox for normal users, note that we use a selector for a field whose name starts with locAttr:<Verified Attribute ID>
     //as there is a hidden field with the same name but no id and we want to disable both so they are not submitted in the post.
     if ($args['administrator_mode'] == 0) {
         data_entry_helper::$javascript .= "\$(\"input[name^='locAttr\\\\:" . $args['verified_attribute_id'] . "']\").attr('disabled','true');";
     }
     return $attributes;
 }
 /**
  * Load the list of occurrence attributes into a static variable. 
  *
  * By maintaining a single list of attributes we can track which have already been output.
  * @param array $readAuth Read authorisation tokens.
  * @param integer $surveyId ID of the survey to load occurrence attributes for.
  */
 protected static function load_custom_occattrs($readAuth, $surveyId)
 {
     if (!isset(self::$occAttrs)) {
         // Add any dynamically generated controls
         $attrArgs = array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth, 'survey_id' => $surveyId);
         if (count(self::$occurrenceIds) == 1) {
             // if we have a single occurrence Id to load, use it to get attribute values
             $attrArgs['id'] = self::$occurrenceIds[0];
         }
         self::$occAttrs = data_entry_helper::getAttributes($attrArgs, false);
     }
 }
 private static function getAttr($auth, $args, $table, $caption)
 {
     switch ($table) {
         case 'occurrence':
             $prefix = 'occAttr';
             break;
         case 'sample':
             $prefix = 'smpAttr';
             break;
         case 'location':
             $prefix = 'locAttr';
             break;
         default:
             return false;
     }
     $myAttributes = data_entry_helper::getAttributes(array('valuetable' => $table . '_attribute_value', 'attrtable' => $table . '_attribute', 'key' => $table . '_id', 'fieldprefix' => $prefix, 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']), false);
     foreach ($myAttributes as $attr) {
         if (strcasecmp($attr['untranslatedCaption'], $caption) == 0) {
             return $attr;
         }
     }
     return false;
 }
Пример #19
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;
    }
 /**
  * Return the Indicia form code
  * @param array $args Input parameters.
  * @param array $node Drupal node object
  * @param array $response Response from Indicia services after posting a verification.
  * @return HTML string
  */
 public static function get_form($args, $node, $response)
 {
     global $user;
     $logged_in = $user->uid > 0;
     if (!$logged_in) {
         return '<p>' . lang::get('Please log in before attempting to use this form.') . '</p>';
     }
     // can't really do this automatically: better to give warning
     if (isset($args['locationTypeFilter'])) {
         return '<p>' . lang::get('Please contact the site administrator. This version of the form uses a different method of specifying the location types.') . '</p>';
     }
     iform_load_helpers(array('report_helper'));
     $auth = report_helper::get_read_auth($args['website_id'], $args['password']);
     if (!self::set_up_survey($args, $auth)) {
         return lang::get('set_up_survey returned false: survey_id missing from presets or location_type definition.');
     }
     $reportOptions = self::get_report_calendar_options($args, $auth);
     $reportOptions['id'] = 'calendar-summary-' . $node->nid;
     if (!empty($args['removable_params'])) {
         self::$removableParams = get_options_array_with_user_data($args['removable_params']);
     }
     self::copy_args($args, $reportOptions, array('weekstart', 'weekOneContains', 'weekNumberFilter', 'outputTable', 'outputChart', 'simultaneousOutput', 'tableHeaders', 'chartLabels', 'disableableSeries', 'chartType', 'rowGroupColumn', 'rowGroupID', 'width', 'height', 'includeTableTotalRow', 'includeTableTotalColumn', 'includeChartTotalSeries', 'includeChartItemSeries', 'includeRawData', 'includeSummaryData', 'includeEstimatesData', 'summaryDataCombining', 'dataRound', 'zeroPointAnchor', 'interpolation', 'firstValue', 'lastValue', 'linkURL', 'includeRawGridDownload', 'includeRawListDownload', 'includeSummaryGridDownload', 'includeEstimatesGridDownload', 'includeListDownload', 'avgFields'));
     if (isset($_GET['outputSource'])) {
         $reportOptions['outputSource'] = $_GET['outputSource'];
     }
     if (isset($_GET['outputFormat'])) {
         $reportOptions['outputFormat'] = $_GET['outputFormat'];
     } else {
         $reportOptions['outputFormat'] = $args['defaultOutput'];
     }
     if (isset($_GET['outputSeries'])) {
         $reportOptions['outputSeries'] = $_GET['outputSeries'];
     }
     // default is all
     // Advanced Chart options
     $rendererOptions = trim($args['renderer_options']);
     if (!empty($rendererOptions)) {
         $reportOptions['rendererOptions'] = json_decode($rendererOptions, true);
     }
     $legendOptions = trim($args['legend_options']);
     if (!empty($legendOptions)) {
         $reportOptions['legendOptions'] = json_decode($legendOptions, true);
     }
     $axesOptions = trim($args['axes_options']);
     if (!empty($axesOptions)) {
         $reportOptions['axesOptions'] = json_decode($axesOptions, true);
     }
     if (isset($args['countColumn']) && $args['countColumn'] != '') {
         $reportOptions['countColumn'] = 'attr_occurrence_' . str_replace(' ', '_', strtolower($args['countColumn']));
         // assume that this is an occurrence attribute.
         $reportOptions['extraParams']['occattrs'] = $args['countColumn'];
     }
     // for a normal user, we can only link to those samples we have created
     $reportOptions['location_list'] = array();
     // for a branch user, we have an allowed list of locations for which we can link to the sample.
     self::$branchLocationList = array();
     if (isset($args['branchManagerPermission']) && $args['branchManagerPermission'] != "" && user_access($args['branchManagerPermission'])) {
         // Get list of locations attached to this user via the branch cms user id attribute
         // first need to scan param_presets for survey_id..
         $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth, 'survey_id' => self::$siteUrlParams[self::$SurveyKey]);
         if (isset($args['locationTypesFilter']) && $args['locationTypesFilter'] != "") {
             $attrArgs['location_type_id'] = self::$siteUrlParams[self::$locationTypeKey]['value'];
         }
         $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
         $cmsAttr = self::extract_attr($locationAttributes, $args['branchFilterAttribute']);
         if (!$cmsAttr) {
             return lang::get('Branch Manager location list lookup: missing Branch allocation attribute') . ' {' . print_r($attrArgs, true) . '} : ' . $args['branchFilterAttribute'];
         }
         $attrListArgs = array('extraParams' => array_merge(array('view' => 'list', 'website_id' => $args['website_id'], 'location_attribute_id' => $cmsAttr['attributeId'], 'raw_value' => $user->uid), $auth), 'table' => 'location_attribute_value');
         $attrList = data_entry_helper::get_population_data($attrListArgs);
         if (isset($attrList['error'])) {
             return $attrList['error'];
         }
         if (count($attrList) > 0) {
             foreach ($attrList as $attr) {
                 self::$branchLocationList[] = $attr['location_id'];
             }
         }
         $reportOptions['location_list'] = self::$branchLocationList;
     }
     // for an admin, we can link to all samples.
     if (isset($args['managerPermission']) && $args['managerPermission'] != "" && user_access($args['managerPermission'])) {
         $reportOptions['location_list'] = 'all';
     }
     if (function_exists('module_exists') && module_exists('easy_login') && function_exists('hostsite_get_user_field')) {
         $reportOptions['my_user_id'] = hostsite_get_user_field('indicia_user_id');
     } else {
         $reportOptions['my_user_id'] = $user->uid;
     }
     $retVal = '';
     // Add controls first: set up a control bar
     $retVal .= "\n<table id=\"controls-table\" class=\"ui-widget ui-widget-content ui-corner-all controls-table\"><thead class=\"ui-widget-header\"><tr>";
     $retVal .= self::date_control($args, $auth, $node, $reportOptions);
     $retVal .= '<th>' . self::user_control($args, $auth, $node, $reportOptions) . '</th>';
     $retVal .= '<th>' . self::location_control($args, $auth, $node, $reportOptions) . '</th>';
     // note this includes the location_type control if needed
     $siteUrlParams = self::get_site_url_params();
     if (!empty($args['removable_params'])) {
         foreach (self::$removableParams as $param => $caption) {
             $checked = isset($_GET[$param]) && $_GET[$param] === 'true' ? ' checked="checked"' : '';
             $retVal .= '<th><input type="checkbox" name="removeParam-' . $param . '" id="removeParam-' . $param . '" class="removableParam"' . $checked . '/>' . '<label for="removeParam-' . $param . '" >' . lang::get($caption) . '</label></th>';
         }
         self::set_up_control_change('removeParam-' . $param, $param, array(), true);
     }
     // are there any params that should be set to blank using one of the removable params tickboxes?
     foreach (self::$removableParams as $param => $caption) {
         if (isset($_GET[$param]) && $_GET[$param] === 'true') {
             $reportOptions['extraParams'][$param] = '';
         }
     }
     if (self::$siteUrlParams[self::$userKey]['value'] == '' && self::$siteUrlParams[self::$locationKey]['value'] == '') {
         $checked = self::$siteUrlParams[self::$cacheKey]['value'] === 'true' ? ' checked="checked"' : '';
         $retVal .= '<th><input type="checkbox" name="cachingParam" id="cachingParam" class="cachingParam"' . $checked . '/>' . '<label for="cachingParam" title="' . lang::get("When fetching the full data set, selcting this improves performance by not going to the warehouse to get the data. Occassionally, even when selected, the data will be refreshed, which will appear to slow down the response.") . '" >' . lang::get("Use cached data") . '</label></th>';
         $reportOptions['caching'] = self::$siteUrlParams[self::$cacheKey]['value'] === 'true' ? true : 'store';
         self::set_up_control_change('cachingParam', self::$cacheKey, array(), true);
         $checked = self::$siteUrlParams[self::$downloadKey]['value'] === 'true' ? ' checked="checked"' : '';
         if (self::$siteUrlParams[self::$downloadKey]['value'] !== 'true' && isset($reportOptions['includeListDownload']) && $reportOptions['includeListDownload'] == true) {
             $reportOptions['includeRawGridDownload'] = false;
             $reportOptions['includeRawListDownload'] = false;
             $reportOptions['includeSummaryGridDownload'] = false;
             $reportOptions['includeEstimatesGridDownload'] = false;
             $reportOptions['includeListDownload'] = false;
             for ($i = 1; $i <= 4; $i++) {
                 unset($args['Download' . $i . 'Caption']);
                 unset($args['download_report_' . $i]);
             }
             data_entry_helper::$javascript .= "jQuery('.downloads-table-label').remove();\n" . "jQuery('#downloads-table thead tr').prepend('<th>" . "<label for=\"downloadParam\" title=\"" . lang::get("When fetching the full data set, unselecting this improves performance by not including the download data in the page. This extra data can lead to a significantly increase in download time.") . "\" >" . lang::get("Include Downloads") . "</label>" . "<input type=\"checkbox\" name=\"downloadParam\" id=\"downloadParam\" class=\"downloadParam\"" . $checked . "/>" . "</th>');\n";
             self::set_up_control_change('downloadParam', self::$downloadKey, array(), true);
         }
     }
     if (self::$siteUrlParams[self::$locationTypeKey]['value'] == '') {
         if (isset($args['locationTypesFilter']) && $args['locationTypesFilter'] != "") {
             $types = explode(',', $args['locationTypesFilter']);
             $terms = self::get_sorted_termlist_terms(array('read' => $auth), 'indicia:location_types', array($types[0]));
             $reportOptions['extraParams']['location_type_id'] = $terms[0]['id'];
         }
     } else {
         $reportOptions['extraParams']['location_type_id'] = self::$siteUrlParams[self::$locationTypeKey]['value'];
     }
     $reportOptions['includeReportTimeStamp'] = isset($args['includeFilenameTimestamps']) && $args['includeFilenameTimestamps'];
     $retVal .= '</tr></thead></table>';
     $reportOptions['highlightEstimates'] = true;
     $retVal .= report_helper::report_calendar_summary($reportOptions);
     // upto this point the report options holds the cms user id as user_id: the report_helper converts this to the indicia
     // user_id if relevant to this installation. We now need to do the same for the report links.
     if (isset($reportOptions['extraParams']['user_id'])) {
         $reportOptions['extraParams']['cms_user_id'] = $reportOptions['extraParams']['user_id'];
         if (function_exists('module_exists') && module_exists('easy_login')) {
             $account = user_load($reportOptions['extraParams']['user_id']);
             if (function_exists('profile_load_profile')) {
                 profile_load_profile($account);
             }
             /* will not be invoked for Drupal7 where the fields are already in the account object */
             if (isset($account->profile_indicia_user_id)) {
                 $reportOptions['extraParams']['user_id'] = $account->profile_indicia_user_id;
             }
         }
     }
     if (isset($args['managerPermission']) && $args['managerPermission'] != "" && user_access($args['managerPermission']) || $reportOptions['extraParams']['location_list'] != '' || $reportOptions['extraParams']['user_id'] != '') {
         // if user specified - either me in normal or branch mode, or a manager
         global $indicia_templates;
         $indicia_templates['report_download_link'] = '<th><a href="{link}"><button type="button">{caption}</button></a></th>';
         // format is assumed to be CSV
         $downloadOptions = array('readAuth' => $auth, 'extraParams' => array_merge($reportOptions['extraParams'], array('date_from' => $reportOptions['date_start'], 'date_to' => $reportOptions['date_end'])), 'itemsPerPage' => false);
         // there are problems dealing with location_list as an array if empty, so connvert
         if ($downloadOptions['extraParams']['location_list'] == "") {
             $downloadOptions['extraParams']['location_list'] = "(-1)";
         } else {
             $downloadOptions['extraParams']['location_list'] = '(' . $downloadOptions['extraParams']['location_list'] . ')';
         }
         for ($i = 1; $i <= 4; $i++) {
             if (isset($args['Download' . $i . 'Caption']) && $args['Download' . $i . 'Caption'] != "" && isset($args['download_report_' . $i]) && $args['download_report_' . $i] != "") {
                 $downloadOptions['caption'] = $args['Download' . $i . 'Caption'];
                 $downloadOptions['dataSource'] = $args['download_report_' . $i];
                 $downloadOptions['filename'] = $reportOptions['downloadFilePrefix'] . preg_replace('/[^A-Za-z0-9]/i', '', $args['Download' . $i . 'Caption']);
                 $downloadOptions['filename'] .= isset($reportOptions['includeReportTimeStamp']) && $reportOptions['includeReportTimeStamp'] ? '_' . date('YmdHis') : '';
                 if (isset($args['download_report_' . $i . '_format'])) {
                     $downloadOptions['format'] = $args['download_report_' . $i . '_format'];
                 }
                 data_entry_helper::$javascript .= "\nif(jQuery('#downloads-table th').length==0)\n  jQuery('#downloads-table thead tr').append('<th class=\"downloads-table-label\">" . lang::get("Downloads") . "</th>');\njQuery('#downloads-table thead tr').append('" . report_helper::report_download_link($downloadOptions) . "');\n";
             }
         }
     }
     return $retVal;
 }
Пример #21
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;
    }
 /**
  * Load the attributes for the sample defined by a supplied Id.
  */
 private static function getAttributesForSample($args, $auth, $id)
 {
     $attrOpts = array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
     if (!empty($id)) {
         $attrOpts['id'] = $id;
     }
     // select only the custom attributes that are for this sample method or all sample methods, if this
     // form is for a specific sample method.
     if (!empty($args['sample_method_id'])) {
         $attrOpts['sample_method_id'] = $args['sample_method_id'];
     }
     $attributes = data_entry_helper::getAttributes($attrOpts, false);
     return $attributes;
 }
 /**
  * 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)
 {
     global $user;
     $checks = self::check_prerequisites();
     $args = self::getArgDefaults($args);
     if ($checks !== true) {
         return $checks;
     }
     iform_load_helpers(array('map_helper'));
     data_entry_helper::add_resource('jquery_form');
     self::$ajaxFormUrl = iform_ajaxproxy_url($node, 'location');
     self::$ajaxFormSampleUrl = iform_ajaxproxy_url($node, 'sample');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $typeTerms = array(empty($args['transect_type_term']) ? 'Transect' : $args['transect_type_term'], empty($args['section_type_term']) ? 'Section' : $args['section_type_term']);
     $settings = array('locationTypes' => helper_base::get_termlist_terms($auth, 'indicia:location_types', $typeTerms), 'locationId' => isset($_GET['id']) ? $_GET['id'] : null, 'canEditBody' => true, 'canEditSections' => true, 'canAllocBranch' => $args['managerPermission'] == "" || user_access($args['managerPermission']), 'canAllocUser' => $args['managerPermission'] == "" || user_access($args['managerPermission']));
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][0]['id'], 'multiValue' => true));
     $settings['section_attributes'] = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][1]['id'], 'multiValue' => true));
     if ($args['allow_user_assignment']) {
         if (false == ($settings['cmsUserAttr'] = extract_cms_user_attr($settings['attributes']))) {
             return 'This form is designed to be used with the CMS User ID attribute setup for locations in the survey, or the "Allow users to be assigned to transects" option unticked.';
         }
         // keep a copy of the cms user ID attribute so we can use it later.
         self::$cmsUserAttrId = $settings['cmsUserAttr']['attributeId'];
     }
     // need to check if branch allocation is active.
     if ($args['branch_assignment_permission'] != '') {
         if (false == ($settings['branchCmsUserAttr'] = self::extract_attr($settings['attributes'], "Branch CMS User ID"))) {
             return '<br />This form is designed to be used with either<br />1) the Branch CMS User ID attribute setup for locations in the survey, or<br />2) the "Permission name for Branch Manager" option left blank.<br />';
         }
         // keep a copy of the branch cms user ID attribute so we can use it later.
         self::$branchCmsUserAttrId = $settings['branchCmsUserAttr']['attributeId'];
     }
     data_entry_helper::$javascript .= "indiciaData.sections = {};\n";
     $settings['sections'] = array();
     $settings['numSectionsAttr'] = "";
     $settings['maxSectionCount'] = $args['maxSectionCount'];
     $settings['autocalcSectionLengthAttrId'] = empty($args['autocalc_section_length_attr_id']) ? 0 : $args['autocalc_section_length_attr_id'];
     $settings['defaultSectionGridRef'] = empty($args['default_section_grid_ref']) ? 'parent' : $args['default_section_grid_ref'];
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
         $settings['walks'] = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'location_id' => $settings['locationId'], 'deleted' => 'f'), 'nocache' => true));
         // Work out permissions for this user: note that canAllocBranch setting effectively shows if a manager.
         if (!$settings['canAllocBranch']) {
             // Check whether I am a normal user and it is allocated to me, and also if I am a branch manager and it is allocated to me.
             $settings['canEditBody'] = false;
             $settings['canEditSections'] = false;
             if ($args['allow_user_assignment'] && count($settings['walks']) == 0 && isset($settings['cmsUserAttr']['default']) && !empty($settings['cmsUserAttr']['default'])) {
                 foreach ($settings['cmsUserAttr']['default'] as $value) {
                     // multi value
                     if ($value['default'] == $user->uid) {
                         // comparing string against int so no triple equals
                         $settings['canEditBody'] = true;
                         $settings['canEditSections'] = true;
                         break;
                     }
                 }
             }
             // If a Branch Manager and not a main manager, then can't edit the number of sections
             if ($args['branch_assignment_permission'] != '' && user_access($args['branch_assignment_permission']) && isset($settings['branchCmsUserAttr']['default']) && !empty($settings['branchCmsUserAttr']['default'])) {
                 foreach ($settings['branchCmsUserAttr']['default'] as $value) {
                     // now multi value
                     if ($value['default'] == $user->uid) {
                         // comparing string against int so no triple equals
                         $settings['canEditBody'] = true;
                         $settings['canAllocUser'] = true;
                         break;
                     }
                 }
             }
         }
         // for an admin user the defaults apply, which will be can do everything.
         // find the number of sections attribute.
         foreach ($settings['attributes'] as $attr) {
             if ($attr['caption'] === 'No. of sections') {
                 $settings['numSectionsAttr'] = $attr['fieldname'];
                 for ($i = 1; $i <= $attr['displayValue']; $i++) {
                     $settings['sections']["S{$i}"] = null;
                 }
                 $existingSectionCount = empty($attr['displayValue']) ? 1 : $attr['displayValue'];
                 data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr['id']) . "').attr('min',{$existingSectionCount}).attr('max'," . $args['maxSectionCount'] . ");\n";
                 if (!$settings['canEditSections']) {
                     data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr['id']) . "').attr('readonly','readonly').css('color','graytext');\n";
                 }
             }
         }
         $sections = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['locationId'], 'deleted' => 'f', 'orderby' => 'id'), 'nocache' => true));
         foreach ($sections as $section) {
             $code = $section['code'];
             data_entry_helper::$javascript .= "indiciaData.sections.{$code} = {'geom':'" . $section['boundary_geom'] . "','id':'" . $section['id'] . "','sref':'" . $section['centroid_sref'] . "','system':'" . $section['centroid_sref_system'] . "'};\n";
             $settings['sections'][$code] = $section;
         }
     } else {
         // not an existing site therefore no walks. On initial save, no section data is created.
         foreach ($settings['attributes'] as $attr) {
             if ($attr['caption'] === 'No. of sections') {
                 $settings['numSectionsAttr'] = $attr['fieldname'];
                 data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr['id']) . "').attr('min',1).attr('max'," . $args['maxSectionCount'] . ");\n";
             }
         }
         $settings['walks'] = array();
     }
     if ($settings['numSectionsAttr'] === '') {
         for ($i = 1; $i <= $settings['maxSectionCount']; $i++) {
             $settings['sections']["S{$i}"] = null;
         }
     }
     $r = '<div id="controls">';
     $headerOptions = array('tabs' => array('#site-details' => lang::get('Site Details')));
     if ($settings['locationId']) {
         $headerOptions['tabs']['#your-route'] = lang::get('Your Route');
         if ($args['always_show_section_details'] || count($settings['section_attributes']) > 0) {
             $headerOptions['tabs']['#section-details'] = lang::get('Section Details');
         }
     }
     if (count($headerOptions['tabs'])) {
         $r .= data_entry_helper::tab_header($headerOptions);
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => 'Tabs', 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
     }
     $r .= self::get_site_tab($auth, $args, $settings);
     if ($settings['locationId']) {
         $r .= self::get_your_route_tab($auth, $args, $settings);
         if ($args['always_show_section_details'] || count($settings['section_attributes']) > 0) {
             $r .= self::get_section_details_tab($auth, $args, $settings);
         }
     }
     $r .= '</div>';
     // controls
     data_entry_helper::enable_validation('input-form');
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l(lang::get('Home'), '<front>');
         $breadcrumb[] = l(lang::get('Sites'), $args['sites_list_path']);
         if ($settings['locationId']) {
             $breadcrumb[] = data_entry_helper::$entity_to_load['location:name'];
         } else {
             $breadcrumb[] = lang::get('New Site');
         }
         drupal_set_breadcrumb($breadcrumb);
     }
     // Inform JS where to post data to for AJAX form saving
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostUrl="' . self::$ajaxFormUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostSampleUrl="' . self::$ajaxFormSampleUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.website_id="' . $args['website_id'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.indiciaSvc = '" . data_entry_helper::$base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.readAuth = {nonce: '" . $auth['read']['nonce'] . "', auth_token: '" . $auth['read']['auth_token'] . "'};\n";
     data_entry_helper::$javascript .= "indiciaData.currentSection = '';\n";
     data_entry_helper::$javascript .= "indiciaData.sectionTypeId = '" . $settings['locationTypes'][1]['id'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.sectionDeleteConfirm = \"" . lang::get('Are you sure you wish to delete section') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.sectionInsertConfirm = \"" . lang::get('Are you sure you wish to insert a new section after section') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.sectionChangeConfirm = \"" . lang::get('Do you wish to save the currently unsaved changes you have made to the Section Details?') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.numSectionsAttrName = \"" . $settings['numSectionsAttr'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.maxSectionCount = \"" . $settings['maxSectionCount'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.autocalcSectionLengthAttrId = " . $settings['autocalcSectionLengthAttrId'] . ";\n";
     data_entry_helper::$javascript .= "indiciaData.defaultSectionGridRef = '" . $settings['defaultSectionGridRef'] . "';\n";
     if ($settings['locationId']) {
         data_entry_helper::$javascript .= "selectSection('S1', true);\n";
     }
     return $r;
 }
 public static function get_occurrences_form($args, $node, $response)
 {
     if (!module_exists('iform_ajaxproxy')) {
         return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     }
     data_entry_helper::add_resource('jquery_form');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // did the parent sample previously exist? Default is no.
     $existing = false;
     if (isset($_POST['sample:id'])) {
         // have just posted an edit to the existing parent sample, so can use it to get the parent location id.
         $parentSampleId = $_POST['sample:id'];
         $parentLocId = $_POST['sample:location_id'];
         $date = $_POST['sample:date'];
         $existing = true;
     } else {
         if (isset($response['outer_id'])) {
             // have just posted a new parent sample, so can use it to get the parent location id.
             $parentSampleId = $response['outer_id'];
         } else {
             $parentSampleId = $_GET['sample_id'];
             $existing = true;
         }
         $sample = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $parentSampleId, 'deleted' => 'f')));
         $sample = $sample[0];
         $parentLocId = $sample['location_id'];
         $date = $sample['date_start'];
     }
     // find any attributes that apply to transect section samples.
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Transect Section'));
     $attributes = data_entry_helper::getAttributes(array('id' => $sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id'], 'multiValue' => false));
     if ($existing) {
         // as the parent sample exists, we need to load the sub-samples and occurrences
         $subSamples = data_entry_helper::get_population_data(array('report' => 'library/samples/samples_list_for_parent_sample', 'extraParams' => $auth['read'] + array('sample_id' => $parentSampleId, 'date_from' => '', 'date_to' => '', 'sample_method_id' => '', 'smpattrs' => implode(',', array_keys($attributes))), 'nocache' => true));
         // transcribe the response array into a couple of forms that are useful elsewhere - one for outputting JSON so the JS knows about
         // the samples, and another for lookup of sample data by code later.
         $subSampleJson = array();
         $subSamplesByCode = array();
         foreach ($subSamples as $subSample) {
             $subSampleJson[] = '"' . $subSample['code'] . '": ' . $subSample['sample_id'];
             $subSamplesByCode[$subSample['code']] = $subSample;
         }
         data_entry_helper::$javascript .= "indiciaData.samples = { " . implode(', ', $subSampleJson) . "};\n";
         $o = data_entry_helper::get_population_data(array('report' => 'library/occurrences/occurrences_list_for_parent_sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'sample_id' => $parentSampleId, 'survey_id' => '', 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => $args['occurrence_attribute_id']), 'nocache' => true));
         // build an array keyed for easy lookup
         $occurrences = array();
         foreach ($o as $occurrence) {
             $occurrences[$occurrence['sample_id'] . ':' . $occurrence['taxa_taxon_list_id']] = array('value' => $occurrence['attr_occurrence_' . $args['occurrence_attribute_id']], 'o_id' => $occurrence['occurrence_id'], 'a_id' => $occurrence['attr_id_occurrence_' . $args['occurrence_attribute_id']]);
         }
         // store it in data for JS to read when populating the grid
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = " . json_encode($occurrences) . ";\n";
     } else {
         data_entry_helper::$javascript .= "indiciaData.samples = {};\n";
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = {};\n";
     }
     $sections = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $parentLocId, 'deleted' => 'f', 'orderby' => 'code')));
     $r = "<form method=\"post\"><div id=\"tabs\">\n";
     $r .= '<input type="hidden" name="sample:id" value="' . $parentSampleId . '" />';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>';
     $r .= '<input type="hidden" name="page" value="grid"/>';
     $r .= data_entry_helper::tab_header(array('tabs' => array('#grid' => lang::get('Enter Transect Data'), '#notes' => lang::get('Notes'))));
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'style' => $args['interface']));
     $r .= "<div id=\"grid\">\n";
     $r .= '<table id="transect-input" class="ui-widget"><thead>';
     $r .= '<tr><th class="ui-widget-header">' . lang::get('Sections') . '</th>';
     foreach ($sections as $section) {
         $r .= '<th class="ui-widget-header">' . $section['code'] . '</th>';
     }
     $r .= '</tr></thead>';
     $r .= '<tbody class="ui-widget-content">';
     // output rows at the top for any transect section level sample attributes
     $rowClass = '';
     foreach ($attributes as $attr) {
         $r .= '<tr ' . $rowClass . '><td>' . $attr['caption'] . '</td>';
         $rowClass = $rowClass == '' ? 'class="alt-row"' : '';
         unset($attr['caption']);
         foreach ($sections as $section) {
             // output a cell with the attribute - tag it with a class & id to make it easy to find from JS.
             $attrOpts = array('class' => 'smp-input smpAttr-' . $section['code'], 'id' => $attr['fieldname'] . ':' . $section['code'], 'extraParams' => $auth['read']);
             // if there is an existing value, set it and also ensure the attribute name reflects the attribute value id.
             if (isset($subSamplesByCode[$section['code']])) {
                 $attrOpts['fieldname'] = $attr['fieldname'] . ':' . $subSamplesByCode[$section['code']]['attr_id_sample_' . $attr['attributeId']];
                 $attr['default'] = $subSamplesByCode[$section['code']]['attr_sample_' . $attr['attributeId']];
             } else {
                 $attr['default'] = isset($_POST[$attr['fieldname']]) ? $_POST[$attr['fieldname']] : '';
             }
             $r .= '<td>' . data_entry_helper::outputAttribute($attr, $attrOpts) . '</td>';
         }
         $r .= '</tr>';
     }
     $r .= '</tbody>';
     $r .= '<tbody class="ui-widget-content" id="occs-body"></tbody>';
     $r .= '</table>';
     $r .= '</div>';
     $r .= "<div id=\"notes\">\n";
     $r .= data_entry_helper::textarea(array('fieldname' => 'sample:comment', 'label' => lang::get('Notes'), 'helpText' => "Use this space to input comments about this week's walk."));
     $r .= '<input type="submit" value="' . lang::get('Save') . '"/>';
     $r .= '</div></div></form>';
     // A stub form for AJAX posting when we need to create an occurrence
     $r .= '<form style="display: none" id="occ-form" method="post" action="' . iform_ajaxproxy_url($node, 'occurrence') . '">';
     $r .= '<input name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input name="occurrence:id" id="occid" />';
     $r .= '<input name="occurrence:taxa_taxon_list_id" id="ttlid" />';
     $r .= '<input name="occurrence:sample_id" id="occ_sampleid"/>';
     $r .= '<input name="occAttr:' . $args['occurrence_attribute_id'] . '" id="occattr"/>';
     $r .= '<input name="transaction_id" id="transaction_id"/>';
     $r .= '</form>';
     // A stub form for AJAX posting when we need to create a sample
     $r .= '<form style="display: none" id="smp-form" method="post" action="' . iform_ajaxproxy_url($node, 'sample') . '">';
     $r .= '<input name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input name="sample:id" id="smpid" />';
     $r .= '<input name="sample:parent_id" value="' . $parentSampleId . '" />';
     $r .= '<input name="sample:survey_id" value="' . $args['survey_id'] . '" />';
     $r .= '<input name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input name="sample:entered_sref" id="smpsref" />';
     $r .= '<input name="sample:entered_sref_system" id="smpsref_system" />';
     $r .= '<input name="sample:location_id" id="smploc" />';
     $r .= '<input name="sample:date" value="' . $date . '" />';
     // include a stub input for each transect section sample attribute
     foreach ($attributes as $attr) {
         $r .= '<input id="' . $attr['fieldname'] . '" />';
     }
     $r .= '</form>';
     // tell the Javascript where to get species from.
     // @todo handle diff species lists.
     data_entry_helper::$javascript .= "indiciaData.initSpeciesList = " . $args['taxon_list_id'] . ";\n";
     // allow js to do AJAX by passing in the information it needs to post forms
     data_entry_helper::$javascript .= "indiciaData.indiciaSvc = '" . data_entry_helper::$base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.readAuth = {nonce: '" . $auth['read']['nonce'] . "', auth_token: '" . $auth['read']['auth_token'] . "'};\n";
     data_entry_helper::$javascript .= "indiciaData.transect = " . $parentLocId . ";\n";
     data_entry_helper::$javascript .= "indiciaData.parentSample = " . $parentSampleId . ";\n";
     data_entry_helper::$javascript .= "indiciaData.sections = " . json_encode($sections) . ";\n";
     data_entry_helper::$javascript .= "indiciaData.occAttrId = " . $args['occurrence_attribute_id'] . ";\n";
     // Do an AJAX population of the grid rows.
     data_entry_helper::$javascript .= "loadSpeciesList();\n";
     data_entry_helper::add_resource('jquery_ui');
     return $r;
 }
Пример #25
0
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args, $node)
 {
     global $user;
     $logged_in = $user->uid > 0;
     $r = '';
     // Get authorisation tokens to update and read from the Warehouse.
     $writeAuth = data_entry_helper::get_auth($args['website_id'], $args['password']);
     $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     $svcUrl = data_entry_helper::$base_url . '/index.php/services';
     $mode = 0;
     // default mode : display survey selector
     // mode 1: display new sample
     // mode 2: display existing sample
     $loadID = null;
     $displayThisOcc = true;
     // when populating from the DB rather than POST we have to be
     // careful with selection object, as geom in wrong format.
     if ($_POST) {
         if (!is_null(data_entry_helper::$entity_to_load)) {
             $mode = 2;
             // errors with new sample, entity poulated with post, so display this data.
         }
         // else valid save, so go back to gridview: default mode 0
     } else {
         if (array_key_exists('sample_id', $_GET)) {
             $mode = 2;
             $loadID = $_GET['sample_id'];
         } else {
             if (array_key_exists('newSample', $_GET)) {
                 $mode = 1;
                 data_entry_helper::$entity_to_load = array();
             }
         }
         // else default to mode 0
     }
     ///////////////////////////////////////////////////////////////////
     // default mode 0 : display survey selector
     ///////////////////////////////////////////////////////////////////
     if ($mode == 0) {
         // Create the Sample list datagrid for this user.
         drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/hasharray.js', 'module');
         drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.datagrid.js', 'module');
         drupal_add_js("jQuery(document).ready(function(){\n  \$('div#smp_grid').indiciaDataGrid('rpt:mnhnl_collab_list_samples', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['location_name', 'entered_sref', 'date', 'num_occurrences', 'completed'],\n    reportColumnTitles: {location_name : '" . lang::get('LANG_Location') . "', entered_sref : '" . lang::get('LANG_Spatial_ref') . "', date : '" . lang::get('LANG_Date') . "', num_occurrences : '" . lang::get('LANG_Num_Occurrences') . "', completed : '" . lang::get('LANG_Completed') . "'},\n    actionColumns: {" . lang::get('LANG_Edit') . " : \"" . url('node/' . $node->nid, array('query' => 'sample_id=�id�')) . "\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : {\n    \t\t\tsurvey_id : '" . $args['survey_id'] . "',\n    \t\t\tuserID_attr_id : '" . $args['uid_attr_id'] . "',\n    \t\t\tuserID : '" . $user->uid . "'\n    \t\t\t\t},\n    itemsPerPage : 12 \n  });\n});\n\n", 'inline');
         $r .= '<div id="sampleList" class="mnhnl-btw-datapanel"><div id="smp_grid"></div>';
         $r .= '<form><input type="button" value="' . lang::get('LANG_Add_Sample') . '" onclick="window.location.href=\'' . url('node/' . $node->nid, array('query' => 'newSample')) . '\'"></form></div>';
         $r .= "</div>\n";
         return $r;
     }
     ///////////////////////////////////////////////////////////////////
     data_entry_helper::$javascript .= "\n// Create vector layers: one to display the location onto, and another for the occurrence list\n// the default edit layer is used for the occurrences themselves\nlocStyleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Green\",\n                    strokeColor: \"Black\",\n                    fillOpacity: 0.3,\n                    strokeWidth: 1\n                  })\n  });\nlocationLayer = new OpenLayers.Layer.Vector(\"" . lang::get("LANG_Location_Layer") . "\",\n                                    {styleMap: locStyleMap});\n";
     if ($loadID) {
         // Can't cache these as data may have just changed
         data_entry_helper::$entity_to_load['occurrence:record_status'] = 'I';
         $url = $svcUrl . '/data/sample/' . $loadID;
         $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
         $session = curl_init($url);
         curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
         $entity = json_decode(curl_exec($session), true);
         // Attributes should be loaded by get_attributes.
         data_entry_helper::$entity_to_load = array();
         foreach ($entity[0] as $key => $value) {
             data_entry_helper::$entity_to_load['sample:' . $key] = $value;
         }
         $url = $svcUrl . '/data/occurrence';
         $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&sample_id=" . $loadID . "&deleted=FALSE";
         $session = curl_init($url);
         curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
         $entities = json_decode(curl_exec($session), true);
         foreach ($entities as $entity) {
             data_entry_helper::$entity_to_load['occurrence:record_status'] = $entity['record_status'];
             data_entry_helper::$entity_to_load['sc:' . $entity['taxa_taxon_list_id'] . ':' . $entity['id'] . ':present'] = true;
         }
         data_entry_helper::$entity_to_load['sample:geom'] = '';
         // value received from db is not WKT, which is assumed by all the code.
         data_entry_helper::$entity_to_load['sample:date'] = data_entry_helper::$entity_to_load['sample:date_start'];
         // bit of a bodge to get around vague dates.
     }
     $defAttrOptions = array('extraParams' => $readAuth);
     //    $r .= "<h1>MODE = ".$mode."</h1>";
     //    $r .= "<h2>readOnly = ".$readOnly."</h2>";
     $r = "<form method=\"post\" id=\"entry_form\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $r .= $writeAuth;
     $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
         $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
     }
     // request automatic JS validation
     data_entry_helper::enable_validation('entry_form');
     $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
     if ($logged_in) {
         // If logged in, output some hidden data about the user
         $uid = $user->uid;
         $email = $user->mail;
         $username = $user->name;
         $uid_attr_id = $args['uid_attr_id'];
         $email_attr_id = $args['email_attr_id'];
         $username_attr_id = $args['username_attr_id'];
         // This assumes that we have the following attributes : no built in error checking.
         $r .= "<input type=\"hidden\" name=\"" . $attributes[$uid_attr_id]['fieldname'] . "\" value=\"{$uid}\" />\n";
         $r .= "<input type=\"hidden\" name=\"" . $attributes[$email_attr_id]['fieldname'] . "\" value=\"{$email}\" />\n";
         $r .= "<input type=\"hidden\" name=\"" . $attributes[$username_attr_id]['fieldname'] . "\" value=\"{$username}\" />\n";
     }
     $r .= "<div id=\"controls\">\n";
     if ($args['interface'] != 'one_page') {
         $r .= "<ul>\n";
         if (!$logged_in) {
             $r .= '  <li><a href="#about_you"><span>' . lang::get('LANG_About_You_Tab') . "</span></a></li>\n";
         }
         $r .= '  <li><a href="#species"><span>' . lang::get('LANG_Species_Tab') . "</span></a></li>\n";
         $r .= '  <li><a href="#place"><span>' . lang::get('LANG_Place_Tab') . "</span></a></li>\n";
         $r .= '  <li><a href="#other"><span>' . lang::get('LANG_Other_Information_Tab') . "</span></a></li>\n";
         $r .= "</ul>\n";
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface']));
     }
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////
     if (!$logged_in) {
         $r .= "<div id=\"about_you\">\n";
         $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('LANG_About_You_Tab_Instructions') . "</p>";
         $defAttrOptions['class'] = 'control-width-4';
         $r .= data_entry_helper::outputAttribute($attributes[$args['first_name_attr_id']], $defAttrOptions);
         $r .= data_entry_helper::outputAttribute($attributes[$args['surname_attr_id']], $defAttrOptions);
         $r .= data_entry_helper::outputAttribute($attributes[$args['email_attr_id']], $defAttrOptions);
         $r .= data_entry_helper::outputAttribute($attributes[$args['phone_attr_id']], $defAttrOptions);
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'first'));
         }
         unset($defAttrOptions['class']);
         $r .= "</div>\n";
     }
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////
     global $indicia_templates;
     $indicia_templates['taxon_label'] = '<div class="biota"><span class="nobreak sci binomial"><em>{taxon}</em></span> {authority}</div>';
     $r .= "<div id=\"species\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('LANG_Species_Tab_Instructions') . "</p>";
     $extraParams = $readAuth + array('taxon_list_id' => $args['list_id']);
     $species_list_args = array('label' => lang::get('occurrence:taxa_taxon_list_id'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 1, 'view' => 'detail', 'parentField' => 'parent_id', 'occAttrs' => explode(',', $args['checklist_attributes']), 'extraParams' => $extraParams, 'survey_id' => $args['survey_id']);
     $r .= data_entry_helper::species_checklist($species_list_args);
     $r .= "<label for=\"sample:comment\">" . lang::get('LANG_Sample_Comment_Label') . "</label><input type=\"text\" id=\"sample:comment\" name=\"sample:comment\" value=\"" . data_entry_helper::$entity_to_load['sample:comment'] . "\" />\n";
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->id == 0 ? 'first' : 'middle'));
     }
     $r .= "</div>\n";
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////
     $r .= "<div id=\"place\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('LANG_Place_Tab_Instructions') . "</p>";
     // Build the array of spatial reference systems into a format Indicia can use.
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= data_entry_helper::sref_and_system(array('label' => lang::get('LANG_SRef_Label'), 'systems' => $systems));
     $location_list_args = array('label' => lang::get('LANG_Location_Label'), 'view' => 'detail', 'extraParams' => array_merge(array('view' => 'detail', 'orderby' => 'name'), $extraParams));
     $r .= call_user_func(array('data_entry_helper', $args['location_ctrl']), $location_list_args);
     $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('LANG_Georef_Label'), 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language']));
     $options = iform_map_get_map_options($args, $readAuth);
     $options['layers'][] = 'locationLayer';
     $olOptions = iform_map_get_ol_options($args);
     $r .= data_entry_helper::map_panel($options, $olOptions);
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls'));
     }
     $r .= "</div>\n";
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////
     $r .= "<div id=\"other\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('LANG_Other_Information_Tab_Instructions') . "</p>";
     $r .= data_entry_helper::date_picker(array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date'));
     $r .= data_entry_helper::outputAttribute($attributes[$args['biotope_attr_id']], $defAttrOptions);
     $r .= data_entry_helper::outputAttribute($attributes[$args['voucher_attr_id']], $defAttrOptions);
     $values = array('I', 'C');
     // not initially doing V=Verified
     $r .= '<label for="occurrence:record_status">' . lang::get('LANG_Record_Status_Label') . '</label><select id="occurrence:record_status" name="occurrence:record_status">';
     foreach ($values as $value) {
         $r .= '<option value="' . $value . '"';
         if (isset(data_entry_helper::$entity_to_load['occurrence:record_status'])) {
             if (data_entry_helper::$entity_to_load['occurrence:record_status'] == $value) {
                 $r .= ' selected="selected"';
             }
         }
         $r .= '>' . lang::get('LANG_Record_Status_' . $value) . '</option>';
     }
     $r .= '</select>';
     //  TODO image upload - not sure how to do this as images are attached to occurrences, and occurrences
     //  are embedded in the species list.
     //    $r .= "<label for='occurrence:image'>".lang::get('LANG_Image_Label')."</label>\n".
     //        data_entry_helper::image_upload('occurrence:image');
     $r .= '<br/><br/>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'last'));
     } else {
         $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save') . "\" />\n";
     }
     $r .= "</div>\n";
     $r .= "</div>\n";
     if (!empty(data_entry_helper::$validation_errors)) {
         $r .= data_entry_helper::dump_remaining_errors();
     }
     $r .= "</form>";
     // may need to keep following code for location change functionality
     data_entry_helper::$onload_javascript .= "\n    \nlocationChange = function(obj){\n\tlocationLayer.destroyFeatures();\n\tif(obj.value != ''){\n\t\tjQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location/\"+obj.value +\n\t\t\t\"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "\" +\n\t\t\t\"&callback=?\", function(data) {\n            if (data.length>0) {\n            \tvar parser = new OpenLayers.Format.WKT();\n            \tfor (var i=0;i<data.length;i++)\n\t\t\t\t{\n\t      \t\t\tif(data[i].centroid_geom){\n\t\t\t\t\t\tfeature = parser.read(data[i].centroid_geom);\n\t\t\t\t\t\tcentre = feature.geometry.getCentroid();\n\t\t\t\t\t\tcentrefeature = new OpenLayers.Feature.Vector(centre, {}, {label: data[i].name});\n\t\t\t\t\t\tlocationLayer.addFeatures([feature, centrefeature]); \n\t\t\t\t\t}\n\t\t\t\t\tif(data[i].boundary_geom){\n\t\t\t\t\t\tfeature = parser.read(data[i].boundary_geom);\n\t\t\t\t\t\tfeature.style = {strokeColor: \"Blue\",\n    \t                \tstrokeWidth: 2,\n  \t\t\t\t\t\t\tlabel: (data[i].centroid_geom ? \"\" : data[i].name)};\n\t\t\t\t\t\tlocationLayer.addFeatures([feature]);\n \t\t\t\t\t}\n    \t\t\t\tlocationLayer.map.zoomToExtent(locationLayer.getDataExtent());\n  \t\t\t\t}\n\t\t\t}\n\t\t});\n  }\n};\njQuery('#imp-location').unbind('change');\njQuery('#imp-location').change(function(){\n\tlocationChange(this);\n});\n// upload location & sref initial values into map.\njQuery('#imp-location').change();\njQuery('#imp-sref').change();\n\n";
     return $r;
 }
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     global $user;
     $logged_in = $user->uid > 0;
     // Get authorisation tokens to update and read from the Warehouse.
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $readAuth = $auth['read'];
     // enable image viewing with FancyBox - only required if the file box is enabled
     //data_entry_helper::$javascript .= "jQuery(\"a.fancybox\").fancybox();\n";
     $r = "\n<form method=\"post\" id=\"entry_form\">\n";
     if (isset($_GET['taxa_taxon_list_id']) || isset($_GET['taxon_external_key'])) {
         if (isset($_GET['taxa_taxon_list_id'])) {
             $filter = array('id' => $_GET['taxa_taxon_list_id']);
         } else {
             $filter = array('external_key' => $_GET['taxon_external_key']);
         }
         $species = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $readAuth + $filter + array('taxon_list_id' => $args['list_id'], 'view' => 'detail', 'preferred' => 't')));
         // we need only one result, but there could be more than one picture, therefore multiple rows
         $uniqueMeaning = false;
         if (count($species) == 1) {
             $uniqueMeaning = $species[0]['taxon_meaning_id'];
         }
         if (count($species) > 1) {
             $uniqueMeaning = $species[0]['taxon_meaning_id'];
             foreach ($species as $item) {
                 if ($item['taxon_meaning_id'] != $uniqueMeaning) {
                     $uniqueMeaning = false;
                 }
             }
         }
         if ($uniqueMeaning) {
             // now we have the meaning_id, we need to fetch the actual species in the chosen common name
             $speciesCommon = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $readAuth + array('taxon_meaning_id' => $uniqueMeaning, 'language_iso' => iform_lang_iso_639_2($user->lang), 'view' => 'detail')));
             $r .= '<div class="ui-widget ui-widget-content ui-corner-all page-notice ui-helper-clearfix">';
             $nameString = ($species[0]['language_iso'] == 'lat' ? '<em>' : '') . $species[0]['taxon'] . ($species[0]['language_iso'] == 'lat' ? '</em>' : '');
             if (count($speciesCommon) >= 1) {
                 // use a common name if we have one
                 $nameString = $speciesCommon[0]['taxon'] . ' (' . $nameString . ')';
             }
             if (!empty($species[0]['description_in_list'])) {
                 $r .= '<div class="page-notice">' . lang::get('you are recording a', $nameString) . '</div>';
             }
             $taxa_taxon_list_id = $species[0]['id'];
             $images_path = data_entry_helper::$base_url . (isset(data_entry_helper::$indicia_upload_path) ? data_entry_helper::$indicia_upload_path : 'upload/');
             foreach ($species as $item) {
                 if (!empty($item['image_path'])) {
                     $r .= '<a class="fancybox left" href="' . $images_path . $item['image_path'] . '" style="margin: 0 1em 1em;">';
                     $r .= '<img width="100" src="' . $images_path . 'thumb-' . $item['image_path'] . '" />';
                     $r .= '</a>';
                 }
             }
             if (!empty($species[0]['description_in_list'])) {
                 $r .= '<p>' . $species[0]['description_in_list'] . "</p>";
             } else {
                 $r .= '<p>' . lang::get('you are recording a', $nameString) . '</p>';
             }
             $r .= "</div>\n";
         } else {
             $r .= "<p>The species not be identified uniquely from the URL parameters.</p>\n";
         }
     }
     // request automatic JS validation
     data_entry_helper::enable_validation('entry_form');
     $r .= "<div id=\"controls\">\n";
     if ($args['interface'] != 'one_page') {
         $r .= "<ul>\n";
         if (!$logged_in) {
             $r .= '  <li><a href="#about_you"><span>' . lang::get('about you') . "</span></a></li>\n";
         }
         if (!isset($taxa_taxon_list_id)) {
             $r .= '  <li><a href="#species"><span>' . lang::get('what did you see') . "</span></a></li>\n";
         }
         $r .= '  <li><a href="#place"><span>' . lang::get('where was it') . "</span></a></li>\n";
         $r .= '  <li><a href="#other"><span>' . lang::get('other information') . "</span></a></li>\n";
         $r .= "</ul>\n";
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface']));
     }
     if ($user->uid == 0) {
         $r .= "<fieldset id=\"about_you\">\n";
         $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('about you tab instructions') . "</p>";
         $r .= data_entry_helper::text_input(array('label' => lang::get('first name'), 'fieldname' => 'smpAttr:' . $args['first_name_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('surname'), 'fieldname' => 'smpAttr:' . $args['surname_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('email'), 'fieldname' => 'smpAttr:' . $args['email_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('phone number'), 'fieldname' => 'smpAttr:' . $args['phone_attr_id'], 'class' => 'control-width-4'));
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'first'));
         }
         $r .= "</fieldset>\n";
     }
     // the species tab is ommitted if the page is called with a taxon in the querystring parameters
     if (isset($taxa_taxon_list_id)) {
         $r .= "<input type=\"hidden\" name=\"occurrence:taxa_taxon_list_id\" value=\"{$taxa_taxon_list_id}\"/>\n";
     } else {
         $r .= "<fieldset id=\"species\">\n";
         $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('species tab instructions') . "</p>";
         $extraParams = $readAuth + array('taxon_list_id' => $args['list_id']);
         if ($args['preferred']) {
             $extraParams += array('preferred' => 't');
         }
         if ($args['restrict_species_to_users_lang']) {
             $extraParams += array('language_iso' => iform_lang_iso_639_2($user->lang));
         }
         $species_list_args = array('label' => lang::get('occurrence:taxa_taxon_list_id'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'view' => 'detail', 'parentField' => 'parent_id', 'extraParams' => $extraParams);
         if ($args['species_ctrl'] == 'tree_browser') {
             // change the node template to include images
             global $indicia_templates;
             $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', $args['species_ctrl']), $species_list_args);
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->id == 0 ? 'first' : 'middle'));
         }
         $r .= "</fieldset>\n";
     }
     $r .= "<fieldset id=\"place\">\n";
     // Output all our hidden data here, because this tab is always present
     $r .= $auth['write'];
     if ($logged_in) {
         // If logged in, output some hidden data about the user
         $r .= iform_user_get_hidden_inputs($args);
     }
     // if the species being recorded is a fixed species defined in the URL, then output a hidden
     if (isset($taxa_taxon_list_id)) {
         $r .= "<input type=\"hidden\" name=\"occurrence:taxa_taxon_list_id'\" value=\"" . $taxa_taxon_list_id . "\" />\n";
     }
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"record_status\" value=\"" . $args['record_status'] . "\" />\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('place tab instructions') . "</p>";
     // Build the array of spatial reference systems into a format Indicia can use.
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= data_entry_helper::georeference_lookup(iform_map_get_georef_options($args, $auth['read']));
     $r .= data_entry_helper::sref_and_system(array('label' => lang::get('sample:entered_sref'), 'systems' => $systems));
     // retrieve options for the IndiciaMapPanel, and optionally options for OpenLayers.
     $options = iform_map_get_map_options($args, $readAuth);
     $options['tabDiv'] = 'place';
     $olOptions = iform_map_get_ol_options($args);
     $options['scroll_wheel_zoom'] = false;
     $r .= data_entry_helper::map_panel($options, $olOptions);
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->id == 0 && isset($taxa_taxon_list_id) ? 'first' : 'middle'));
     }
     $r .= "</fieldset>\n";
     $r .= "<fieldset id=\"other\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('other tab instructions') . "</p>";
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     $r .= data_entry_helper::file_box(array('caption' => 'Upload your photos', 'readAuth' => $readAuth, 'resizeWidth' => 1024, 'resizeHeight' => 768, 'table' => 'occurrence_image', 'tabDiv' => 'other', 'runtimes' => array('html5', 'html4')));
     // Dynamically create a control for the abundance, unless overridden for this species
     if (isset($species) && count($species) > 0 && trim($args['abundance_overrides']) !== '') {
         $overrides = explode("\n", $args['abundance_overrides']);
         foreach ($overrides as $override) {
             $tokens = explode(':', $override);
             if ($tokens[0] == $species[0]['taxon']) {
                 // remove the default abundance attribute behaviour
                 $args['abundance_attr_id'] = '';
                 if (trim($tokens[1]) !== '') {
                     $attrIds = explode(',', $tokens[1]);
                     $attributes = data_entry_helper::getAttributes(array('id' => null, 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => "occAttr", 'extraParams' => $readAuth + array('query' => urlencode(json_encode(array('in' => array('id', $attrIds))))), 'survey_id' => $args['survey_id']));
                     foreach ($attributes as $attribute) {
                         $r .= data_entry_helper::outputAttribute($attribute, array('language' => iform_lang_iso_639_2($user->lang), 'booleanCtrl' => 'checkbox'));
                     }
                 }
             }
         }
     }
     if (!empty($args['abundance_attr_id'])) {
         $abundance_args = array('label' => lang::get('abundance'), 'fieldname' => 'occAttr:' . $args['abundance_attr_id'], 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $readAuth + array('termlist_id' => $args['abundance_termlist_id']), 'size' => 6, 'sep' => '<br/>');
         $r .= call_user_func(array('data_entry_helper', $args['abundance_ctrl']), $abundance_args);
     }
     $r .= data_entry_helper::textarea(array('label' => lang::get('sample:comment'), 'fieldname' => 'sample:comment', 'class' => 'wide'));
     $r .= '<div class="footer">' . data_entry_helper::checkbox(array('label' => lang::get('happy for contact'), 'labelClass' => 'auto', 'fieldname' => 'smpAttr:' . $args['contact_attr_id'])) . '</div>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'last'));
     } else {
         $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     }
     $r .= "</fieldset>\n";
     $r .= "</div>\n";
     $r .= "</form>";
     return $r;
 }
Пример #27
0
 /**
  * Get the block of custom attributes at the species (occurrence) level
  */
 private static function get_control_speciesattributes($auth, $args, $tabalias, $options)
 {
     if (!self::getGridMode($args)) {
         // Add any dynamically generated controls
         $attrArgs = array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
         if (count(self::$occurrenceIds) == 1) {
             // if we have a single occurrence Id to load, use it to get attribute values
             $attrArgs['id'] = self::$occurrenceIds[0];
         }
         $attributes = data_entry_helper::getAttributes($attrArgs);
         $defAttrOptions = array('extraParams' => $auth['read']);
         $r = self::get_attribute_html($attributes, $args, $defAttrOptions);
         if ($args['occurrence_comment']) {
             $r .= data_entry_helper::textarea(array('fieldname' => 'occurrence:comment', 'label' => lang::get('Record Comment')));
         }
         if ($args['occurrence_images']) {
             $opt = array('table' => 'occurrence_image', 'label' => lang::get('Upload your photos'));
         }
         if ($args['interface'] !== 'one_page') {
             $opts['tabDiv'] = $tabalias;
         }
         $r .= data_entry_helper::file_box($opts);
         return $r;
     } else {
         // in grid mode the attributes are embedded in the grid.
         return '';
     }
 }
Пример #28
0
function iform_mnhnl_locationattributes($auth, $args, $tabalias, $options)
{
    $creatorAttr = iform_mnhnl_getAttrID($auth, $args, 'location', 'Creator');
    if ($creatorAttr) {
        data_entry_helper::$javascript .= "\njQuery('[name=locAttr:" . $creatorAttr . "],[name^=locAttr:" . $creatorAttr . ":]').removeClass('wide').attr('readonly','readonly');";
    }
    $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
    //    if($options['read_only']===true) $attrArgs['read_only']='read_only';
    $tabName = isset($options['tabNameFilter']) && isset($options['tabNameFilter']) != '' ? $options['tabNameFilter'] : '';
    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);
    $defAttrOptions = array_merge(array('extraParams' => array_merge($auth['read'], array('view' => 'detail')), 'language' => iform_lang_iso_639_2($args['language'])), $options);
    $r = '';
    foreach ($locationAttributes as $attribute) {
        if ($tabName == '' && $attribute['inner_structure_block'] != "Filter" || strcasecmp($tabName, $attribute['inner_structure_block']) == 0) {
            $opt = $defAttrOptions + get_attr_validation($attribute, $args);
            $r .= data_entry_helper::outputAttribute($attribute, $opt);
        }
    }
    return $r;
}
 /**
  * Return the generated output for the media grid tab.
  * @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 integer $nid The Drupal node object's ID.
  * @param object $auth The full read-write authorisation.
  * @return HTML.
  */
 private static function get_media_tab($args, $nid, $auth)
 {
     global $user;
     data_entry_helper::add_resource('fancybox');
     data_entry_helper::add_resource('plupload');
     data_entry_helper::add_resource('jquery_ui');
     $limit1 = $args['sample_attribute_id_1_limit'];
     $limit2 = $args['sample_attribute_id_2_limit'];
     if (!isset($args['sample_attribute_id_2']) || $args['sample_attribute_id_2'] == "") {
         $limit2 = 1;
         $caption2 = "";
     } else {
         $caption2 = $attributesIdx[$args['sample_attribute_id_2']]['caption'];
     }
     $attributesIdx = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $args['quadrat_level_sample_method_id'], 'multiValue' => false));
     $scd = isset($args['site_caption_differentiator']) && $args['site_caption_differentiator'] != "" ? explode(',', $args['site_caption_differentiator']) : array('1');
     $qcd = isset($args['quadrat_caption_differentiator']) && $args['quadrat_caption_differentiator'] != "" ? explode(',', $args['quadrat_caption_differentiator']) : array('1');
     $bumpf = isset($args['media_tab_bumpf']) && $args['media_tab_bumpf'] != "" ? $args['media_tab_bumpf'] : lang::get('Please use the caption field to indicate whether the image is of a particular ' . (count($qcd) > 1 ? 'aspect of a ' : '') . $attributesIdx[$args['sample_attribute_id_1']]['caption'] . ', or the shore/site.') . ' ' . lang::get('When you start typing you should see a set of appropriate options from which you can choose: this will guide you to enter the correct value and format. Alternative just pressing the down arrow key should give the full list.');
     //    'description'=>'Format is &lt;x&gt;:&lt;n&gt;=&lt;txt&gt;:&lt;n&gt;=&lt;txt&gt;[,&lt;x&gt;:&lt;n&gt;=&lt;txt&gt;:&lt;n&gt;=&lt;txt&gt;] where &lt;x&gt; is the attribute id, &lt;n&gt; is the attribute value, and &lt;txt&gt; is the replacement value to be used in the template.',
     $mappings = isset($args['quadrat_caption_attribute_mapping']) ? explode(',', $args['quadrat_caption_attribute_mapping']) : array();
     $mappingsList = array();
     foreach ($mappings as $mapping) {
         $parts = explode(':', $mapping);
         $map = array();
         for ($i = 1; $i < count($parts); $i++) {
             // skip first
             $map[] = explode('=', $parts[$i]);
         }
         $mappingsList['attr' . $parts[0]] = $map;
     }
     data_entry_helper::$javascript .= "indiciaData.limit1={$limit1};\r\nindiciaData.site_caption_template='" . (isset($args['site_caption_template']) ? $args['site_caption_template'] : 'Site') . "';\r\nindiciaData.site_caption_differentiator=" . json_encode($scd) . ";\r\nindiciaData.limit2={$limit2};\r\nindiciaData.quadrat_caption_template='" . str_replace(array('{caption1}', '{caption2}'), array($attributesIdx[$args['sample_attribute_id_1']]['caption'], $caption2), isset($args['quadrat_caption_template']) ? $args['quadrat_caption_template'] : '{caption1} {N1}') . "';\r\nindiciaData.quadrat_caption_differentiator=" . json_encode($qcd) . ";\r\nindiciaData.quadrat_caption_attribute_mapping=" . json_encode($mappingsList) . ";\r\n";
     $r = '<div id="media">' . '<p class="ui-state-highlight page-notice ui-corner-all">' . $bumpf . '<span style="display:none;">' . 'MEM:' . ini_get('memory_limit') . ' FILE:' . ini_get('upload_max_filesize') . ' POST:' . ini_get('post_max_size') . '</span>' . '<br/>' . lang::get('The maximum number of files you can upload is ') . (count($scd) + count($qcd) * $limit1 * $limit2) . '. The maximum filesize you can upload is 4M - the images will be resized to a maximum of 1500 pixels high or wide, to ensure this is the case.' . '.<p>' . data_entry_helper::file_box(array('table' => 'sample_medium', 'caption' => lang::get('Photos'), 'codeGenerated' => 'all', 'maxFileCount' => count($scd) + count($qcd) * $limit1 * $limit2, 'file_box_uploaded_extra_fieldsTemplate' => '<input type="hidden" name="{idField}" id="{idField}" value="{idValue}" />' . '<input type="hidden" name="{pathField}" id="{pathField}" value="{pathValue}" />' . '<input type="hidden" name="{typeField}" id="{typeField}" value="{typeValue}" />' . '<input type="hidden" name="{typeNameField}" id="{typeNameField}" value="{typeNameValue}" />' . '<input type="hidden" name="{deletedField}" id="{deletedField}" value="{deletedValue}" class="deleted-value" />' . '<input type="hidden" id="{isNewField}" value="{isNewValue}" />' . '<label for="{captionField}">Caption:</label><br/><input type="text" list="captions" maxlength="100" style="width: {imagewidth}px" name="{captionField}" id="{captionField}" value="{captionValue}"/>', 'resizeWidth' => '1500', 'resizeHeight' => '1500')) . (self::$readOnly ? '' : '<br/><input type="submit" value="' . lang::get('Save') . '" title="' . lang::get('Saves any data entered across all the tabs.') . '" />') . '<datalist id="captions"></datalist>' . '</div>';
     $typeTermData = data_entry_helper::get_population_data(array('table' => 'termlists_term', 'extraParams' => $auth['read'] + array('view' => 'cache', 'termlist_title' => 'Media types', 'columns' => 'id,term')));
     $typeTermIdLookup = array();
     foreach ($typeTermData as $record) {
         $typeTermIdLookup[$record['term']] = $record['id'];
     }
     data_entry_helper::$javascript .= "indiciaData.mediaTypeTermIdLookup=" . json_encode($typeTermIdLookup) . ";\n";
     return $r;
 }
 /**
  * Return the Indicia form code
  * @param array $args Input parameters.
  * @param array $node Drupal node object
  * @param array $response Response from Indicia services after posting a verification.
  * @return HTML string
  */
 public static function get_form($args, $node, $response)
 {
     global $user;
     $retVal = '';
     $logged_in = $user->uid > 0;
     if (!$logged_in) {
         return '<p>' . lang::get('Please log in before attempting to use this form.') . '</p>';
     }
     // can't really do this automatically: better to give warning
     if (isset($args['locationTypeFilter'])) {
         return '<p>' . lang::get('Please contact the site administrator. This version of the form uses a different method of specifying the location types.') . '</p>';
     }
     iform_load_helpers(array('report_helper'));
     $auth = report_helper::get_read_auth($args['website_id'], $args['password']);
     if (!self::set_up_survey($args, $auth)) {
         return lang::get('set_up_survey returned false: survey_id missing from presets or location_type definition.');
     }
     $reportOptions = self::get_report_calendar_2_options($args, $auth);
     $reportOptions['id'] = 'calendar-summary-' . $node->nid;
     if (!empty($args['removable_params'])) {
         self::$removableParams = get_options_array_with_user_data($args['removable_params']);
     }
     self::copy_args($args, $reportOptions, array('weekstart', 'weekOneContains', 'weekNumberFilter', 'outputTable', 'outputChart', 'tableHeaders', 'chartLabels', 'disableableSeries', 'chartType', 'rowGroupColumn', 'rowGroupID', 'width', 'height', 'includeChartTotalSeries', 'includeChartItemSeries', 'includeRawData', 'includeSummaryData', 'includeEstimatesData', 'includeRawGridDownload', 'includeSummaryGridDownload', 'includeEstimatesGridDownload', 'sampleFields'));
     if (isset($_GET['outputSeries'])) {
         $reportOptions['outputSeries'] = $_GET['outputSeries'];
     }
     // default is all
     // Advanced Chart options
     $rendererOptions = trim($args['renderer_options']);
     if (!empty($rendererOptions)) {
         $reportOptions['rendererOptions'] = json_decode($rendererOptions, true);
     }
     $axesOptions = trim($args['axes_options']);
     if (!empty($axesOptions)) {
         $reportOptions['axesOptions'] = json_decode($axesOptions, true);
     }
     if (isset($args['countColumn']) && $args['countColumn'] != '') {
         $reportOptions['countColumn'] = 'attr_occurrence_' . str_replace(' ', '_', strtolower($args['countColumn']));
         // assume that this is an occurrence attribute.
         $reportOptions['extraParams']['occattrs'] = $args['countColumn'];
     }
     // for a normal user, we can only link to those samples we have created
     $reportOptions['location_list'] = array();
     // for a branch user, we have an allowed list of locations for which we can link to the sample.
     self::$branchLocationList = array();
     if (isset($args['branch_manager_permission']) && $args['branch_manager_permission'] != "" && user_access($args['branch_manager_permission'])) {
         // Get list of locations attached to this user via the branch cms user id attribute
         // first need to scan param_presets for survey_id..
         $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth, 'survey_id' => self::$siteUrlParams[self::$SurveyKey]);
         if (isset($args['locationTypesFilter']) && $args['locationTypesFilter'] != "") {
             $attrArgs['location_type_id'] = self::$siteUrlParams[self::$locationTypeKey]['value'];
         }
         $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
         $cmsAttr = self::extract_attr($locationAttributes, $args['branchFilterAttribute']);
         if (!$cmsAttr) {
             return lang::get('Branch Manager location list lookup: missing Branch allocation attribute') . ' {' . print_r($attrArgs, true) . '} : ' . $args['branchFilterAttribute'];
         }
         $attrListArgs = array('extraParams' => array_merge(array('view' => 'list', 'website_id' => $args['website_id'], 'location_attribute_id' => $cmsAttr['attributeId'], 'raw_value' => $user->uid), $auth), 'table' => 'location_attribute_value');
         $attrList = data_entry_helper::get_population_data($attrListArgs);
         if (isset($attrList['error'])) {
             return $attrList['error'];
         }
         if (count($attrList) > 0) {
             foreach ($attrList as $attr) {
                 self::$branchLocationList[] = $attr['location_id'];
             }
         }
         $reportOptions['location_list'] = self::$branchLocationList;
     }
     // for an admin, we can link to all samples.
     if (isset($args['manager_permission']) && $args['manager_permission'] != "" && user_access($args['manager_permission'])) {
         $reportOptions['location_list'] = 'all';
     }
     // Add controls first: set up a control bar
     $retVal .= "\n<table id=\"controls-table\" class=\"ui-widget ui-widget-content ui-corner-all controls-table\"><thead class=\"ui-widget-header\"><tr>";
     $retVal .= self::year_control($args, $auth, $node, $reportOptions);
     $retVal .= '<th>' . self::user_control($args, $auth, $node, $reportOptions) . '</th>';
     $retVal .= '<th>' . self::location_control($args, $auth, $node, $reportOptions) . '</th>';
     // note this includes the location_type control if needed
     $siteUrlParams = self::get_site_url_params();
     if (!empty($args['removable_params'])) {
         foreach (self::$removableParams as $param => $caption) {
             $checked = isset($_GET[$param]) && $_GET[$param] === 'true' ? ' checked="checked"' : '';
             $retVal .= '<th><input type="checkbox" name="removeParam-' . $param . '" id="removeParam-' . $param . '" class="removableParam"' . $checked . '/>' . '<label for="removeParam-' . $param . '" >' . lang::get($caption) . '</label></th>';
             if ($checked != '') {
                 $reportOptions['downloadFilePrefix'] .= 'RM' . preg_replace('/[^A-Za-z0-9]/i', '', $param) . '_';
             }
         }
         self::set_up_control_change('removeParam-' . $param, $param, array(), true);
     }
     // are there any params that should be set to blank using one of the removable params tickboxes?
     foreach (self::$removableParams as $param => $caption) {
         if (isset($_GET[$param]) && $_GET[$param] === 'true') {
             $reportOptions[$param] = '';
             $reportOptions['extraParams'][$param] = '';
         }
     }
     if (self::$siteUrlParams[self::$locationTypeKey]['value'] == '') {
         if (isset($args['locationTypesFilter']) && $args['locationTypesFilter'] != "") {
             $types = explode(',', $args['locationTypesFilter']);
             $terms = self::get_sorted_termlist_terms(array('read' => $auth), 'indicia:location_types', array($types[0]));
             $reportOptions['extraParams']['location_type_id'] = $terms[0]['id'];
         }
     } else {
         $reportOptions['extraParams']['location_type_id'] = self::$siteUrlParams[self::$locationTypeKey]['value'];
     }
     if (isset($args['linkURL'])) {
         $reportOptions['linkURL'] = $args['linkURL'] . (isset($siteUrlParams[self::$URLExtensionKey]) ? $siteUrlParams[self::$URLExtensionKey] : '');
         $reportOptions['linkURL'] .= (strpos($reportOptions['linkURL'], '?') !== FALSE ? '&' : '?') . 'sample_id=';
     }
     $reportOptions['includeReportTimeStamp'] = isset($args['includeFilenameTimestamps']) && $args['includeFilenameTimestamps'];
     $retVal .= '</tr></thead></table>';
     $reportOptions['survey_id'] = self::$siteUrlParams[self::$SurveyKey];
     // Sort of assuming that only one location type recorded against per survey.
     $reportOptions['downloads'] = array();
     if (isset($args['manager_permission']) && $args['manager_permission'] != "" && user_access($args['manager_permission']) || $reportOptions['extraParams']['location_list'] != '' || $reportOptions['extraParams']['user_id'] != '') {
         // if user specified - either me in normal or branch mode, or a manager
         for ($i = 1; $i <= 4; $i++) {
             if (isset($args['Download' . $i . 'Caption']) && $args['Download' . $i . 'Caption'] != "" && isset($args['download_report_' . $i]) && $args['download_report_' . $i] != "") {
                 $reportOpts = array('caption' => $args['Download' . $i . 'Caption'], 'dataSource' => $args['download_report_' . $i], 'filename' => $reportOptions['downloadFilePrefix'] . preg_replace('/[^A-Za-z0-9]/i', '', $args['Download' . $i . 'Caption']) . (isset($reportOptions['includeReportTimeStamp']) && $reportOptions['includeReportTimeStamp'] ? '_' . date('YmdHis') : ''));
                 if (isset($args['download_report_' . $i . '_format'])) {
                     $reportOpts['format'] = $args['download_report_' . $i . '_format'];
                 }
                 $reportOptions['downloads'][] = $reportOpts;
             }
         }
     } else {
         $reportOptions['includeRawGridDownload'] = false;
     }
     $retVal .= report_helper::report_calendar_summary2($reportOptions);
     return $retVal;
 }