/**
 * 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>'));" . "}), ' &nbsp;');" . "});" . "});" . "}" . "}" . "\$('#{$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')) . __('&nbsp;:') . '</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;
}
Example #2
0
/**
 * This function is similar to option_for_select from symfony, except that it allows you
 * to specify a class for the options (which is class_prefix+value)
 */
function options_with_classes_for_select($options = array(), $selected = '', $html_options = array(), $class_prefix = '')
{
    $html_options = _parse_attributes($html_options);
    if (is_array($selected)) {
        $selected = array_map('strval', array_values($selected));
    }
    $html = '';
    if ($value = _get_option($html_options, 'include_custom')) {
        $html .= content_tag('option', $value, array('value' => '')) . "\n";
    } else {
        if (_get_option($html_options, 'include_blank')) {
            $html .= content_tag('option', '', array('value' => '')) . "\n";
        }
    }
    foreach ($options as $key => $value) {
        if (is_array($value)) {
            $html .= content_tag('optgroup', options_with_classes_for_select($value, $selected, $html_options), array('label' => $key), $class_prefix) . "\n";
        } else {
            $option_options = array('value' => $key);
            if (!empty($class_prefix)) {
                $tmp = explode('/', $key, 2);
                $suffix = $tmp[0];
                $option_options['class'] = $class_prefix . $suffix;
            }
            if (is_array($selected) && in_array(strval($key), $selected, true) || !is_array($selected) && strval($key) == strval($selected)) {
                $option_options['selected'] = 'selected';
            }
            $html .= content_tag('option', $value, $option_options) . "\n";
        }
    }
    return $html;
}