CakePHP 3 - 允许用户为记录查询分配和更改订单

时间:2017-09-05 13:40:07

标签: jquery mysql ajax cakephp cakephp-3.0

目前在我的系统中,通过CakePHP 3,查询MySQL数据库,搜索slideshow plugin中使用的照片列表。用户选择要在幻灯片中使用的照片,并可以从幻灯片中添加或删除照片。但是,他们目前无法选择幻灯片显示这些照片的顺序。

在Controller中,查询如下所示:

$imagesUsed = $this->Gallery->find('all',[
    'conditions' => ['status' => 'shown', 'type' => 'image']
])->toArray();

在显示幻灯片显示的页面上:

<script>
    $(function () {
        jQuery(document).ready(function () {
            $('#header').backstretch([
                <?php foreach ($imagesUsed as $image){ ?>
                "<?= $host.$basepath ?>/webroot/uploads/<?= $image->link ?>",
                <?php } ?>
            ], {duration: 2000, fade: 750});
        });
    });
</script>

我想知道如何为查询的幻灯片照片分配数字以向用户清楚地显示顺序,并且还允许他们更改该顺序。例如:

  • 水果幻灯片目前有Apple图片(1)和香蕉图片(2)。
  • 然后,用户想要为幻灯片显示上传Peach图像,但不希望将其添加为第3张图像,而是希望将Peach更改为第一张图像。他们不想从幻灯片中删除所有图像,然后以正确的顺序重新添加图像。

更新:我在数据库表中添加了custom_sort列。我还创建了一个带有foreach循环的表单,以及一个包含JavaScript onchange函数的下拉列表选项。我正在努力找到一种方法将两者结合在一起。

使用Foreach循环的表单(不完整):

<?php $this->Form->create($gallery) ?>
<legend><?= __('Update Image Order') ?></legend>
<fieldset>
    <div class="container col-sm-12">
        <?php foreach ($galleries as $gallery): ?>
            <div class="col-sm-4">
                <?php echo $this->Form->input('link',['class' => 'form-control', 'readonly']); ?>
            </div>
            <div class="col-sm-4">
                <?php echo $this->Form->input('name',['class' => 'form-control', 'readonly']); ?>
            </div>
            <div class="col-sm-2">
                <?php echo $this->Form->input('page', ['class' => 'form-control', 'readonly']); ?>
            </div>
            <div class="col-sm-2">
                <?php echo $this->Form->input('custom_sort', ['label' => 'Slideshow Order', 'class' => 'form-control']); ?>
            </div>
        <?php endforeach ?>
    </div>
</fieldset>
<div style="text-align: center">
    <?php echo $this->Form->button(__('Submit'), ['class' => 'btn btn-secondary btn-xl page-scroll']) ?>
</div>
<?php $this->Form->end() ?>

在控制器中:

public function updateorder()
{
    $galleries = $this->Galleries->find('all',[
        'conditions' => ['status' => 'shown', 'type' => 'image'],
        'order' => ['custom_sort' => 'ASC']
    ])->toArray();

    if ($this->request->is(['patch', 'post', 'put'])) {
        $galleries = $this->Galleries->patchEntities($galleries, $this->request->data);
        if ($this->Galleries->updateAll([$galleries], [])) {
            $this->Flash->success(__('The image slideshow orders have been updated.'));

            return $this->redirect(['action' => 'managemedia']);
        } else {
            $this->Flash->error(__('The image slideshow orders could not be updated. Please, try again.'));
        }
    }
    $this->set(compact('galleries'));
    $this->set('_serialize', ['galleries']);
}

下拉选择和JavaScript onchange功能(不完整):

<label for="page" id="pageLabel" style="text-align: left">Page</label>
<select name="page" id="page" onchange="changePage()" class="form-control">
    <option value="" disabled selected hidden>Select a page</option>
    <option value="Home">Home</option>
    <option value="Fruits">Fruits</option>
    <option value="Vegetables">Vegetables</option>
</select>

<script>
function changePage() {
    var pageChoice = document.getElementById('page');
    var selectedPageChoice = pageChoice.options[pageChoice.selectedIndex].value;
    $.ajax({
        url: "<?= $host . $basepath ?>/gallery.json",
        type: 'POST',
        success: function (res) {
            console.log(res);
        }
    })
}
</script>

console.log(res)在浏览器控制台中向我展示了这一点:

> Object
  > galleries: Array (x) //galleries being the array variable set in the AJAX request URL, Array (x) referring to the number of elements in that array.
    > 0: {id: 1, link: "images/apples.jpg", name: "Apple", page: "Fruits", custom_sort: 1}
    > 1: {id: 2, link: "images/banana.jpg", name: "Banana", page: "Fruits", custom_sort: 2}
    > 2: {id: 3, link: "images/pumpkin.jpg", name: "Pumpkin", page: "Vegetables", custom_sort: 1}
    > 3: {id: 4, link: "images/peach.jpg", name: "Peach", page: "Fruits", custom_sort: 3}

我可以从中检索单个值:

console.log(res.galleries.0.link);会在控制台中打印Peach。

目前,表单显示4个表单输入重复项(等于现有条目数),但它们都是空白的。

2 个答案:

答案 0 :(得分:0)

您可以使用jQuery UI Sortable(http://jqueryui.com/sortable/)。您可以在发布时序列化排序顺序,并使用AJAX请求更新数据库。

答案 1 :(得分:0)

我通常在db中添加一个名为sortable或custom_sort的列。

您可以为用户提供输入以指定他们自己的订单。

您的查询将如下所示。

// Notice I call Galleries. This may not be right for you, 
// but cake convention is plural table names
// I also use where() instead of conditions. This is also a suggestion
$images = $this->Galleries->find('all')
    ->where(['status' => 'shown', 'type' => 'image'])
    ->order(['custom_sort' => 'ASC']);

我还建议您自己调用toArray而不是设置序列化变量

$this->set(['images' => $images]);
$this->set('_serialize', 'images');

并确保您的请求需要json

$.ajax({dataType:'json'});

提交更新的订单

更新图像时,您可以进行批量更新,假设您发布的数据如下所示。

$requestData = [
    [
        'id' => 100,
        'custom_sort' => 1,
    ],
    [
        'id' => 200,
        'custom_sort' => 2,
    ],
    [
        'id' => 300,
        'custom_sort' => 3,
    ]
];

您可以像这样快速保存数据

$galleries = $this->Galleries->newEntities($requestData);
// This does not call callbacks (beforeSave, afterSave)
$this->Galleries->updateAll($galleries);

根据问题进行修改

更新多条记录可能看起来像这样。

在输出循环中通过图像

<?php foreach($images as $image): ?>
    <input data-image_id="<?= $image->id; ?>" class="image-custom-sort" value="<?= $image->custom_sort; ?>" />
<?php endforeach; ?>
<button onClick="handleSubmit">Save Sort Order</button>

然后一些javascript。我已经写了一段时间,因为我编写了Jquery,因此一些jquery特定的部分可能是错误的,但这应该给你一个想法。不要复制并粘贴下面的代码,因为我认为它不会按原样运行。

function handleSubmit(e){
    var inputs = $('input.image-custom-sort');
    var data = [];
    $.each(inputs, function (input) {
        data.push({
            id: input.dataset.image_id
            custom_sort: $(input).val()
        })
    });

    $.ajax({
        dataType: 'json',
        data: data
    })
}