/** * Executes getautocomplete action. * returns a bit of html and JS to perform autocomplete */ public function executeGetautocomplete() { sfLoader::loadHelpers(array('MyForm')); // retrieve module name on which to perform autocomplete if ($this->hasRequestParameter('module_id')) { $module_id = $this->getRequestParameter('module_id'); $modules = sfConfig::get('app_modules_list'); $module_name = $modules[$module_id]; } elseif ($this->hasRequestParameter('module_name')) { $module_name = $this->getRequestParameter('module_name'); } else { return $this->renderText(''); } $field_prefix = $this->getRequestParameter('field_prefix', ''); $extra_params = $this->getRequestParameter('extra_params'); sfLoader::loadHelpers(array('AutoComplete')); if ($module_name == 'users' && $this->getModuleName() == 'images' && !$this->getUser()->hasCredential('moderator')) { $user = $this->getUser(); $out = input_hidden_tag('document_id', $user->getId(), array('id' => $field_prefix . '_document_id')) . input_hidden_tag('document_module', $module_name, array('id' => $field_prefix . '_document_module')) . $user->getUsername() . ' ' . c2c_submit_tag(__('Link'), array('class' => 'samesize', 'picto' => 'action_create')); } else { if ($module_name != 'routes') { $display_button = $this->getRequestParameter('button') != '0'; $out = input_hidden_tag('document_id', '0', array('id' => $field_prefix . '_document_id')) . input_hidden_tag('document_module', $module_name, array('id' => $field_prefix . '_document_module')) . c2c_auto_complete($module_name, $field_prefix . '_document_id', array('field_prefix' => $field_prefix, 'display_button' => $display_button, 'extra_params' => $extra_params)) . ($display_button ? '</form>' : ''); } else { $summit_id = $field_prefix . '_summit_id'; $div_select = $field_prefix . '_routes_select'; $updated_failure = sfConfig::get('app_ajax_feedback_div_name_failure'); $id = $field_prefix . '_rsummits_name'; $out = input_hidden_tag('document_module', $module_name, array('id' => $field_prefix . '_document_module')) . __('Summit : ') . input_tag('summits_name', '', array('size' => 45, 'id' => $id, 'data-suggest-no-exclude' => 1)) . '<div id="' . $field_prefix . '_associated_routes" name="associated_routes" style="display:none;">' . '<div id="' . $div_select . '" name="' . $div_select . '"></div>' . javascript_queue("var indicator = \$('#indicator');" . "\$('#{$id}').c2cAutocomplete({" . "url: '" . url_for("summits/autocomplete") . "'," . "minChars: " . sfConfig::get('app_autocomplete_min_chars') . (isset($extra_params) ? ", params: '{$extra_params}'" : '') . "}).on('itemselect', function(e, item) {" . "indicator.show();" . "\$.get('" . url_for('summits/getroutes') . "'," . "'summit_id=' + item.id + '&div_prefix={$field_prefix}_&div_name=document_id')" . ".always(function() { indicator.hide(); })" . ".fail(function(data) { C2C.showFailure(data.responseText); })" . ".done(function(data) {" . "\$('#{$div_select}').html(data).parent().show();" . "C2C.getWizardRouteRatings('{$field_prefix}_document_id');" . "});" . "});"); if ($this->getRequestParameter('button') != '0') { $out .= c2c_submit_tag(__('Link'), array('class' => 'samesize', 'picto' => 'action_create')); } $out .= '</div>'; } } return $this->renderText($out); }
/** * Create a form that allow to link the current document with several kinds of other docs * * @param module current document module * @param id current document id * @param modules_list list of modules available for association * @param default_selected default selected module in the dropdown list * @param field_prefix used to prevent to have ids conflict when multiple forms * @param $options * $hide if true, display button to hide/show the form + some text * $indicator, the ID of the HTML object used to display indications on the ajax status (Loading, Success, ...) * $removed_id, the ID of the HTML object to hide * $suggest_near_docs, for suggesting docs based on geolocalization * $suggest_friends, for suggesting people you go out with most * * FIXME js code is quite messy, would be great to move most of it into separate js file */ function c2c_form_add_multi_module($module, $id, $modules_list, $default_selected, $options) { // optional values $field_prefix = _option($options, 'field_prefix', 'list_associated_docs'); $hide = _option($options, 'hide', true); $indicator = _option($options, 'indicator', 'indicator'); $removed_id = _option($options, 'removed_id'); $suggest_near_docs = _option($options, 'suggest_near_docs', false); $suggest_friends = _option($options, 'suggest_friends', false); $conf = sfConfig::get('app_modules_list'); $modules_list = array_intersect($conf, $modules_list); $modules_list_i18n = array_map('__', $modules_list); // modules for which lookig for neighboors has some sense $near_docs_modules_list = array_intersect($conf, array('huts', 'parkings', 'sites', 'summits', 'routes')); $near_docs_module_ids_list = array_keys($near_docs_modules_list); // for site-site, parking-parking or summit-summit associations, be explicit about association direction if (in_array($module, array('sites', 'parkings', 'summits'))) { $modules_list_i18n[array_search($module, $modules_list)] = __('sub-' . $module); } // dropdown for choosing the type of docs to link $select_modules = select_tag('dropdown_modules', options_with_classes_for_select($modules_list_i18n, array($default_selected), array(), 'picto picto_'), array('class' => 'picto picto_' . $default_selected)); $picto_add = $hide ? '' : picto_tag('picto_add', in_array('users', $modules_list) ? __('Link an existing user or document') : __('Link an existing document')) . ' '; $out = $picto_add . $select_modules; // js code fro autocompletion $js = "\$('#dropdown_modules').change(function() {" . "var \$this = \$(this), value = \$this.val(), indicator = \$('#{$indicator}').show();" . "\$this.attr('class', 'picto picto_' + value);" . "\$.get('" . url_for("/{$module}/getautocomplete") . "', 'module_id=' + value + '&field_prefix={$field_prefix}" . ($suggest_near_docs ? "' + (['" . implode("','", $near_docs_module_ids_list) . "'].indexOf(value) > -1 ?\n '&extra_params=" . urlencode("lat=" . $suggest_near_docs['lat'] . "&lon=" . $suggest_near_docs['lon']) . "' : '')" : '\'') . ")" . ".always(function() { indicator.hide(); })" . ".done(function(data) { \$('#{$field_prefix}_form').html(data);"; if ($suggest_near_docs || $suggest_friends) { $suggest_exclude = _option($options, 'suggest_exclude', []); // additional code for suggesting documents in the neighborhood or friends when relevant $js = "function getSuggestions() {" . "var input = \$('#{$field_prefix}_form').find('input[autocomplete=off]')," . "module = input.attr('name').replace('_name', '')," . "exclude = " . json_encode($suggest_exclude) . "," . "suggestions_div = \$('.autocomplete-suggestions').empty();" . "if (['" . implode("','", $near_docs_modules_list) . "'].indexOf(module) > -1 || module == 'users') {" . "var params = (module == 'users') ? { id: \$('#name_to_use').attr('data-user-id') } :" . "{ lat:" . $suggest_near_docs['lat'] . ", lon:" . $suggest_near_docs['lon'] . " };" . "if (input.not('[data-suggest-no-exclude]') && exclude[module] && exclude[module].length) {" . "params['exclude'] = exclude[module].join(',');" . "}" . "\$.getJSON('/'+module+'/suggest', params)" . ".done(function(data) {" . "if (data.length) suggestions_div.append('" . __('Suggestions: ') . "');" . "\$.each(data, function(index, obj) {" . "suggestions_div.append(\$('<a href=\"'+obj.url+'\">'+obj.name+'</a>').click(function(e) {" . "if (e.which !== 1) return;" . "e.preventDefault();" . "\$('#{$field_prefix}_form input[type=text]').triggerHandler('forceselect.autocomplete'," . "\$('<span id='+obj.id+'>'+obj.name+'</span>'));" . "}), ' ');" . "});" . "});" . "}" . "}" . "\$('#{$field_prefix}_form_association a').one('click', getSuggestions);" . $js; $js .= "getSuggestions();"; } $js .= "});});"; $out .= javascript_queue($js); // form start $out .= c2c_form_remote_add_element("{$module}/addAssociation?main_id={$id}", $field_prefix, $indicator, $removed_id); // default form content $auto_complete_options = array('field_prefix' => $field_prefix); if ($suggest_near_docs && in_array($modules_list[$default_selected], $near_docs_modules_list)) { $auto_complete_options['extra_params'] = "lat=" . $suggest_near_docs['lat'] . "&lon=" . $suggest_near_docs['lon']; } $out .= '<div id="' . $field_prefix . '_form' . '" class="ac_form">' . input_hidden_tag('document_id', '0', array('id' => $field_prefix . '_document_id')) . input_hidden_tag('document_module', $modules_list[$default_selected], array('id' => $field_prefix . '_document_module')) . c2c_auto_complete($modules_list[$default_selected], $field_prefix . '_document_id', $auto_complete_options) . '</div></form><div class="autocomplete-suggestions"></div>'; // this is where the linked docs will be displayed after ajax $out = '<div class="doc_add">' . $out . '</div>'; if ($hide) { $picto_add_rm = '<span class="assoc_img picto_add" title="' . __('show form') . '"></span>' . '<span class="assoc_img picto_rm" title="' . __('hide form') . '"></span>'; $picto_add_rm = link_to_function($picto_add_rm, "C2C.toggleForm('{$field_prefix}_form')"); $title = '<div id="_association_tool" class="section_subtitle extra" data-tooltip>' . (in_array('users', $modules_list) ? __('Link an existing user or document') : __('Link an existing document')) . __(' :') . '</div> '; $pictos = ' '; foreach ($modules_list as $module) { $pictos .= picto_tag('picto_' . $module, __($module)); } $pictos = link_to_function($pictos, "C2C.toggleForm('{$field_prefix}_form')"); $pictos = '<div class="short_data">' . $pictos . '</div>'; $out = '<div class="one_kind_association empty_content">' . '<div class="association_tool hide" id="' . $field_prefix . '_form_association">' . $picto_add_rm . $title . $pictos . '<ul id="' . $field_prefix . '"><li style="display:none"></li></ul>' . $out . '</div></div>'; } return $out; }