Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.1][Package / Custom Field] Field type text_suggestions_from_array aka Autocomplete #15

Closed
chriscalip opened this issue Jan 18, 2018 · 16 comments

Comments

@chriscalip
Copy link

Who wants it? Can we have it?

Autocomplete from array, text_suggestions_from_array
datalist-default
flexdatalist

Difference between select2 and autocomplete datalist?
Think of it as the difference between a requirement and a suggestion. For the select element, the user is required to select one of the options you've given. For the datalist element, it is suggested that the user select one of the options you've given, but he can actually enter anything he wants in the input.

All features found in https://laravel-backpack.readme.io/docs/crud-fields#section-select_from_array
with an additional feature of "or_other"

Roughly same feature: https://www.drupal.org/project/select_or_other

@chriscalip
Copy link
Author

chriscalip commented Apr 18, 2018

In a position to deliver this feature request.
So at the essence of this feature request is the idea of helping users to answer a question with suggestions.

Now one way to go about this is to make a "pick an option or other" flow.
select-or-other-pic
This can be a pain to deliver because it merges 2 form fields: checkboxes, and a textbox into one.

Another way to go about this is just a textbox with suggestions
http://blog.teamtreehouse.com/creating-autocomplete-dropdowns-datalist-element
https://stackoverflow.com/questions/6865943/html-form-select-option-vs-datalist-option
datalist-default

@chriscalip
Copy link
Author

Well I am down to picking 2 libraries; each with its advantages and disadvantages.

https://github.com/leaverou/awesomplete/
https://github.com/pawelczak/EasyAutocomplete

@chriscalip
Copy link
Author

chriscalip commented Apr 19, 2018

Text Suggestions libraries capable of doing multiple values.
Both libraries uses convention of comma separated values to denote multiple values.

http://projects.sergiodinislopes.pt/flexdatalist/
https://github.com/leaverou/awesomplete/

Flextdatalist is heavier (requires jquery!) but has better visual feedback on selections
flexdatalist
Awesomplete is lighter but less visual feedback on selections, eg. Textbox field values are comma separated.
awesomplete

@mamarmite
Copy link

I made a suggestion in PR Laravel-Backpack/CRUD#1257 with a toggling functionnality. It's still very WIP, but you can start with that by making a toggle option on the other value and managing the save process after validation.

Any suggestions, fixes or improvements are very welcome.

@chriscalip
Copy link
Author

chriscalip commented Apr 19, 2018

@mamarmite Right, interesting feature. the difference of this feature request is that select2 makes options required entry values. This feature allows entries outside the options.
For more details see: https://stackoverflow.com/questions/6865943/html-form-select-option-vs-datalist-option

Errata:
I switched from suggestion checkboxes or other to textfield autocomplete suggestions.

@indra1
Copy link

indra1 commented Apr 19, 2018

You know you can add your own custom fields in backpack, right? I don't really see the need for this tbh

@chriscalip
Copy link
Author

@indra1 Yes, I've already added my custom fields. it works; I was just making a patch for it.
Close this issue if you don't want a pull request.

@chriscalip chriscalip changed the title Feature Request: CRUD field type select_or_other_from_array Feature Request: CRUD field type text_suggestions_from_array Apr 19, 2018
@chriscalip
Copy link
Author

chriscalip commented Apr 19, 2018

Custom code with the limitations of the available autocomplete js libraries are not ready for the rigors of contributing back.
I am closing this issue.

If anyone wants to bring this back.. here were the roadblocks.

http://projects.sergiodinislopes.pt/flexdatalist/ had better ux but has critical bug:
sergiodlopes/jquery-flexdatalist#118
This prevents multiple values feature for this autocomplete js library.

LeaVerou/awesomplete#14184 has ok ux for multiple values..
but has a feature request that just not moving.
LeaVerou/awesomplete#14184
This prevents the nice tagging style on multiple values feature.

@chriscalip
Copy link
Author

chriscalip commented Apr 19, 2018

Anyone interested on using this crud field type. Here's a basic draft.
text_suggestions_from_array using js library http://leaverou.github.io/awesomplete/

resources/views/vendor/backpack/crud/fields/text_suggestions_from_array.blade.php

<!-- text_suggestions_from_array -->
<div @include('crud::inc.field_wrapper_attributes') >
    <label>{!! $field['label'] !!}</label>
    <br />
    <input
        type="text"
        name="{{ $field['name'] }}"
        data-list="#{{ $field['name'] }}-datalist"
        value="{{ old($field['name']) ? old($field['name']) : (isset($field['value']) ? $field['value'] : (isset($field['default']) ? $field['default'] : '' )) }}"
        @include('crud::inc.field_attributes', ['default_class' =>  'form-control awesomplete'])
        @if (isset($field['allows_multiple']) && $field['allows_multiple']==true)data-multiple @endif
    >
    <ul
        id="{{ $field['name'] }}-datalist"
        style="display:none">

        @if (count($field['options']))
            @foreach ($field['options'] as $key => $value)
                @if((old($field['name']) && ($key == old($field['name']) || is_array(old($field['name'])) && in_array($key, old($field['name'])))) || (is_null(old($field['name'])) && isset($field['value']) && ($key == $field['value'] || (is_array($field['value']) && in_array($key, $field['value'])))))
                    <option value="{{ $key }}" selected>{{ $value }}</option>
                @else
                    <option value="{{ $key }}">{{ $value }}</option>
                @endif
            @endforeach
        @endif
    </ul>


    {{-- HINT --}}
    @if (isset($field['hint']))
        <p class="help-block">{!! $field['hint'] !!}</p>
    @endif
</div>

{{-- ########################################## --}}
{{-- Extra CSS and JS for this particular field --}}
{{-- If a field type is shown multiple times on a form, the CSS and JS will only be loaded once --}}
@if ($crud->checkIfFieldIsFirstOfItsType($field, $fields))

    {{-- FIELD CSS - will be loaded in the after_styles section --}}
    @push('crud_fields_styles')
        <!-- include text_suggestions css-->
        <link href="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.2/awesomplete.css" rel="stylesheet" type="text/css" />
    @endpush

    {{-- FIELD JS - will be loaded in the after_scripts section --}}
    @push('crud_fields_scripts')
        <!-- include text_suggestions js-->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.2/awesomplete.js"></script>
        <script>
            new Awesomplete('input[data-multiple]', {
                filter: function(text, input) {
                    return Awesomplete.FILTER_CONTAINS(text, input.match(/[^,]*$/)[0]);
                },

                item: function(text, input) {
                    return Awesomplete.ITEM(text, input.match(/[^,]*$/)[0]);
                },

                replace: function(text) {
                    var before = this.input.value.match(/^.+,\s*|/)[0];
                    this.input.value = before + text + ", ";
                }
            });
        </script>
    @endpush

@endif
{{-- End of Extra CSS and JS --}}
{{-- ########################################## --}}

How to use:

        $this->crud->addField([
            'name' => 'cities',
            'label' => 'Participating Cities',
            'type' => 'text_suggestions_from_array',
            'allows_multiple' => true,
            'options' => ['Chicago' => 'Chicago', 'New York' => 'New York', 'Boston' => 'Boston', 'Tokyo' => 'Tokyo'],
        ]);

@chriscalip chriscalip changed the title Feature Request: CRUD field type text_suggestions_from_array Feature Request: CRUD field type text_suggestions_from_array aka Autocomplete Apr 19, 2018
@chriscalip
Copy link
Author

Opened issue, as of today I am not able to complete this task; but someone might be able to finish this feature request.

@chriscalip chriscalip reopened this Apr 20, 2018
@tabacitu
Copy link
Member

tabacitu commented May 9, 2018

Hi @chriscalip - looks like some great work you've done here.

It might be that I'm just dumb, but what is different between this field and select2_from_array, except for using a different JS plugin?

Thanks, cheers!

@chriscalip
Copy link
Author

@tabacitu
Think of it as the difference between a requirement and a suggestion. For the select element, the user is required to select one of the options you've given. For the datalist element, it is suggested that the user select one of the options you've given, but he can actually enter anything he wants in the input.

@tabacitu
Copy link
Member

Oh, ok, I get it. In this case, we can totally add a flexdatalist or awesomplete field type.

I would personally prefer flexdatalist over awesomplete, since it looks like:

  • awesomplete has a very particular look and feel, that doesn't really match AdminLTE or admin panels in general;
  • awesomplete doesn't seem to support adding custom datalist items, while flexdatalist does;
  • flexdatalist seems to be more configurable;

@tabacitu tabacitu changed the title Feature Request: CRUD field type text_suggestions_from_array aka Autocomplete [4.1][Package / Custom Field] Field type text_suggestions_from_array aka Autocomplete Aug 17, 2019
@tabacitu tabacitu transferred this issue from Laravel-Backpack/CRUD Jul 25, 2020
@tabacitu tabacitu added this to To do in 📥 Inbox (in need of a deadline) via automation Oct 9, 2020
@dandarie
Copy link

Hi.

I was able to create a tags field with minimal effort using the dynamic option creation feature of select2:

$this->crud->addField([
            'name' => 'tags',
            'fake' => true,
            'store_in' => 'extras',
            'type' => 'select2_from_array',
            'allows_multiple' => true,
            'attributes' => [
                'data-tags' => true
            ],
            'options' =>[
                // existing options
            ],
        ]);

One caveat, though: the options array must have the same key and value for each item. Otherwise, the value sent to the controller is the numeric key of the item, for existing items.

'options' =>[
  'video' => 'video',
  'image' => 'image'
],

One obviously needs to provide a model mutator to save the new values and also some method to hydrate all options.

Now all you need to do is update the documentation :)

@tabacitu
Copy link
Member

tabacitu commented Jun 6, 2023

Whoaw - this suggestions sure has slipped through the cracks 😔 Trying to wrap up old issues, and like @dandarie said above, we can now do exactly this using the built-in select2 field. So I'm going to close this issue - I don't think an add-on for this is needed. I would happily publish a tutorial on this though, if anybody wants to write one in our Backpack blog. 1200+ developers would see it, and it's a great way to promote your own blog, brand etc.

Thanks a lot for collaborating here, Chris and everyone else. Apologies for replying so late.
Cheers!

@tabacitu tabacitu closed this as completed Jun 6, 2023
@dandarie
Copy link

dandarie commented Jun 6, 2023

More important is to update the docs. I myself have forgotten about this and needed it some time ago, then came back to this after searching for a solution.

Will this still work in v6?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants