Bee-Lab / BeelabTagBundle

🏷 A simple implementation of tags for Symfony and Doctrine ORM
GNU Lesser General Public License v3.0
46 stars 19 forks source link

Js example uses old select2 version #4

Closed Filoz closed 8 years ago

Filoz commented 8 years ago

Hi, In the js example the provided javascript code refers to 3.5 version of select2. Now select2 has deprecated many methods in 4.0: https://select2.github.io/announcements-4.0.html#hidden-input https://select2.github.io/announcements-4.0.html#removed-initselection

Also the form type refers to symfony 2; In symfony 3 setDefaultOptionsis removed in favor of configureOptions

garak commented 8 years ago

Hi Filoz, thanks for reporting the issue. I improved the example with more up-to-date code. About Select2: I can't just switch to newest version without changing much of the code, since 4.0 is using a select and this is not so obvious in Symfony. If you get a working example with Select2 4.0, feel free to propose a Pull Request

Filoz commented 8 years ago

Hi @garak ! thank you for your reply; Yes, you are absolutely right! the problems is using only a select without a text (hidden) type...

I found a solution... the code is ugly, I have to rewrite it, but it's a start. (it seems to works) I simply create a select field from an input text field and then I attach a "change" event to update the text field Every suggest is welcome!

        $(document).ready(function () {
            (function () {

                function formatRepo (repo) {
                    if (repo.loading) return repo.text;

                    var markup = "<div class='select2-result-repository clearfix'>" +
                            "<div class='select2-result-repository__title'>" + repo.name + "</div></div>";

                    return markup;
                }

                function formatRepoSelection (repo) {
                    return repo.name || repo.id;
                }

                var $tagInput = $('input[name$="[tagsText]"]');

                function tags($input) {
                    $input.attr('type', 'hidden');

                    var $select = $('<select id="select_' + $input.attr("name") + '" name="select_' + $input.attr("name") + '" class="form-control" multiple="multiple" />');

                    var data = $input.val().split(',');
                    for(var v in data) {
                        var value = $.trim(data[v]);
                        $("<option />", {value: value, text: value}).attr("selected", true).appendTo($select);
                    }

                    $select.insertAfter($input);

                    $select.select2({
                        tags: true,
                        //multiple: true,
                        ajax: {
                            url: $input.data('ajax'),
                            dataType: "json",
                            delay: 250,
                            data: function (params) {
                                return {
                                    q: params.term, // search term
                                    page: params.page
                                };
                            },
                            processResults: function (data, params) {
                                params.page = params.page || 1;

                                return {
                                    results: data.items,
                                    pagination: {
                                        more: (params.page * 30) < data.total_count
                                    }
                                };
                            },
                            cache: true,
                            escapeMarkup: function (markup) { return markup; }, 
                            minimumInputLength: 1,
                            templateResult: formatRepo, 
                            templateSelection: formatRepoSelection, 
                        }
                    });

                    $select.on("change", function (e) {
                        var selectedValues = $(this).val();
                        $input.val(selectedValues.join(", "));
                    });
                }

                if ($tagInput.length > 0) {
                    tags($tagInput);
                }
            }());
        });

When the code will be ok, I can make a pull to update the docs.

My only doubt is when a form has 'allow_extra_fields' => false, that can be a problem. The solution can be to remove the select when the submit button is clicked.

Filoz commented 8 years ago

An edit to the json is also needed

{
    "items": [
        {%- for tag in tags -%}
        {
            "id": "{{ tag }}",
            "text": "{{ tag }}"
        }
        {% if not loop.last %},
        {% endif %}
        {%- endfor -%}
    ]
}

This edit because the json can brig some extra data. Give a look to this line: more: (params.page * 30) < data.total_count If we add to the json the tags count, it is possible to simply paginate the results