community-forum icon indicating copy to clipboard operation
community-forum copied to clipboard

[Feature Request] Add new field type checklist_array

Open lordjack opened this issue 4 years ago • 2 comments
trafficstars

Feature Request

What's the feature you think Backpack should have?

My suggestion is the addition of another CheckboxList field type with array for the form. Example: checklist_array

I implements this new feature, and would like to share this solution with this solution, so that other developers may also need to use and also contribute to the framework that is very good, I am very liking to use it.

Have you already implemented a prototype solution, for your own project?

Yes

Do you see this as a core feature or an add-on?

Yes

Follow my contribution.

I create a file at resources/views/vendor/backpack/crud/fields/checklist_array.blade.php with the below content (checklist_array):

I updated the code for the one below, One of the updates I did was, when editing it did not bring the selected values. Now you are bringing through script in javascript

<!-- checklist with directly provided options -->
<!-- checklist_filtered -->
@php
$options = isset($field['options']) ? $field['options'] : [];

// calculate the value of the hidden input
$field['value'] = old(square_brackets_to_dots($field['name'])) ?? ($field['value'] ?? ($field['default'] ?? []));

if (is_string($field['value'])) {
    $field['value'] = json_decode($field['value']);
} 

// define the init-function on the wrapper
$field['wrapper']['data-init-function'] = $field['wrapper']['data-init-function'] ?? 'bpFieldInitChecklist';
@endphp

@include('crud::fields.inc.wrapper_start')
<label>{!! $field['label'] !!}</label>
@include('crud::fields.inc.translatable_icon')

<input type="hidden" value='@json($field['value'])' name="{{ $field['name'] }}">

<div class="row">
    @foreach ($options as $option)
    <div class="col-sm-4">
        <div class="checkbox">
            <label>
                <input type="checkbox" name="{{ $field['name'] }}[]" value="{{ $option }}" @if( ( old( $field["name"] )
                    && in_array($option , old( $field["name"])) ) ) checked="checked" @endif> {!! $option !!}
            </label>
        </div>
    </div>
    @endforeach
</div>

{{-- HINT --}}
@if (isset($field['hint']))
<p class="help-block">{!! $field['hint'] !!}</p>
@endif
@include('crud::fields.inc.wrapper_end')

{{-- ########################################## --}}
{{-- 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->fieldTypeNotLoaded($field))
@php
$crud->markFieldTypeAsLoaded($field);
@endphp
{{-- FIELD JS - will be loaded in the after_scripts section --}}
@push('crud_fields_scripts')
<script>
    function bpFieldInitChecklist(element) {
                //console.log(element);
                var hidden_input = element.find('input[type=hidden]');
                var selected_options = JSON.parse(hidden_input.val() || '[]');
                var checkboxes = element.find('input[type=checkbox]');
                var container = element.find('.row');

                // set the default checked/unchecked states on checklist options
                checkboxes.each(function(key, option) {
                    var id = $(this).val();
                    if (selected_options.map(String).includes(id)) {
                        $(this).prop('checked', 'checked');
                    } else {
                        $(this).prop('checked', false);
                    }
                });

                // when a checkbox is clicked
                // set the correct value on the hidden input
                checkboxes.click(function() {
                    var newValue = [];

                    checkboxes.each(function() {
                        if ($(this).is(':checked')) {
                            var id = $(this).val();
                            newValue.push(id);
                        }
                    });

                    hidden_input.val(JSON.stringify(newValue));

                });
            }

</script>
@endpush

@endif
{{-- End of Extra CSS and JS --}}
{{-- ########################################## --}}
   //form
   $this->crud->addField([
        'label'     => 'Printers',
        'type'      => 'checklist_array',
        'name'      => 'printer',
        'attribute' => 'printer_name',
        'options'   => ['HP', 'Cannon', 'Dell'],
    ]);
 
//model
protected $casts = [
        ...
        'printer' => 'array',
    ];

lordjack avatar Jun 19 '21 15:06 lordjack

Hello there! Thanks for opening your first issue on this repo!

Just a heads-up: Here at Backpack we use Github Issues only for tracking bugs. Talk about new features is also acceptable. This helps a lot in keeping our focus on improving Backpack. If you issue is not a bug/feature, please help us out by closing the issue yourself and posting in the appropriate medium (see below). If you're not sure where it fits, it's ok, a community member will probably reply to help you with that.

Backpack communication channels:

  • Bug Reports, Feature Requests - Github Issues (here);
  • Quick help (How do I do X) - Gitter Chatroom;
  • Long questions (I have done X and Y and it won't do Z wtf) - Stackoverflow, using the backpack-for-laravel tag;
  • Showing off something you've made, asking for opinion on Backpack/Laravel matters - Reddit;

Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or Stackoverflow is thanks to our awesome awesome community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch.

Thank you!

-- Justin Case The Backpack Robot

welcome[bot] avatar Jun 19 '21 15:06 welcome[bot]

@lordjack I totally agree with you!

I've needed this before and just did the same as you, created a custom checklist_array. I think it is very very useful, I 100% vote for it to be a core field. Either refactoring the current one to allow both scenarios (so if you define options it works with options you provide, otherwise it would get the from the provided model).

Or simply introduce a new field (probably easier and safer). But 100% I've needed this several times in the past and just created custom fields.

I don't want to "put the wagon in front of the oxens", but I think we are going to do this in 4.2, atleast I am going to vouche for it.

Would you like to create the PR for it so you would show up as a contributor ? No problem if you don't have time or will to do it, I can do it later when we start merging stuff into 4.2.

Anyway, thanks for sharing your solution, I am pretty sure it will help someone in the meanwhile.

Wish you the best, Pedro

pxpm avatar Sep 07 '21 09:09 pxpm