Yii2 动态表单更新在 kartik-Select2 上失败

问题描述 投票:0回答:1

我正在使用 wbraganca 动态表单小部件。它对于“创建”操作效果很好。 让我感谢那些在 YouTube 上制作精彩教程视频的人!!!

我现在正在执行更新操作。我在采购订单功能上使用它。

更新动作的控制器:

public function actionUpdate($id)
{
    $model = $this->findModel($id);
    $modelsItem = $model->purchaseitems;

    if ($model->load(Yii::$app->request->post()) ) {

        $oldIDs = ArrayHelper::map($modelsItem, 'purchaseitem_id', 'purchaseitem_id');
        $modelsItem = Model::createMultiple(Purchaseitem::classname(), $modelsItem);
        Model::loadMultiple($modelsItem, Yii::$app->request->post());
        $deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsItem, 'purchaseitem_id', 'purchaseitem_id')));

        $valid = $model->validate();
        $valid = Model::validateMultiple($modelsItem) && $valid;

        if ($valid) {
            $transaction = \Yii::$app->db->beginTransaction();
            try {
                if ($flag = $model->save(false)) {
                    if (! empty($deletedIDs)) {
                        Purchaseitem::deleteAll(['purchaseitem_id' => $deletedIDs]);
                    }
                    foreach ($modelsItem as $modelItem) {
                        $modelItem->purchaseitem_purchaseorder_id = $model->purchaseorder_id;
                        $modelItem->purchaseitem_description = Inventory::findOne($modelItem->purchaseitem_inventory_id)->inventory_partno;

                        if (! ($flag = $modelItem->save(false))) {
                            $transaction->rollBack();
                            break;
                        }
                    }
                }
                if ($flag) {
                    $transaction->commit();
                    return $this->redirect(['view', 'id' => $model->purchaseorder_id]);
                }
            } catch (Exception $e) {
                $transaction->rollBack();
            }
        }

        //return $this->redirect(['view', 'id' => $model->purchaseorder_id]);
    } else {
        return $this->render('update', [
            'model' => $model,
            'modelsItem' => (empty($modelsItem)) ? [new Purchaseitem] : $modelsItem

        ]);
    }
}

但我认为问题可能发生在视图文件上,因为 Select2 字段可以显示值,这是产品的“id”而不是产品代码。

视图:

<div class="panel panel-default"> 
    <div class="panel-body"> 
         <?php DynamicFormWidget::begin([
                'widgetContainer' => 'dynamicform_wrapper', 
                'widgetBody' => '.container-items', 
                'widgetItem' => '.item', 
                'limit' => 50, 
                'min' => 1, 
                'insertButton' => '.add-item', 
                'deleteButton' => '.remove-item', 
                'model' => $modelsItem[0],
                'formId' => 'dynamic-form',
                'formFields' => [
                    'purchaseitem_inventory_id',
                    'purchaseitem_qty',
                    'purchaseitem_cost_usd',
                    'purchaseitem_deliverydate',
                ],
            ]); ?>
        <?php foreach ($modelsItem as $i => $modelItem): ?>
            <div class="item">
                <?php
                    // necessary for update action.
                    if (! $modelItem->isNewRecord) {
                        echo Html::activeHiddenInput($modelItem, "[{$i}]purchaseitem_id");
                    }
                ?>
                <div class="row">
                    <?= $form->field($modelItem, "[{$i}]purchaseitem_inventory_id")->widget(
                            Select2::classname(), [
                                'pluginOptions' => [
                                    'allowClear' => true,
                                    'minimumInputLength' => 2,
                                    'language' => [
                                        'errorLoading' => new JsExpression("function () { return 'Error on finding results...'; }"),
                                    ],
                                    'ajax' => [
                                        'url' => Url::toRoute('inventory/inventorylist'),
                                        'dataType' => 'json',
                                        'data' => new JsExpression('function(params) { return {q:params.term}; }')
                                    ],
                                    'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
                                    'templateResult' => new JsExpression('function(purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
                                    'templateSelection' => new JsExpression('function (purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
                                ],
                            ])->label(false) ?>
                    <?= $form->field($modelItem, "[{$i}]purchaseitem_qty")->textInput(['maxlength' => true])->label(false) ?>
                    <?= $form->field($modelItem, "[{$i}]purchaseitem_cost_usd")->textInput(['maxlength' => true])->label(false) ?>
                    <?= $form->field($modelItem, "[{$i}]purchaseitem_deliverydate")->widget(
                            DatePicker::className(), [
                                'options' => [
                                    ['placeholder' => 'Please enter delivery date'],
                                ],
                                'removeButton' => false,
                                'pluginOptions' => [
                                    'autoclose'=>true,
                                    'format' => 'yyyy-mm-dd',
                                    'todayHighlight' => true,
                                ]
                            ]
                        )->label(false) ?>
                </div>
            </div>
        <?php endforeach; ?>
    </div>
</div>

我认为问题可能与 JsExpression 函数的那几行有关。

'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
'templateSelection' => new JsExpression('function (purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),

对于Select2查询URL方法在这里:

public function actionInventorylist($q = null, $id = null) {
    Yii::$app->response->format = yii\web\Response::FORMAT_JSON;
    $out = ['results' => ['id' => '', 'text' => '']];
    if (!is_null($q)) {
        $query = new Query;
        $query->select('inventory_id AS id, inventory_partno AS text')
            ->from('inventory')
            ->where(['like', 'inventory_partno', $q])
            ->limit(10);
        $command = $query->createCommand();
        $data = $command->queryAll();
        $out['results'] = array_values($data);
    }
    elseif ($id > 0) {
        $out['results'] = ['id' => $id, 'text' => Inventory::find($id)->inventory_partno];
    }
    return $out;
}

当我单击更新视图时,我可以加载记录。除“partno”字段外,大多数数据都输入到表单的正确位置。我使用 Select2 让用户通过文本选择零件号并将“id”存储在表中。它适用于“创建”视图。 但在更新视图中,它只显示“id”而不是“partno”。

如果我在字段中输入,我只能选择“其他”部分,让我在这里解释一下:

如果有2个代码,“ABC”带“id”为1,“XYZ”带“id”为2。

记录原为“ABC”,字段显示“1”。 如果我输入“XYZ”,它将显示“XYZ”作为小部件的正常效果。但是,如果我改回“ABC”,它将显示“1”而不是“ABC”。

而且表格也无法提交更新。单击按钮没有任何效果。

我是 Yii2 框架的新手,并且很困惑这个问题,有谁知道我该如何解决这个问题? 谢谢!!!!

php yii2 jquery-select2 kartik-v dynamicform
1个回答
0
投票

我只是解决了问题,实际上发生了一些问题。

为了解决 Select2 小部件无法显示零件号而不是 ID 的问题,我通过 ID 找到零件号并在 Select2 中使用

initValueText
提供它。对于我的情况:

$partno = empty($modelItem->purchaseitem_inventory_id) ? '':Inventory::findOne($modelItem->purchaseitem_inventory_id)->inventory_partno;
$form->field($modelItem, "[{$i}]purchaseitem_inventory_id")->widget(Select2::classname(), ['initValueText' => $partno, ...

关于更新POST失败的问题,我得到了

Getting unknown property: backend\models\Purchaseitem::id
的错误,我发现它发生在动态表单小部件
Model.php
第25行。该行是
$keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));

如果我将

'id'
更改为我的 ID 字段名称,即
'purchaseitem_id'
,它将起作用,但此模型仅适用于此 Id 字段名称。所以我得到了模型的 PrimaryKey 并使其适用于我的其他模型。

添加此行

$primaryKey = $model->tableSchema->primaryKey;
并修改上面的行
$keys = array_keys(ArrayHelper::map($multipleModels, $primaryKey, $primaryKey));

© www.soinside.com 2019 - 2024. All rights reserved.