예제 #1
0
/**
 * List of methods that assist with handling recording groups.
 * @package Client
 * @subpackage PrebuiltForms.
 */
function group_authorise_form($args, $readAuth)
{
    if (!empty($args['limit_to_group_id']) && $args['limit_to_group_id'] !== (empty($_GET['group_id']) ? '' : $_GET['group_id'])) {
        // page owned by a different group, so throw them out
        hostsite_show_message(lang::get('This page is a private recording group page which you cannot access.'), 'alert');
        hostsite_goto_page('<front>');
    }
    if (!empty($_GET['group_id'])) {
        // loading data into a recording group. Are they a member or is the page public?
        // @todo: consider performance - 2 web services hits required to check permissions.
        if (hostsite_get_user_field('indicia_user_id')) {
            $gu = data_entry_helper::get_population_data(array('table' => 'groups_user', 'extraParams' => $readAuth + array('group_id' => $_GET['group_id'], 'user_id' => hostsite_get_user_field('indicia_user_id')), 'nocache' => true));
        } else {
            $gu = array();
        }
        $gp = data_entry_helper::get_population_data(array('table' => 'group_page', 'extraParams' => $readAuth + array('group_id' => $_GET['group_id'], 'path' => drupal_get_path_alias($_GET['q']))));
        if (count($gp) === 0) {
            hostsite_show_message(lang::get('You are trying to access a page which is not available for this group.'), 'alert');
            hostsite_goto_page('<front>');
        } elseif (count($gu) === 0 && $gp[0]['administrator'] !== NULL) {
            // not a group member, so throw them out
            hostsite_show_message(lang::get('You are trying to access a page for a group you do not belong to.'), 'alert');
            hostsite_goto_page('<front>');
        }
    }
}
 protected static function get_form_html($args, $auth, $attributes)
 {
     global $user;
     data_entry_helper::$javascript .= "\n      var sampleCreatedOn;\n      var lockingDate;\n    ";
     //Test if the sample date is less than the locking date, if it is then lock the form.
     if (!empty($_GET['sample_id']) && !empty($args['locking_date']) && !in_array('administrator', $user->roles)) {
         $sampleData = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('id' => $_GET['sample_id'], 'view' => 'detail')));
         //The date also has a time element. However this breaks javascript new date, so just get first part of the date (remove time).
         //(the line below just gets the part of the string before the space).
         $sampleCreatedOn = strtok($sampleData[0]['created_on'], ' ');
         if (!empty($sampleCreatedOn)) {
             data_entry_helper::$javascript .= "\n          sampleCreatedOn = new Date('" . $sampleCreatedOn . "');\n          lockingDate = new Date('" . $args['locking_date'] . "');\n        ";
         }
     }
     //If the date the sample was created is less than the threshold date set by the user, then
     //lock the form (put simply, old data cannot be edited by the user).
     data_entry_helper::$javascript .= "\n      if (sampleCreatedOn&&lockingDate&&sampleCreatedOn<lockingDate) {  \n        \$('[id*=_lock]').remove();\n \$('.remove-row').remove();\n\n        \$('.scImageLink,.scClonableRow').hide();\n        \$('.edit-taxon-name,.remove-row').hide();\n        \$('#disableDiv').find('input, textarea, text, button, select').attr('disabled','disabled');\n      }";
     //remove default validation mode of 'message' as species grid goes spazzy
     data_entry_helper::$validation_mode = array('colour');
     //Div that can be used to disable page when required
     $r = '<div id = "disableDiv">';
     $r .= parent::get_form_html($args, $auth, $attributes);
     $r .= '</div>';
     return $r;
 }
예제 #3
0
 public static function link_to_parent($auth, $args, $tabalias, $options, $path)
 {
     if (empty($_GET['table']) || $_GET['table'] !== 'sample' || empty($_GET['id'])) {
         throw new exception('paths_editor.link_to_parent control needs to be called from a form that saves a sample');
     }
     // construct a query to pull back the parent sample and any existing child samples in one go
     $samples = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('query' => json_encode(array('where' => array('id', $_GET['id']), 'orwhere' => array('parent_id', $_GET['id']))), 'view' => 'detail'), 'caching' => false));
     $childGeoms = array();
     $r = '';
     foreach ($samples as $sample) {
         if ($sample['id'] === $_GET['id']) {
             // found the parent sample. Send to JS so it can be shown on the map
             data_entry_helper::$javascript .= "indiciaData.showParentSampleGeom = '{$sample['geom']}';\n";
             $r = data_entry_helper::hidden_text(array('fieldname' => 'sample:date', 'default' => $sample['date_start']));
         } else {
             // found an already input child sample
             $childGeoms[] = "'{$sample['geom']}'";
         }
     }
     // Output some instructions to the user which will depend on whether we are on the first
     // child sample or not.
     if (!empty($options['outputInstructionsTo'])) {
         $instruct = empty($childGeoms) ? $options['firstInstructions'] : $options['otherInstructions'];
         data_entry_helper::$javascript .= "\$('#{$options['outputInstructionsTo']}').html('{$instruct}');\n";
     }
     $childGeoms = implode(',', $childGeoms);
     data_entry_helper::$javascript .= "indiciaData.showChildSampleGeoms = [{$childGeoms}];\n";
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'sample:parent_id', 'default' => $_GET['id']));
     return $r;
 }
 public static function site_description($auth, $args, $tabalias, $options, $path)
 {
     if (!empty($_GET[$options['urlParameter']])) {
         $locationCommentData = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('id' => $_GET[$options['urlParameter']], 'view' => 'detail')));
         $r = '<div><h2>' . $locationCommentData[0]['name'] . '</h2><p>' . $locationCommentData[0]['comment'] . '</p></div>';
         return $r;
     }
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @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;
 }
예제 #6
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     if (!($user_id = hostsite_get_user_field('indicia_user_id'))) {
         return self::abort('Please ensure that you\'ve filled in your surname on your user profile before joining a group.', $args);
     }
     if (empty($_GET['group_id'])) {
         return self::abort('This form must be called with a group_id in the URL parameters.', $args);
     }
     $r = '';
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $group = data_entry_helper::get_population_data(array('table' => 'group', 'extraParams' => $auth['read'] + array('id' => $_GET['group_id']), 'nocache' => true));
     if (count($group) !== 1) {
         return self::abort('The group you\'ve requested membership of does not exist.', $args);
     }
     iform_load_helpers(array('submission_builder'));
     $group = $group[0];
     // Check for an existing group user record
     $existing = data_entry_helper::get_population_data(array('table' => 'groups_user', 'extraParams' => $auth['read'] + array('group_id' => $_GET['group_id'], 'user_id' => $user_id), 'nocache' => true));
     if (count($existing)) {
         if ($existing[0]['pending'] === 'true') {
             // if a previous request was made and unapproved when the group was request only, but the group is now public, we can approve their existing
             // groups_user record.
             if ($group['joining_method'] === 'P') {
                 $data = array('groups_user:id' => $existing[0]['id'], 'groups_user:pending' => 'f');
                 $wrap = submission_builder::wrap($data, 'groups_user');
                 $r = data_entry_helper::forward_post_to('groups_user', $wrap, $auth['write_tokens']);
                 return self::success($auth, $group, $args);
             } else {
                 return self::abort("You've already got a membership request for {$group['title']} pending approval.", $args);
             }
         } else {
             return self::abort("You're already a member of {$group['title']}.", $args);
         }
     } else {
         $data = array('groups_user:group_id' => $group['id'], 'groups_user:user_id' => $user_id);
         // request only, so make the groups_user record pending approval
         if ($group['joining_method'] === 'R') {
             $data['groups_user:pending'] = 't';
         }
         $wrap = submission_builder::wrap($data, 'groups_user');
         $r = data_entry_helper::forward_post_to('groups_user', $wrap, $auth['write_tokens']);
         if (!isset($r['success'])) {
             return self::abort('An error occurred whilst trying to update your group membership.', $args);
         } elseif ($group['joining_method'] === 'R') {
             return self::abort("Your request to join {$group['title']} is now awaiting approval.", $args);
         } else {
             return self::success($auth, $group, $args);
         }
     }
     return $r;
 }
예제 #7
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     if (empty($_GET['group_id'])) {
         return 'This page needs a group_id URL parameter.';
     }
     global $base_url;
     global $user;
     iform_load_helpers(array('data_entry_helper'));
     data_entry_helper::$javascript .= "indiciaData.nodeId=" . $node->nid . ";\n";
     data_entry_helper::$javascript .= "indiciaData.baseUrl='" . $base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.currentUsername='******';\n";
     //Translations for the comment that goes into occurrence_comments when a record is verified or rejected.
     data_entry_helper::$javascript .= 'indiciaData.verifiedTranslation = "' . lang::get('Verified') . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.rejectedTranslation = "' . lang::get('Rejected') . "\";\n";
     self::$auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     group_authorise_form($args, self::$auth['read']);
     $group = data_entry_helper::get_population_data(array('table' => 'group', 'extraParams' => self::$auth['read'] + array('id' => $_GET['group_id'], 'view' => 'detail')));
     $group = $group[0];
     hostsite_set_page_title("{$group['title']}: {$node->title}");
     $def = json_decode($group['filter_definition'], true);
     $defstring = '';
     // reconstruct this as a string to feed into dynamic report explorer
     foreach ($def as $key => $value) {
         if ($key) {
             $value = is_array($value) ? json_encode($value) : $value;
             $defstring .= "{$key}={$value}\n";
             if ($key === 'indexed_location_id' || $key === 'indexed_location_list' || $key === 'location_id' || $key === 'location_list') {
                 $args['location_boundary_id'] = $value;
             } elseif (($key === 'taxon_group_id' || $key === 'taxon_group_list') && strpos($value, ',') === FALSE) {
                 // if the report is locked to a single taxon group, then we don't need taxonomy columns.
                 $args['skipped_report_columns'] = array('taxon_group', 'taxonomy');
             }
         }
     }
     if (empty($_GET['implicit'])) {
         // no need for a group user filter
         $args['param_presets'] = implode("\n", array($args['param_presets'], $defstring));
     } else {
         // filter to group users - either implicitly, or only if they explicitly submitted to the group
         $prefix = $_GET['implicit'] === 'true' || $_GET['implicit'] === 't' ? 'implicit_' : '';
         // add the group parameters to the preset parameters passed to all reports on this page
         $args['param_presets'] = implode("\n", array($args['param_presets'], $defstring, "{$prefix}group_id=" . $_GET['group_id']));
     }
     $args['param_presets'] .= "\n";
     if (!empty($args['hide_standard_param_filter'])) {
         data_entry_helper::$javascript .= "\$('#standard-params').hide();\n";
     }
     return parent::get_form($args, $node);
 }
예제 #8
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     if (!($user_id = hostsite_get_user_field('indicia_user_id'))) {
         return self::abort('Please ensure that you\'ve filled in your surname on your user profile before leaving a group.', $args);
     }
     if (empty($_GET['group_id'])) {
         return self::abort('This form must be called with a group_id in the URL parameters.', $args);
     }
     $r = '';
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $group = data_entry_helper::get_population_data(array('table' => 'group', 'extraParams' => $auth['read'] + array('id' => $_GET['group_id']), 'nocache' => true));
     if (count($group) !== 1) {
         return self::abort('The group you\'ve requested membership of does not exist.', $args);
     }
     iform_load_helpers(array('submission_builder'));
     $group = $group[0];
     // Check for an existing group user record
     $existing = data_entry_helper::get_population_data(array('table' => 'groups_user', 'extraParams' => $auth['read'] + array('group_id' => $_GET['group_id'], 'user_id' => $user_id), 'nocache' => true));
     if (count($existing) !== 1) {
         return self::abort('You are not a member of this group.', $args);
     }
     if (!empty($_POST['response']) && $_POST['response'] === lang::get('Cancel')) {
         drupal_goto($args['groups_page_path']);
     } elseif (!empty($_POST['response']) && $_POST['response'] === lang::get('Confirm')) {
         $data = array('groups_user:id' => $existing[0]['id'], 'groups_user:group_id' => $group['id'], 'groups_user:user_id' => $user_id, 'deleted' => 't');
         $wrap = submission_builder::wrap($data, 'groups_user');
         $response = data_entry_helper::forward_post_to('groups_user', $wrap, $auth['write_tokens']);
         if (isset($response['success'])) {
             hostsite_show_message("You are no longer participating in {$group['title']}!");
             drupal_goto($args['groups_page_path']);
         } else {
             return self::abort('An error occurred whilst trying to update your group membership.');
         }
     } else {
         // First access of the form. Let's get confirmation
         $reload = data_entry_helper::get_reload_link_parts();
         $reloadpath = $reload['path'] . '?' . data_entry_helper::array_to_query_string($reload['params']);
         $r = '<form action="' . $reloadpath . '" method="POST"><fieldset>';
         $r .= '<legend>' . lang::get('Confirmation') . '</legend>';
         $r .= '<input type="hidden" name="leave" value="1" />';
         $r .= '<p>' . lang::get('Are you sure you want to stop participating in {1}?', $group['title']) . '</p>';
         $r .= '<input type="submit" value="' . lang::get('Confirm') . '" name="response" />';
         $r .= '<input type="submit" value="' . lang::get('Cancel') . '" name="response" />';
         $r .= '</fieldset></form>';
     }
     return $r;
 }
예제 #9
0
 /**
  * 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)
 {
     iform_load_helpers(array('import_helper'));
     $auth = import_helper::get_read_write_auth($args['website_id'], $args['password']);
     group_authorise_form($args, $auth['read']);
     if ($args['model'] == 'url') {
         if (!isset($_GET['type'])) {
             return "This form is configured so that it must be called with a type parameter in the URL";
         }
         $model = $_GET['type'];
     } else {
         $model = $args['model'];
     }
     if (isset($args['presetSettings'])) {
         $presets = get_options_array_with_user_data($args['presetSettings']);
         $presets = array_merge(array('website_id' => $args['website_id'], 'password' => $args['password']), $presets);
     } else {
         $presets = array('website_id' => $args['website_id'], 'password' => $args['password']);
     }
     if (!empty($_GET['group_id'])) {
         // loading data into a recording group.
         $group = data_entry_helper::get_population_data(array('table' => 'group', 'extraParams' => $auth['read'] + array('id' => $_GET['group_id'], 'view' => 'detail')));
         $group = $group[0];
         $presets['sample:group_id'] = $_GET['group_id'];
         hostsite_set_page_title(lang::get('Import data into the {1} group', $group['title']));
         // if a single survey specified for this group, then force the data into the correct survey
         $filterdef = json_decode($group['filter_definition'], true);
         if (!empty($filterdef['survey_list_op']) && $filterdef['survey_list_op'] === 'in' && !empty($filterdef['survey_list'])) {
             $surveys = explode(',', $filterdef['survey_list']);
             if (count($surveys) === 1) {
                 $presets['survey_id'] = $surveys[0];
             }
         }
     }
     try {
         $r = import_helper::importer(array('model' => $model, 'auth' => $auth, 'presetSettings' => $presets));
     } catch (Exception $e) {
         hostsite_show_message($e->getMessage(), 'warning');
         $reload = import_helper::get_reload_link_parts();
         unset($reload['params']['total']);
         unset($reload['params']['uploaded_csv']);
         $reloadpath = $reload['path'] . '?' . import_helper::array_to_query_string($reload['params']);
         $r = "<p>" . lang::get('Would you like to ') . "<a href=\"{$reloadpath}\">" . lang::get('import another file?') . "</a></p>";
     }
     return $r;
 }
예제 #10
0
 public function breadcrumb($auth, $args, $tabalias, $options)
 {
     global $base_url;
     $breadCrumbLocationNamesArray = array();
     //The location ids to display in the breadcrumb are held in the URL if the user
     //is returning from another page.
     $breadCrumbLocationIdsArray = explode(',', $_GET['breadcrumb']);
     $locationRecords = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'], 'nocache' => true));
     //Get the names associated with the ids
     foreach ($breadCrumbLocationIdsArray as $breadCrumbLocationId) {
         foreach ($locationRecords as $locationRecord) {
             if ($locationRecord['id'] === $breadCrumbLocationId) {
                 $breadCrumbLocationNamesArray[] = $locationRecord['name'];
             }
         }
     }
     $r = '';
     //Only display links to homepage if we have links to show
     if (!empty($breadCrumbLocationNamesArray)) {
         $r .= '<label><h4>Links to homepage</h4></label></br>';
         $r .= '<div>';
         $r .= '<ul id="homepage-breadcrumb">';
         //Loop through the links to show
         foreach ($breadCrumbLocationNamesArray as $num => $breadCrumbLocationName) {
             //For each link back to the homepage, we need to give the homepage some locations IDs to rebuild
             //its breadcrumb with. So we need to include ids of any locations that are "above" the location we are linking back with.
             //e.g. If the link is for Guildford, then we would need to supply the ids for Guildford, Surrey and South England
             //as well to the homepage can make a full breadcrumb trail to guildford.
             if (empty($breadCrumbParamToSendBack)) {
                 $breadCrumbParamToSendBack = 'breadcrumb=' . $breadCrumbLocationIdsArray[$num];
             } else {
                 $breadCrumbParamToSendBack .= ',' . $breadCrumbLocationIdsArray[$num];
             }
             $r .= '<li id="breadcrumb-part-"' . $num . '>';
             //The breadcrumb link is a name, with a url back to the homepage containing ids for the homepage
             //to show in its breadcrumb
             $r .= '<a href="' . $base_url . (variable_get('clean_url', 0) ? '' : '?q=') . $options['homepage_path'] . (variable_get('clean_url', 0) ? '?' : '&') . $breadCrumbParamToSendBack . '">' . $breadCrumbLocationName . '<a>';
             $r .= '</li>';
         }
         $r .= '</ul></div>';
     }
     return $r;
 }
예제 #11
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     if (empty($_GET['group_id'])) {
         return 'This page needs a group_id URL parameter.';
     }
     require_once 'includes/map.php';
     require_once 'includes/groups.php';
     global $indicia_templates;
     iform_load_helpers(array('report_helper', 'map_helper'));
     $conn = iform_get_connection_details($node);
     $readAuth = report_helper::get_read_auth($conn['website_id'], $conn['password']);
     report_helper::$javascript .= "indiciaData.website_id={$conn['website_id']};\n";
     report_helper::$javascript .= "indiciaData.nodeId={$node->nid};\n";
     group_authorise_form($args, $readAuth);
     $group = data_entry_helper::get_population_data(array('table' => 'group', 'extraParams' => $readAuth + array('id' => $_GET['group_id'], 'view' => 'detail')));
     $group = $group[0];
     hostsite_set_page_title("{$group['title']}: {$node->title}");
     $actions = array();
     if (!empty($args['edit_location_path'])) {
         $actions[] = array('caption' => 'edit', 'url' => '{rootFolder}' . $args['edit_location_path'], 'urlParams' => array('group_id' => $_GET['group_id'], 'location_id' => '{location_id}'));
     }
     $actions[] = array('caption' => 'remove', 'javascript' => "remove_location_from_group({groups_location_id});");
     $leftcol = report_helper::report_grid(array('readAuth' => $readAuth, 'dataSource' => 'library/locations/locations_for_groups', 'sendOutputToMap' => true, 'extraParams' => array('group_id' => $_GET['group_id']), 'rowId' => 'location_id', 'columns' => array(array('display' => 'Actions', 'actions' => $actions, 'caption' => 'edit', 'url' => '{rootFolder}'))));
     $leftcol .= '<fieldset><legend>' . lang::Get('Add sites to the group') . '</legend>';
     $leftcol .= '<p>' . lang::get('LANG_Add_Sites_Instruct') . '</p>';
     if (!empty($args['edit_location_path'])) {
         $leftcol .= lang::get('Either') . ' <a class="button" href="' . hostsite_get_url($args['edit_location_path'], array('group_id' => $_GET['group_id'])) . '">' . lang::get('enter details of a new site') . '</a><br/>';
     }
     $leftcol .= data_entry_helper::select(array('label' => lang::get('Or, add an existing site'), 'fieldname' => 'add_existing_location_id', 'report' => 'library/locations/locations_available_for_group', 'caching' => false, 'blankText' => lang::get('<please select>'), 'valueField' => 'location_id', 'captionField' => 'name', 'extraParams' => $readAuth + array('group_id' => $_GET['group_id'], 'user_id' => hostsite_get_user_field('indicia_user_id', 0)), 'afterControl' => '<button id="add-existing">Add</button>'));
     $leftcol .= '</fieldset>';
     // @todo Link existing My Site to group. Need a new report to list sites I created, with sites already in the group
     // removed. Show in a drop down with an add button. Adding must create the groups_locations record, plus refresh
     // the grid and refresh the drop down.
     // @todo set destination after saving added site
     $map = map_helper::map_panel(iform_map_get_map_options($args, $readAuth), iform_map_get_ol_options($args));
     $r = str_replace(array('{col-1}', '{col-2}'), array($leftcol, $map), $indicia_templates['two-col-50']);
     data_entry_helper::$javascript .= "indiciaData.group_id={$_GET['group_id']};\n";
     return $r;
 }
예제 #12
0
 /**
  * Return the generated form output.
  * @return Form HTML.
  * @todo: Implement this method
  */
 public static function get_form($args)
 {
     $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     // setup the map options
     $options = iform_map_get_map_options($args, $readAuth);
     $olOptions = iform_map_get_ol_options($args);
     if (array_key_exists('table', $_GET) && $_GET['table'] == 'sample') {
         // Use a cUrl request to get the data from Indicia which contains the value we need to filter against
         // Read the record that was just posted.
         $fetchOpts = array('table' => 'occurrence', 'extraParams' => $readAuth + array('sample_id' => $_GET['id'], 'view' => 'detail'));
         // @todo Error handling on the response
         $occurrence = data_entry_helper::get_population_data($fetchOpts);
     }
     // Add the 3 distribution layers if present. Reverse the order so 1st layer is topmost
     $layerName = self::build_distribution_layer(3, $args, $occurrence);
     if ($layerName) {
         $options['layers'][] = $layerName;
     }
     $layerName = self::build_distribution_layer(2, $args, $occurrence);
     if ($layerName) {
         $options['layers'][] = $layerName;
     }
     $layerName = self::build_distribution_layer(1, $args, $occurrence);
     if ($layerName) {
         $options['layers'][] = $layerName;
     }
     // Now output a grid of the occurrences that were just saved.
     if (isset($occurrence)) {
         $r .= "<table class=\"submission\"><thead><tr><th>Species</th><th>Date</th><th>Spatial Reference</th></tr></thead>\n";
         $r .= "<tbody>\n";
         foreach ($occurrence as $record) {
             $r .= "<tr><td>" . $record['taxon'] . "</td><td>" . $record['date_start'] . "</td><td>" . $record['entered_sref'] . "</td></tr>\n";
         }
         $r .= "</tbody></table>\n";
     }
     $r .= data_entry_helper::map_panel($options, $olOptions);
     return $r;
 }
예제 #13
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     if (empty($_GET['group_id'])) {
         return 'This page needs a group_id URL parameter.';
     }
     self::$auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $group = data_entry_helper::get_population_data(array('table' => 'group', 'extraParams' => self::$auth['read'] + array('id' => $_GET['group_id'])));
     $group = $group[0];
     hostsite_set_page_title($group['title']);
     $filter = data_entry_helper::get_population_data(array('table' => 'filter', 'extraParams' => self::$auth['read'] + array('id' => $group['filter_id'])));
     $filter = $filter[0];
     $def = json_decode($filter['definition'], true);
     $defstring = '';
     // reconstruct this as a string to feed into dynamic report explorer
     foreach ($def as $key => $value) {
         if ($key) {
             $defstring .= "{$key}={$value}\n";
         }
     }
     // add the group parameters to the preset parameters passed to all reports on this page
     $args['param_presets'] = implode("\n", array($args['param_presets'], $defstring, "group_id=" . $_GET['group_id']));
     return parent::get_form($args, $node);
 }
예제 #14
0
 /**
  * Clears moderation notifications for a moderator automatically on visiting the page, so then they
  * will get notified about new incoming records.
  */
 public static function clear_moderation_task_notifications($auth, $args, $tabalias, $options, $path)
 {
     //Using 'submission_list' and 'entries' allows us to specify several top-level submissions to the system
     //i.e. we need to be able to submit several notifications.
     $submission['submission_list']['entries'] = array();
     $submission['id'] = 'notification';
     $notifications = data_entry_helper::get_population_data(array('table' => 'notification', 'extraParams' => $auth['read'] + array('acknowledged' => 'f', 'user_id' => hostsite_get_user_field('indicia_user_id'), 'source_type' => 'PT'), 'nocache' => true));
     if (count($notifications) > 0) {
         $auth = data_entry_helper::get_read_write_auth(variable_get('indicia_website_id', 0), variable_get('indicia_password', ''));
         //Setup the structure we need to submit.
         foreach ($notifications as $notification) {
             $data['id'] = 'notification';
             $data['fields']['id']['value'] = $notification['id'];
             $data['fields']['acknowledged']['value'] = 't';
             $submission['submission_list']['entries'][] = $data;
         }
         //Submit the stucture for processing
         $response = data_entry_helper::forward_post_to('save', $submission, $auth['write_tokens']);
         if (!is_array($response) || !array_key_exists('success', $response)) {
             drupal_set_message(print_r($response, true));
         }
     }
     return '';
 }
 public function informationSheetSurveysReport($auth, $args, $tabalias, $options, $path)
 {
     //The Surveys associated with the Count Unit are held as location_attribute_values so collect these
     $surveysAttributeData = data_entry_helper::get_population_data(array('table' => 'location_attribute_value', 'extraParams' => $auth['read'] + array('location_id' => $_GET['id'], 'location_attribute_id' => $options['surveys_attribute_id']), 'nocache' => true, 'sharing' => $sharing));
     //Create a table to put the data in
     $r = '<div><h3>Surveys</h3><table><tr><th>Name</th><th>Date</th></tr>';
     //Cycle around each Survey associated with the Count Unit and add rows to the grid.
     foreach ($surveysAttributeData as $surveysAttributeDataItem) {
         //The Survey Id and Date are json_encoded in the location_atribute_value so decode.
         $decoded = json_decode($surveysAttributeDataItem['value']);
         //The stored data does not include the Survey name, so we need to collect it.
         $surveysData = data_entry_helper::get_population_data(array('table' => 'survey', 'extraParams' => $auth['read'] + array('id' => $decoded[0]), 'nocache' => true, 'sharing' => $sharing));
         $r .= '<tr><td>';
         $r .= $surveysData[0]['title'];
         $r .= '</td>';
         $r .= '<td>';
         //The second item in the $decoded array holds the date associated with the Survey entry.
         $r .= $decoded[1];
         $r .= '</td>';
         $r .= '</tr>';
     }
     $r .= '</table></div>';
     return $r;
 }
예제 #16
0
/**
 * Returns a list of hidden inputs which are extracted from the form attributes which can be extracted
 * from the user's profile information in Drupal. The attributes which are used are marked as handled
 * so they don't need to be output elsewhere on the form. This function also handles non-profile based 
 * CMS User ID, Username, and Email; and also special processing for names.
 * @param array $attributes List of form attributes.
 * @param array $args List of form arguments. Can include values called:
 *   copyFromProfile - boolean indicating if values should be copied from the profile when the names match
 *   nameShow - boolean, if true then name values should be displayed rather than hidden.
 *     In fact this extends to all profile fields whose names match attribute 
 *     captions. E.g. in D7, field_age would populate an attribute with caption 
 *     age.
 *   emailShow - boolean, if true then email values should be displayed rather than hidden.
 * @param boolean $exists Pass true for an existing record. If the record exists, then the attributes
 *   are marked as handled but are not output to avoid overwriting metadata about the original creator of the record.
 * @param array $readAuth Read authorisation tokens.
 * @return string HTML for the hidden inputs.
 */
function get_user_profile_hidden_inputs(&$attributes, $args, $exists, $readAuth)
{
    // This is Drupal specific code
    global $user;
    $logged_in = $user->uid > 0;
    // If the user is not logged in there is no profile so return early.
    if (!$logged_in) {
        return '';
    }
    $hiddens = '';
    $version6 = substr(VERSION, 0, 1) == '6';
    if ($version6) {
        // In version 6 the profile module holds user setttings.
        // but may not be using profile module, but still need to proceed to handle CMS User ID etc.
        if (function_exists('profile_load_all_profile')) {
            // D6 specific
            profile_load_all_profile($user);
        }
    } else {
        // In version 7, the field module holds user settings.
        $user = user_load($user->uid);
    }
    foreach ($attributes as &$attribute) {
        // Constuct the name of the user property (which varies between versions) to match against the attribute caption.
        $attrPropName = ($version6 ? 'profile_' : 'field_') . strtolower(str_replace(' ', '_', $attribute['caption']));
        if (isset($user->{$attrPropName}) && isset($args['copyFromProfile']) && $args['copyFromProfile'] == true) {
            // Obtain the property value which is stored differently between versions.
            if ($version6) {
                $attrPropValue = $user->{$attrPropName};
            } else {
                $attrPropValues = field_get_items('user', $user, $attrPropName);
                $attrPropValue = isset($attrPropValues[0]['safe value']) ? $attrPropValues[0]['safe value'] : $attrPropValues[0]['value'];
            }
            // lookups need to be translated to the termlist_term_id, unless they are already IDs
            if ($attribute['data_type'] === 'L' && !preg_match('/^[\\d]+$/', $attrPropValue)) {
                $terms = data_entry_helper::get_population_data(array('table' => 'termlists_term', 'extraParams' => $readAuth + array('termlist_id' => $attribute['termlist_id'], 'term' => $attrPropValue)));
                $value = count($terms) > 0 ? $terms[0]['id'] : '';
            } else {
                $value = $attrPropValue;
            }
            if (isset($args['nameShow']) && $args['nameShow'] == true) {
                // Show the attribute with default value.
                $attribute['default'] = $value;
            } else {
                // Hide the attribute value
                $attribute['handled'] = true;
                $attribute['value'] = $value;
            }
        } elseif (strcasecmp($attribute['caption'], 'cms user id') == 0) {
            $attribute['value'] = $user->uid;
            $attribute['handled'] = true;
            // user id attribute is never displayed
        } elseif (strcasecmp($attribute['caption'], 'cms username') == 0) {
            $attribute['value'] = $user->name;
            $attribute['handled'] = true;
            // username attribute is never displayed
        } elseif (strcasecmp($attribute['caption'], 'email') == 0) {
            if (isset($args['emailShow']) && $args['emailShow'] == true) {
                // Show the email attribute with default value.
                $attribute['default'] = $user->mail;
            } else {
                // Hide the email value
                $attribute['value'] = $user->mail;
                $attribute['handled'] = true;
            }
        } elseif (strcasecmp($attribute['caption'], 'first name') == 0 || strcasecmp($attribute['caption'], 'last name') == 0 || strcasecmp($attribute['caption'], 'surname') == 0) {
            // This would be the case where the warehouse is configured to store these
            // values but there are no matching profile fields
            if (!isset($args['nameShow']) || $args['nameShow'] != true) {
                // Name attributes are not displayed because we have the users login.
                $attribute['handled'] = true;
            }
        }
        // If we have a value for one of the user login attributes then we need to
        // output this value. BUT, for existing data we must not overwrite the user
        // who created the record. Note that we don't do this at the beginning of
        // the method as we still wanted to mark the attributes as handled.
        if (isset($attribute['value']) && !$exists) {
            $hiddens .= '<input type="hidden" name="' . $attribute['fieldname'] . '" value="' . $attribute['value'] . '" />' . "\n";
        }
    }
    return $hiddens;
}
 /**
  * Gets a taxon name from a Meaning ID.
  *
  * @param int $meaningId The map layer we are preparing.
  * @param array $readAuth Read authentication.
  * @return The taxon name.
  */
 private static function get_taxon($meaningId, $readAuth)
 {
     global $user;
     $fetchOpts = array('table' => 'taxa_taxon_list', 'extraParams' => $readAuth + array('view' => 'detail', 'language_iso' => iform_lang_iso_639_2(hostsite_get_user_field('language')), 'taxon_meaning_id' => $meaningId));
     $taxonRecords = data_entry_helper::get_population_data($fetchOpts);
     return $taxonRecords[0]['taxon'];
 }
예제 #18
0
 private static function get_comments($readAuth, $includeAddNew = true)
 {
     iform_load_helpers(array('data_entry_helper'));
     $comments = data_entry_helper::get_population_data(array('table' => 'occurrence_comment', 'extraParams' => $readAuth + array('occurrence_id' => $_GET['occurrence_id'], 'sortdir' => 'DESC', 'orderby' => 'updated_on'), 'nocache' => true, 'sharing' => 'verification'));
     $r = '';
     if (count($comments) === 0) {
         $r .= '<p id="no-comments">' . lang::get('No comments have been made.') . '</p>';
     }
     $r .= '<div id="comment-list">';
     foreach ($comments as $comment) {
         $r .= '<div class="comment">';
         $r .= '<div class="header">';
         $r .= '<strong>' . (empty($comment['person_name']) ? $comment['username'] : $comment['person_name']) . '</strong> ';
         $r .= self::ago(strtotime($comment['updated_on']));
         $r .= '</div>';
         $c = str_replace("\n", '<br/>', $comment['comment']);
         $r .= "<div>{$c}</div>";
         $r .= '</div>';
     }
     $r .= '</div>';
     if ($includeAddNew) {
         global $user;
         $r .= '<form><fieldset><legend>' . lang::get('Add new comment') . '</legend>';
         $r .= '<input type="hidden" id="comment-by" value="' . $user->name . '"/>';
         $r .= '<textarea id="comment-text"></textarea><br/>';
         $r .= '<button type="button" class="default-button" onclick="saveComment();">' . lang::get('Save') . '</button>';
         $r .= '</fieldset></form>';
     }
     return $r;
 }
 /**
  * Get the observer control as an autocomplete.
  */
 protected static function get_control_observerautocomplete($auth, $args, $tabAlias, $options)
 {
     global $user;
     //Get the name of the currently logged in user
     $defaultUserData = data_entry_helper::get_report_data(array('dataSource' => 'library/users/get_people_details_for_website_or_user', 'readAuth' => $auth['read'], 'extraParams' => array('user_id' => hostsite_get_user_field('indicia_user_id'), 'website_id' => $args['website_id'])));
     //If we are in edit mode then we need to get the name of the saved observer for the sample
     if (!empty($_GET['sample_id']) && !empty($args['observer_name'])) {
         $existingUserData = data_entry_helper::get_population_data(array('table' => 'sample_attribute_value', 'extraParams' => $auth['read'] + array('sample_id' => $_GET['sample_id'], 'sample_attribute_id' => $args['observer_name'])));
     }
     $observer_list_args = array_merge_recursive(array('extraParams' => array_merge($auth['read'])), $options);
     $observer_list_args['label'] = t('Observer Name');
     $observer_list_args['extraParams']['website_id'] = $args['website_id'];
     $observer_list_args['captionField'] = 'fullname_surname_first';
     $observer_list_args['id'] = 'obSelect:' . $args['observer_name'];
     $observer_list_args['report'] = 'library/users/get_people_details_for_website_or_user';
     //Auto-fill the observer name with the name of the observer of the existing saved sample if it exists,
     //else default to current user name
     if (!empty($existingUserData[0]['value'])) {
         $observer_list_args['defaultCaption'] = $existingUserData[0]['value'];
     } else {
         if (empty($_GET['sample_id'])) {
             $observer_list_args['defaultCaption'] = $defaultUserData[0]['fullname_surname_first'];
         }
     }
     return data_entry_helper::autocomplete($observer_list_args);
 }
 /**
  * Performs the action of accepting an invite.
  * @param array $args Form configuration arguments
  * @param array $invite Invitation record
  * @param array $auth Authorisation tokens
  * @return type 
  */
 private static function accept($args, $invite, $auth)
 {
     // insert a groups_users record
     $values = array('group_id' => $invite['group_id'], 'user_id' => hostsite_get_user_field('indicia_user_id'), 'administrator' => 'f');
     $auth['write_tokens']['persist_auth'] = true;
     $s = submission_builder::build_submission($values, array('model' => 'groups_user'));
     $r = data_entry_helper::forward_post_to('groups_user', $s, $auth['write_tokens']);
     // either a success, or already a member (2004=unique key violation)
     if (!isset($r['success']) && (!isset($r['code']) || $r['code'] !== 2004)) {
         if (function_exists('watchdog')) {
             watchdog('iform', 'An internal error occurred whilst trying to accept an invite: ' . print_r($r, true));
         }
         return self::fail_message('An internal error occurred whilst trying to accept the invite', $args);
     } elseif (isset($r['code']) && $r['code'] === 2004) {
         hostsite_show_message(lang::get('You are already a member of the group!'));
         hostsite_goto_page($args['groups_page_path']);
     } else {
         // delete the invitation
         $values = array('id' => $invite['id'], 'deleted' => 't');
         $s = submission_builder::build_submission($values, array('model' => 'group_invitation'));
         $r = data_entry_helper::forward_post_to('group_invitation', $s, $auth['write_tokens']);
         $group = data_entry_helper::get_population_data(array('table' => 'group', 'extraParams' => $auth['read'] + array('id' => $invite['group_id'])));
         if (!isset($r['success'])) {
             if (function_exists('watchdog')) {
                 watchdog('iform', 'An internal error occurred whilst trying to delete an accepted invite: ' . print_r($r, true));
             }
             // probably no point telling the user, as the invite accept worked OK
         }
         hostsite_goto_page($args['group_home_path'], array('group_id' => $invite['group_id']));
     }
 }
 /**
  * Method called when posting the form. Saves the subscription details to the warehouse.
  * @param $args
  * @param $auth
  * @throws \exception
  */
 private static function subscribe($args, $auth)
 {
     $url = data_entry_helper::$base_url . 'index.php/services/species_alerts/register?';
     $params = array('auth_token' => $auth['write_tokens']['auth_token'], 'nonce' => $auth['write_tokens']['nonce'], 'first_name' => $_POST['first_name'], 'surname' => $_POST['surname'], 'email' => $_POST['email'], 'website_id' => $args['website_id'], 'alert_on_entry' => $_POST['species_alert:alert_on_entry'] ? 't' : 'f', 'alert_on_verify' => $_POST['species_alert:alert_on_verify'] ? 't' : 'f');
     if (!empty($_POST['species_alert:id'])) {
         $params['id'] = $_POST['species_alert:id'];
     }
     if (!empty($_POST['species_alert:taxon_list_id'])) {
         $params['taxon_list_id'] = $_POST['species_alert:taxon_list_id'];
     }
     if (!empty($_POST['species_alert:location_id'])) {
         $params['location_id'] = $_POST['species_alert:location_id'];
     }
     if (!empty($_POST['user_id'])) {
         $params['user_id'] = $_POST['user_id'];
     }
     if (!empty($_POST['taxa_taxon_list_id'])) {
         // We've got a taxa_taxon_list_id in the post data. But, it is better to subscribe via a taxon
         // meaning ID, or even better, the external key.
         $taxon = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $auth['read'] + array('id' => $_POST['taxa_taxon_list_id'], 'view' => 'cache')));
         if (count($taxon) !== 1) {
             throw new exception('Unable to find unique taxon when attempting to subscribe');
         }
         $taxon = $taxon[0];
         if (!empty($taxon['external_key'])) {
             $params['external_key'] = $taxon['external_key'];
         } else {
             $params['taxon_meaning_id'] = $taxon['taxon_meaning_id'];
         }
     } elseif (!empty($_POST['species_alert:external_key'])) {
         $params['external_key'] = $_POST['species_alert:external_key'];
     } elseif (!empty($_POST['species_alert:taxon_meaning_id'])) {
         $params['taxon_meaning_id'] = $_POST['species_alert:taxon_meaning_id'];
     }
     $url .= data_entry_helper::array_to_query_string($params, true);
     $result = data_entry_helper::http_post($url);
     if ($result['result']) {
         hostsite_show_message(lang::get('Your subscription has been saved.'));
     } else {
         hostsite_show_message(lang::get('There was a problem saving your subscription.'));
         if (function_exists('watchdog')) {
             watchdog('iform', 'Species alert error on save: ' . print_r($result, true));
         }
     }
 }
 /**
  * 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;
 }
예제 #23
0
/**
 * Adds a vector to the map for a particular location, and zooms into it.
 */
function iform_map_zoom_to_location($locationId, $readAuth)
{
    $getPopDataOpts = array('table' => 'location', 'extraParams' => $readAuth + array('id' => $locationId, 'view' => 'detail'));
    $response = data_entry_helper::get_population_data($getPopDataOpts);
    $geom = $response[0]['boundary_geom'] ? $response[0]['boundary_geom'] : $response[0]['centroid_geom'];
    iform_map_zoom_to_geom($geom, lang::get('{1} boundary', $response[0]['name']));
}
예제 #24
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;
    }
 /**
  * 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;
 }
 /**
  * Adds the observation data and identifiers (if new) to the submission array from the form values.
  * @param array $sample The sample submission. 
  * @param array $values Associative array of form data values. 
  * @param array $args Associative array of form configuration parameters. 
  * @return array Submission structure with observations/identifiers added.
  */
 private static function add_observation_submissions($sample, $values, $args)
 {
     // get identifier ids for any stored identifiers which match the submitted identifier codes
     $ident_code_keys = preg_grep('/^idn:[0-9]+:[^:]+:identifier:coded_value$/', array_keys($values));
     $codes = array();
     foreach ($ident_code_keys as $ident_code_key) {
         $code = $values[$ident_code_key];
         if ($code !== '') {
             $codes[] = $code;
         }
     }
     $matches = array();
     if (count($codes) > 0) {
         $query = array('in' => array('coded_value', $codes));
         $filter = array('query' => json_encode($query));
         $queryOptions = array('table' => 'identifier', 'extraParams' => self::$auth['read'] + $filter, 'nocache' => true);
         $matches = data_entry_helper::get_population_data($queryOptions);
     }
     // get submission for each observation and add it to the sample submission
     $keys = preg_grep('/^idn:[0-9]+:occurrence:taxa_taxon_list_id$/', array_keys($values));
     foreach ($keys as $key) {
         // build the observation submission
         $key_parts = explode(':', $key);
         $idx = $key_parts[1];
         $so_keys = preg_grep('/^idn:' . $idx . ':(subject_observation|occurrence|occurrence_image|occurrences_subject_observation|occAttr|sjoAttr):/', array_keys($values));
         foreach ($so_keys as $so_key) {
             $so_key_parts = explode(':', $so_key, 3);
             $values[$so_key_parts[2]] = $values[$so_key];
         }
         $so = submission_builder::build_submission($values, array('model' => 'subject_observation'));
         // create submodel for join to occurrence and add it
         $oso = self::build_occurrence_observation_submission($values);
         $so['subModels'][] = array('fkId' => 'subject_observation_id', 'model' => $oso);
         // create submodel for each join to identifier (plus identifier models if new) and add it
         foreach (array('neck-collar', 'colour-left', 'colour-right', 'metal') as $identifier_type) {
             $ident_keys = preg_grep('/^idn:' . $idx . ':' . $identifier_type . ':(identifier|identifiers_subject_observation|idnAttr|isoAttr):/', array_keys($values));
             foreach ($ident_keys as $i_key) {
                 $i_key_parts = explode(':', $i_key, 4);
                 $values[$i_key_parts[3]] = $values[$i_key];
             }
             // if identifier checkbox set, this identifier is being reported. If id > 0, this identifier exists.
             if ($values['identifier:checkbox'] == 1 || $values['identifier:id'] !== '0') {
                 $so = self::build_identifier_observation_submission($values, $matches, $so);
             }
             // clean up the flattened keys
             foreach ($ident_keys as $i_key) {
                 $i_key_parts = explode(':', $i_key, 4);
                 unset($values[$i_key_parts[3]]);
             }
         }
         // clean up the flattened subject_observation keys
         foreach ($so_keys as $so_key) {
             $so_key_parts = explode(':', $so_key, 3);
             unset($values[$so_key_parts[2]]);
         }
         // add it all to the main sample submission
         $sample['subModels'][] = array('fkId' => 'sample_id', 'model' => $so);
     }
     return $sample;
 }
 /**
  * Handles the construction of a submission array from a set of form values.
  * For example, the following represents a submission structure for a simple
  * sample and 1 occurrence submission
  * return data_entry_helper::build_sample_occurrence_submission($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)
 {
     if (!isset($values['page']) || $values['page'] != 'grid') {
         // submitting the first page, with top level sample details
         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.
             $read = array('nonce' => $values['read_nonce'], 'auth_token' => $values['read_auth_token']);
             $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'];
         }
     }
     $submission = submission_builder::build_submission($values, array('model' => 'sample'));
     return $submission;
 }
 /**
  * An ajax handler which returns the surveys that are available for a given sharing type.
  * @param type $website_id
  * @param type $password
  * @param type $node
  */
 public static function ajax_surveys_for_sharing_type($website_id, $password, $node)
 {
     iform_load_helpers(array('data_entry_helper'));
     // @todo filter by the available context filters if appropriate
     $readAuth = array('nonce' => $_GET['nonce'], 'auth_token' => $_GET['auth_token']);
     $surveys = data_entry_helper::get_population_data(array('table' => 'survey', 'extraParams' => $readAuth + array('view' => 'detail', 'orderby' => 'website,title'), 'sharing' => self::expand_sharing_mode($_GET['sharing_type'])));
     $r = array();
     foreach ($surveys as $survey) {
         $r["survey-{$survey['id']}"] = "{$survey['website']} &gt; {$survey['title']}";
     }
     echo json_encode($r);
 }
예제 #29
0
 public static function get_species_checklist_occ_list($options)
 {
     // at this point the data_entry_helper::$entity_to_load has been preloaded with the occurrence data.
     // Get the list of species that are always added to the grid
     if (isset($options['listId']) && !empty($options['listId'])) {
         $taxalist = data_entry_helper::get_population_data($options);
     } else {
         $taxalist = array();
     }
     // copy the options array so we can modify it
     $extraTaxonOptions = array_merge(array(), $options);
     // We don't want to filter the taxa to be added, because if they are in the sample, then they must be included whatever.
     unset($extraTaxonOptions['extraParams']['taxon_list_id']);
     unset($extraTaxonOptions['extraParams']['preferred']);
     unset($extraTaxonOptions['extraParams']['language_iso']);
     // append the taxa to the list to load into the grid
     $fullTaxalist = data_entry_helper::get_population_data($extraTaxonOptions);
     $taxaLoaded = array();
     $occList = array();
     $maxgensequence = 0;
     foreach (data_entry_helper::$entity_to_load as $key => $value) {
         $parts = explode(':', $key, 4);
         // Is this taxon attribute data?
         if (count($parts) > 2 && $parts[0] == 'sc' && $parts[1] != '-ttlId-') {
             if ($parts[2] == '') {
                 $occList['error'] = 'ERROR PROCESSING entity_to_load: found name ' . $key . ' with no sequence/id number in part 2';
             } else {
                 if (!isset($occList[$parts[2]])) {
                     $occ['id'] = $parts[2];
                     $pos = strpos($parts[1], '_');
                     $txID = $pos === false ? $parts[1] : substr($parts[1], 0, $pos);
                     foreach ($fullTaxalist as $taxon) {
                         if ($txID == $taxon['id']) {
                             $occ['taxon'] = $taxon;
                             $taxaLoaded[] = $txID;
                         }
                     }
                     $occList[$parts[2]] = $occ;
                     if (!is_numeric($parts[2])) {
                         $maxgensequence = intval(max(substr($parts[2], 1), $maxgensequence));
                     }
                 }
             }
         }
     }
     if (!isset(data_entry_helper::$entity_to_load['sample:id'])) {
         foreach ($taxalist as $taxon) {
             if (!in_array($taxon['id'], $taxaLoaded)) {
                 $maxgensequence++;
                 $occ['id'] = 'x' . $maxgensequence;
                 $occ['taxon'] = $taxon;
                 $occList[] = $occ;
             }
         }
     }
     return $occList;
 }
 public static function get_occurrences_form($args, $node, $response)
 {
     global $user;
     if (!module_exists('iform_ajaxproxy')) {
         return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     }
     drupal_add_js('misc/tableheader.js');
     // for sticky heading
     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;
     $url = explode('?', $args['my_obs_page'], 2);
     $params = NULL;
     $fragment = NULL;
     // fragment is always at the end.
     if (count($url) > 1) {
         $params = explode('#', $url[1], 2);
         if (count($params) > 1) {
             $fragment = $params[1];
         }
         $params = $params[0];
     } else {
         $url = explode('#', $url[0], 2);
         if (count($url) > 1) {
             $fragment = $url[1];
         }
     }
     $args['my_obs_page'] = url($url[0], array('query' => $params, 'fragment' => $fragment, 'absolute' => TRUE));
     if (isset($_POST['sample:id'])) {
         // have just posted an edit to the existing sample
         $sampleId = $_POST['sample:id'];
         $existing = true;
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
     } else {
         if (isset($response['outer_id'])) {
             // have just posted a new sample.
             $sampleId = $response['outer_id'];
         } else {
             $sampleId = $_GET['sample_id'];
             $existing = true;
         }
     }
     $sample = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $sampleId, 'deleted' => 'f')));
     $sample = $sample[0];
     $date = $sample['date_start'];
     if (!function_exists('module_exists') || !module_exists('easy_login')) {
         // work out the CMS User sample ID.
         $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Field Observation'));
         $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']));
         if (false == ($cmsUserAttr = extract_cms_user_attr($attributes))) {
             return 'Easy Login not active: This form is designed to be used with the CMS User ID attribute setup for samples in the survey.';
         }
     }
     $allTaxonMeaningIdsAtSample = array();
     if ($existing) {
         // Only need to load the occurrences for a pre-existing sample
         $o = data_entry_helper::get_population_data(array('report' => 'reports_for_prebuilt_forms/UKBMS/ukbms_occurrences_list_for_sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'sample_id' => $sampleId, 'survey_id' => $args['survey_id'], 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => $args['occurrence_attribute_ids']), 'nocache' => true));
         // build an array keyed for easy lookup
         $occurrences = array();
         $attrs = explode(',', $args['occurrence_attribute_ids']);
         if (!isset($o['error'])) {
             foreach ($o as $occurrence) {
                 if (!in_array($occurrence['taxon_meaning_id'], $allTaxonMeaningIdsAtSample)) {
                     $allTaxonMeaningIdsAtSample[] = $occurrence['taxon_meaning_id'];
                 }
                 $occurrences[$occurrence['taxon_meaning_id']] = array('ttl_id' => $occurrence['taxa_taxon_list_id'], 'ttl_id' => $occurrence['taxa_taxon_list_id'], 'preferred_ttl_id' => $occurrence['preferred_ttl_id'], 'o_id' => $occurrence['occurrence_id'], 'processed' => false);
                 foreach ($attrs as $attr) {
                     $occurrences[$occurrence['taxon_meaning_id']]['value_' . $attr] = $occurrence['attr_occurrence_' . $attr];
                     $occurrences[$occurrence['taxon_meaning_id']]['a_id_' . $attr] = $occurrence['attr_id_occurrence_' . $attr];
                 }
             }
         }
         // 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.existingOccurrences = {};\n";
     }
     $occ_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'multiValue' => false));
     data_entry_helper::$javascript .= "indiciaData.occurrence_totals = [];\n";
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute = [];\n";
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl = [];\n";
     $defAttrOptions = array('extraParams' => $auth['read'] + array('orderby' => 'id'), 'suffixTemplate' => 'nosuffix');
     $occ_attributes_captions = array();
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $occ_attributes_captions[$idx] = $occ_attributes[$attr]['caption'];
         unset($occ_attributes[$attr]['caption']);
         $ctrl = data_entry_helper::outputAttribute($occ_attributes[$attr], $defAttrOptions);
         data_entry_helper::$javascript .= "indiciaData.occurrence_totals[" . $idx . "] = [];\n";
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute[" . $idx . "] = {$attr};\n";
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl[" . $idx . "] = jQuery('" . str_replace("\n", "", $ctrl) . "');\n";
     }
     //    $r = "<h2>".$location[0]['name']." on ".$date."</h2>\n";
     $r = '<div id="tabs">';
     $tabs = array('#grid1' => t($args['species_tab_1']));
     // tab 1 is required.
     if (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != '') {
         $tabs['#grid2'] = t(isset($args['species_tab_2']) && $args['species_tab_2'] != '' ? $args['species_tab_2'] : 'Species Tab 2');
     }
     if (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != '') {
         $tabs['#grid3'] = t(isset($args['species_tab_3']) && $args['species_tab_3'] != '' ? $args['species_tab_3'] : 'Species Tab 3');
     }
     if (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != '') {
         $tabs['#grid4'] = t(isset($args['species_tab_4']) && $args['species_tab_4'] != '' ? $args['species_tab_4'] : 'Species Tab 4');
     }
     $tabs['#notes'] = lang::get('Notes');
     $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'style' => 'Tabs'));
     // will assume that first table is based on abundance count, so do totals
     $r .= '<div id="grid1"><table id="observation-input1" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
     }
     $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead>';
     $r .= '<tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
     }
     $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     $extraParams = array_merge($auth['read'], array('taxon_list_id' => $args['taxon_list_id_1'], 'preferred' => 't', 'allow_data_entry' => 't', 'view' => 'cache', 'orderby' => 'taxonomic_sort_order'));
     if (!empty($args['taxon_filter_field_1']) && !empty($args['taxon_filter_1'])) {
         $extraParams[$args['taxon_filter_field_1']] = helper_base::explode_lines($args['taxon_filter_1']);
     }
     $taxa = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams));
     data_entry_helper::$javascript .= "indiciaData.speciesList1List = [";
     $first = true;
     foreach ($taxa as $taxon) {
         data_entry_helper::$javascript .= ($first ? "\n" : ",\n") . "{'id':" . $taxon['id'] . ",'taxon_meaning_id':" . $taxon['taxon_meaning_id'] . ",'preferred_language_iso':'" . $taxon["preferred_language_iso"] . "','default_common_name':'" . str_replace("'", "\\'", $taxon["default_common_name"]) . "'}";
         $first = false;
     }
     data_entry_helper::$javascript .= "];\n";
     data_entry_helper::$javascript .= "indiciaData.allTaxonMeaningIdsAtSample = [" . implode(',', $allTaxonMeaningIdsAtSample) . "];\n";
     if (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != '') {
         $r .= '<div id="grid2"><p id="grid2-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input2" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != '') {
         $r .= '<div id="grid3"><p id="grid3-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input3" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != '') {
         $r .= '<div id="grid4"><p id="grid4-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input4" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table>';
         $r .= '<label for="taxonLookupControl4" class="auto-width">' . lang::get('Add species to list') . ':</label> <input id="taxonLookupControl4" name="taxonLookupControl4" >';
         $r .= '<br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     // for the comment form, we want to ensure that if there is a timeout error that it reloads the
     // data as stored in the DB.
     $reload = data_entry_helper::get_reload_link_parts();
     $reload['params']['sample_id'] = $parentSampleId;
     unset($reload['params']['new']);
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         // decode params prior to encoding to prevent double encoding.
         foreach ($reload['params'] as $key => $param) {
             $reload['params'][$key] = urldecode($param);
         }
         $reloadPath .= '?' . http_build_query($reload['params']);
     }
     // fragment is always at the end. discard this.
     $reloadPath = explode('#', $reloadPath, 2);
     $reloadPath = $reloadPath[0];
     $r .= "<div id=\"notes\"><form method=\"post\" id=\"notes_form\" action=\"" . $reloadPath . "#notes\">\n";
     $r .= $auth['write'];
     $r .= '<input type="hidden" name="sample:id" value="' . $sampleId . '" />' . '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>' . '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>' . '<input type="hidden" name="page" value="notes"/>';
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('When using this page, please remember that the data is not saved to the database as you go (which is the case for the previous tabs). In order to save the data entered in this page you must click on the Submit button at the bottom of the page.') . '</p>';
     $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('Submit') . '" id="save-button"/></form>';
     $r .= '<br /><a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Finish') . '</a></div></div>';
     // enable validation on the comments form in order to include the simplified ajax queuing for the autocomplete.
     data_entry_helper::enable_validation('notes_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" value="' . $sampleId . '"/>';
     $r .= '<input name="occAttr:" id="occattr"/>';
     $r .= '<input name="transaction_id" id="transaction_id"/>';
     $r .= '<input name="user_id" value="' . hostsite_get_user_field('user_id', 1) . '"/>';
     $r .= '</form>';
     // tell the Javascript where to get species from.
     data_entry_helper::add_resource('jquery_ui');
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     data_entry_helper::$javascript .= "indiciaData.speciesList1 = " . $args['taxon_list_id_1'] . ";\n";
     if (!empty($args['taxon_filter_field_1']) && !empty($args['taxon_filter_1'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterField = '" . $args['taxon_filter_field_1'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_1']);
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterValues = '" . json_encode($filterLines) . "';\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList2 = " . (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != "" ? $args['taxon_list_id_2'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_2']) && !empty($args['taxon_filter_2'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterField = '" . $args['taxon_filter_field_2'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_2']);
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList3 = " . (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != "" ? $args['taxon_list_id_3'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_3']) && !empty($args['taxon_filter_3'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterField = '" . $args['taxon_filter_field_3'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_3']);
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList4 = " . (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != "" ? $args['taxon_list_id_4'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_4']) && !empty($args['taxon_filter_4'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterField = '" . $args['taxon_filter_field_4'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_4']);
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterValues = " . json_encode($filterLines) . ";\n";
     }
     // allow js to do AJAX by passing in the information it needs to post forms
     data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"taxonLookupControl4\",\"table#observation-input4\",\"" . data_entry_helper::$base_url . "index.php/services/data\", indiciaData.speciesList4,\n  indiciaData.speciesList4FilterField, indiciaData.speciesList4FilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"},\n  \"" . lang::get('LANG_Duplicate_Taxon') . "\", 25, 4);\n\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.sample = " . $sampleId . ";\n";
     if (function_exists('module_exists') && module_exists('easy_login')) {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = true;\n";
         $userId = hostsite_get_user_field('indicia_user_id');
         if (!empty($userId)) {
             data_entry_helper::$javascript .= "indiciaData.UserID = " . $userId . ";\n";
         } else {
             return '<p>Easy Login active but could not identify user</p>';
         }
         // something is wrong
     } else {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = false;\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserAttrID = " . $cmsUserAttr['attributeId'] . ";\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserID = " . $user->uid . ";\n";
     }
     // Do an AJAX population of the grid rows.
     data_entry_helper::$javascript .= "loadSpeciesList();\njQuery('#tabs').bind('tabsshow', function(event, ui) {\n    var target = ui.panel;\n    // first get rid of any previous tables\n    jQuery('table.sticky-header').remove();\n    jQuery('table.sticky-enabled thead.tableHeader-processed').removeClass('tableHeader-processed');\n    jQuery('table.sticky-enabled.tableheader-processed').removeClass('tableheader-processed');\n    jQuery('table.species-grid.sticky-enabled').removeClass('sticky-enabled');\n    var table = jQuery('#'+target.id+' table.species-grid');\n    if(table.length > 0) {\n        table.addClass('sticky-enabled');\n        if(typeof Drupal.behaviors.tableHeader == 'object') // Drupal 7\n          Drupal.behaviors.tableHeader.attach(table.parent());\n        else // Drupal6 : it is a function\n          Drupal.behaviors.tableHeader(target);\n    }\n    // remove any hanging autocomplete select list.\n    jQuery('.ac_results').hide();\n});";
     return $r;
 }