如何在laravel背包中进行可排序的选择乘?

时间:2018-07-02 12:15:32

标签: laravel backpack-for-laravel

我需要使用Laravel背包-或具有类似功能的自定义背包进行可排序的select2_multiple。

在文档中,有一种方法可以像这样简单地实现select2_multiple:

$this->crud->addField([
    'label' => "Ingredients",
    'type' => 'select2_multiple',
    'name' => 'ingredients', // the method that defines the relationship in your Model
    'entity' => 'ingredients', // the method that defines the relationship in your Model
    'attribute' => 'name', // foreign key attribute that is shown to user
    'model' => Ingredient::class, // foreign key model
    'pivot' => true,
    'select_all' => true    
]);

但是!我看不到任何存储我们选择的条目的 sort 数据的方法!

我已经在数据库中创建字段SORT ingredients_to_products 桌子,这应该可以解决问题,但是如何将其实现到Backpack?

数据库的结构非常简单:产品,成分,成分表到产品表。 Ingredients_to_products 表只有3个字段: product_id ingredient_id sort

Laravel 5.6,背包CRUD 3.3

感谢您的帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

我找到了解决方法。

我创建了一个自定义视图,并对CrudController进行了一些更改,以手动解决排序值。 在视图部分中,我创建了一些JS和新字段,它们表示相关条目的排序值。 顺便说一句,有一个 $ entry-> pivot 函数也可以提供帮助。

所以,我做了什么:创建了一个称为“成分”的新视图

<table class="table table-bordered" id="table">
    <p>Connected ingredients:</p>
<select hidden multiple name="ingredients[]" id="ingredients">
        <?php foreach ($field['value'] as $item){ ?>
            <option selected data-id="<?= $item->id  ?>"  value="<?= $item->id  ?>"><?= $item->name  ?></option>
        <?php } ?>
    </select>

<select hidden multiple name="ingredients_sort[]" id="ingredients_sort">
    <?php foreach ($field['value'] as $item){ ?>
        <option data-id="<?= $item->id ?>" selected  value="<?= $item->pivot->sort  ?>"><?= $item->pivot->sort  ?></option>
    <?php } ?>
</select>

    <?php foreach ($field['value'] as $item){ ?>
        <tr class="item">
            <td>
                <p><?= $item->name  ?></p>
            </td>
            <td>
                <input class="sorter form-control" data-id="<?= $item->id ?>" value="<?= $item->pivot->sort  ?>">
            </td>
            <td>
                <span data-id="<?= $item->id  ?>" class="btn btn-primary remover">Remove</span>
            </td>
        </tr>
    <?php } ?>

因此,正如您所看到的,我们现在有成分 ingredients_sort 数组,这些数组通过JavaScript通过位置进行同步。

我们通过AJAX获取所有可用成分的列表。 排序值-是每个成分条目的关联输入字段。

let selected_ingredients = <?= isset($field['value']) ? json_encode($field['value']) : '' ?>;
let ingredients = [];

document.addEventListener("DOMContentLoaded", load);

function load(){
    getIngredients();
}

function getIngredients() {
    $.get('/ingredients/get').done( (response) => {
        ingredients = JSON.parse(response);
        printList(ingredients);
    } );
}

function printList(ingredients){

    // @todo : print search

    for (let i = 0; i < ingredients.length; i++){
        let item = ingredients[i];
        let _item = document.createElement('div');
            _item.className = 'item btn btn-default';
            _item.setAttribute('data-id', item.id);
            _item.innerHTML = `${item.name}`;
            _item.onclick = function () {
                // @todo: add ingredient to product

                let needAdd = true;

                for (let i = 0; i < selected_ingredients.length; i++){
                    if (selected_ingredients[i].id == item.id){
                        needAdd = false;
                    }
                }

                if (needAdd){

                    $('#ingredients').append(`<option selected data-id="${item.id}" value="${item.id}">${item.name}</option>`);
                    $('#ingredients_sort').append(`<option data-id=${item.id} selected value="0">0</option>`);

                    $('#table').append(
                        `<tr><td>
                            <p>${item.name}</p>

                            </td>
                            <td>
                                <input class="sorter form-control" data-id="${item.id}" value="0">
                            </td>
                            <td>
                                <span data-id="${item.id}" class="remover btn btn-primary">remove</span>
                            </td>
                         </tr>`);

                    $('.remover').unbind().click(function () {
                        $(this).parent().parent().remove();
                    });

                    $('.sorter').unbind().change(function(){
                        let id = $(this).attr('data-id');
                        $(`#ingredients_sort [data-id=${id}]`).val( $(this).val() ).html( $(this).val() );
                    });
                }

            };


        $('#list').append(_item);
    }

    $('.remover').unbind().click(function () {
        let id = $(this).attr('data-id');
        $(`#ingredients [data-id=${id}], #ingredients_sort [data-id=${id}]`).remove();
        $(this).parent().parent().remove();
    });

    $('.sorter').unbind().change(function() {
        let id = $(this).attr('data-id');
        $(`#ingredients_sort [data-id=${id}]`).val( $(this).val() ).html( $(this).val() );
    });
}


function remove(){
    console.log(this);
}

最后一步-将Update方法放入ItemCrudController(在我的应用中为“产品”控制器)

public function update(UpdateRequest $request)
{
     // your additional operations before save here
    $redirect_location = parent::updateCrud($request);

    $obj = \App\Models\Item::find( $request->get('id') );

    $obj->ingredients()->detach();

    $i = 0;
    foreach ( $request->get('ingredients') as $item){
        $obj->ingredients()->save( \App\Models\Ingredient::find($item), ['sort' => $request->get('ingredients_sort')[$i]]);
        $i++;
    }

    return $redirect_location;
}

所以-它有效。 结果照片如下。希望这会帮助某人。

enter image description here