>

Yii2 프로젝트에는 두 가지 모델이 있습니다. 하나의 모델 : ApartmentBuilding  다른 모델에 따라 다릅니다 : Caretaker  관계를 통해. 내가 ApartmentModel 를 만들고 있다고 가정  내가 caretaker 를 선택하는 양식을 통해  동적 드롭 다운에서 그런 다음 필요한 관리인이 데이터베이스에 아직 추가되지 않았 음을 알고 있으므로 ApartmentBuilding 에서 관리인의 세부 정보를 추가해야합니다  모델 양식은 ApartmentBulding 의 세부 사항을 작성 진행  형태. 이것이 내 문제의 유스 케이스입니다.

지금까지 Caretaker 를 시작했습니다   ApartmentBulding 의 모달을 통한 모델 형식  형태. Caretaker 의 세부 사항을 제출할 때  모델 양식에서 사이트가 CaretakerController 의보기로 리디렉션됩니다. . 그러나 내가 필요한 것은 방금 모달을 통해 추가 한 관리인의 새로운 세부 정보로 드롭 다운 양식을 새로 고치고 나머지 양식 작성을 진행할 수 있어야합니다.

이 문제를 해결하는 데 도움이 될 것입니다.

지금까지 내 코드는 다음과 같습니다.

아파트 빌딩 _form.php

<?php
use yii\helpers\Html;
use kartik\widgets\ActiveForm;
use app\models\Landlord;
use app\models\Caretaker;
use yii\helpers\ArrayHelper;
use yii\bootstrap\Button;
use yii\helpers\Url;
/* @var $this yii\web\View */
/* @var $model app\models\ApartmentBuilding */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="apartment-building-form">
    <?php $form = ActiveForm::begin([
        'type' => ActiveForm::TYPE_HORIZONTAL,
        'formConfig' => ['labelSpan' => 3, 'deviceSize' => ActiveForm::SIZE_TINY],
    ]); ?>
    <?= $form->field($model, 'apartment_name')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'landlord_id')->dropDownList(ArrayHelper::map(Landlord::find()->select(['landlord_id', 'first_name', 'last_name'])->all(), 'landlord_id', 'displayName'),['class' => 'form-control inline-block', 'prompt'=>'Select Landlord']) ?>
    <?= $form->field($model, 'physical_address')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'plot_number')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'address')->widget(\kalyabin\maplocation\SelectMapLocationWidget::className(), [
        'attributeLatitude' => 'latitude',
        'attributeLongitude' => 'longitude',
        'googleMapApiKey' => 'YOUR_API_KEY_HERE',
    ]) ?>
    <?= $form->field($model, 'number_of_floors')->textInput() ?>
    <?= $form->field($model, 'apartment_desc')->textInput(['maxlength' => true]) ?>
    <div class="form-group kv-fieldset-inline">
        <?= Html::activeLabel($model, 'caretaker_id', ['label'=>'Caretaker', 'class'=>'col-sm-3 control-label']) ?>
        <div class="col-sm-8">
            <?= $form->field($model, 'caretaker_id',['showLabels'=>false])->dropDownList(ArrayHelper::map(Caretaker::find()->select(['caretaker_id', 'first_name', 'last_name'])->all(), 'caretaker_id', 'displayName'),['class' => 'form-control inline-block', 'prompt'=>'Select Caretaker']) ?>
        </div>  
        <div class="col-sm-1">
            <?= Html::button('<i class="glyphicon glyphicon-plus"></i>', ['value'=>Url::to(['caretaker/new']), 'title' => 'Create New Caretaker', 'class' => 'btn btn-success showModalButton']) ?>
        </div>
    </div>
    <?= $form->field($model, 'other_apt_details')->textInput(['maxlength' => true]) ?>
    <div class="col-sm-offset-3 col-sm-9">
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
        <?= Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
    </div>
    <?php ActiveForm::end(); ?>
</div>

카레 커 _form.php

<?php
use yii\helpers\Html;
use kartik\widgets\ActiveForm;
use kartik\widgets\DatePicker;
/* @var $this yii\web\View */
/* @var $model app\models\Caretaker */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="caretaker-form">
    <?php $form = ActiveForm::begin([
        'type' => ActiveForm::TYPE_HORIZONTAL,
        'formConfig' => ['labelSpan' => 3, 'deviceSize' => ActiveForm::SIZE_TINY],
    ]); ?>
    <?= $form->field($model, 'first_name')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'last_name')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'sex')->dropDownList(['Male' => 'Male', 'Female' => 'Female'],['prompt'=>'Select Sex']) ?> 
    <?= $form->field($model, 'date_of_birth')->widget(DatePicker::classname(), ['options' => ['placeholder' => 'Enter birth date ...'], 'pluginOptions' => ['autoclose'=>true, 'format' => 'yyyy-mm-dd']]) ?>
    <?= $form->field($model, 'address')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'mobile')->widget(\yii\widgets\MaskedInput::className(), ['mask' => '254999999999',]) ?>
    <div class="col-sm-offset-3 col-sm-9">
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
        <?= Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
    </div>
    <?php ActiveForm::end(); ?>
</div>

CaretakerController actionNew ()

public function actionNew()
{
    $model = new Caretaker();
    $model->company_id = Yii::$app->user->identity->company_id;
    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return false;
    } else {
        return $this->renderAjax('create', [
            'model' => $model,
        ]);
    }
}

모달 핸들러 :

<?php
yii\bootstrap\Modal::begin([
    'headerOptions' => ['id' => 'modalHeader'],
    'id' => 'modal',
    'size' => 'modal-lg',
    //keeps from closing modal with esc key or by clicking out of the modal.
    // user must click cancel or X to close
    'clientOptions' => ['backdrop' => 'static', 'keyboard' => FALSE]
]);
echo '<div id="modalContent"><div style="text-align:center"><?= Html::img("@web/img/loading.gif");?></div></div>';
yii\bootstrap\Modal::end();
?>

modal-popup.js

$(function(){
    //get the click of modal button to create / update item
    //we get the button by class not by ID because you can only have one id on a page and you can
    //have multiple classes therefore you can have multiple open modal buttons on a page all with or without
    //the same link.
//we use on so the dom element can be called again if they are nested, otherwise when we load the content once it kills the dom element and wont let you load another modal on click without a page refresh
      $(document).on('click', '.showModalButton', function(){
         //check if the modal is open. if it's open just reload content not whole modal
        //also this allows you to nest buttons inside of modals to reload the content it is in
        //the if else are intentionally separated instead of put into a function to get the 
        //button since it is using a class not an #id so there are many of them and we need
        //to ensure we get the right button and content. 
        // if ($('#modal').data('bs.modal').isShown) 
        if ($("#modal").data('modal') && $("#modal").data('modal').isShown){
            $('#modal').find('#modalContent')
                    .load($(this).attr('value'));
            //dynamically set the header for the modal
            document.getElementById('modalHeader').innerHTML = '<h4>' + $(this).attr('title') + '</h4>';
        } else {
            //if modal isn't open; open it and load content
            $('#modal').modal('show')
                    .find('#modalContent')
                    .load($(this).attr('value'));
             //dynamiclly set the header for the modal
            document.getElementById('modalHeader').innerHTML = '<h4>' + $(this).attr('title') + '</h4>';
        }
    });
});
$(function(){
//load the current page with the conten indicated by 'value' attribute for a given button.
   $(document).on('click', '.loadMainContent', function(){
            $('#main-content').load($(this).attr('value'));
    });
});

참고 modal handler code  그리고 modal-popup.js  보기 및 양식 작성과 같은 다른 여러 모달에서 재사용됩니다. 모달 핸들러 코드는 main.php 에 있습니다.  레이아웃 폴더의


  • 답변 # 1

    다음을 수행하여 문제를 해결할 수있었습니다. (같은 생각에 대한 더 많은 생각은 여전히 ​​환영합니다. 더 완벽한 방법이있을 수 있음을 알고 있습니다)

    다음 Javascript 를 추가했습니다  관리인에게 코드 _form.php

    <?php
    $this->registerJs("$('#createcaretaker').click(function() {
        var firstName = $('#caretaker-first_name').val();
        var lastName = $('#caretaker-last_name').val();
        var sex = $('#caretaker-sex').val();
        var dOB = $('#caretaker-date_of_birth').val();
        var address = $('#caretaker-address').val();
        var mobile = $('#caretaker-mobile').val();
        $('#modal').modal('hide');
        $.get('new?firstName='+firstName+'&lastName='+lastName+'&sex='+sex+'&dOB='+dOB+'&address='+address+'&mobile='+mobile, function(success){
            $('.refreshcaretaker').html(success);
        });
    });");
    ?>
    
    

    그런 다음 같은 양식의 제출 버튼을 다음과 같이 변경했습니다 :

    <button id="createcaretaker" type="button" class="btn btn-success">Create</button>
    
    

    따라서 버튼 ID는 Javascript 를 트리거 할 수 있습니다  서버 측에 데이터를 보내려면 위 코드를 사용하십시오.

    그런 다음 ApartmentBuilding 에서 컨트롤러 작업을 만들었습니다.  다음과 같이 데이터 입력을 처리하는 컨트롤러 :

    public function actionNew($firstName, $lastName, $sex, $dOB, $address, $mobile)
    {
        $model = new Caretaker();
        $model->company_id = Yii::$app->user->identity->company_id;
        if ($firstName != '0' && $lastName != '0' && $sex != '0' && $dOB != '0' && $address != '0' && $mobile != '0') {
            $model->first_name = $firstName;
            $model->last_name = $lastName;
            $model->sex = $sex;
            $model->date_of_birth = $dOB;
            $model->address = $address;
            $model->mobile = $mobile;
            $model->save();
            $caretakers = Caretaker::find()->all();
            foreach ($caretakers as $caretaker) {
                echo '<option value="'.$caretaker->caretaker_id.'">'.$caretaker->displayName.'</option>';
            }
        } else {
            return $this->renderAjax('caretaker_create', [
                'model' => $model,
            ]);
        }
    }
    
    

    이를 수행 한 후, 모달 양식을 제출할 때 다음과 같이 관리인 모델을 작성할 때 ajax를 통해 값을 새로 고칠 수 있도록 상위 양식의 드롭 다운 항목을 변경했습니다.

    <?= $form->field($model, '[{$i}]caretaker_id',['showLabels'=>false])->dropDownList(ArrayHelper::map(Caretaker::find()->select(['caretaker_id', 'first_name', 'last_name'])->all(), 'caretaker_id', 'displayName'),['class' => 'form-control inline-block refreshcaretaker', 'prompt'=>'Select Caretaker']) ?>
    
    

    refreshcaretaker 참고   Javascript 에 의해 트리거되는 클래스  모달이 제출 될 때 위의 코드.

    다음 링크는 Yii2에서 모달 양식 사용에 대해 자세히 설명합니다.

  • 이전 android - 전체 화면에서 스피너 드롭 다운
  • 다음 python - 파이 테스트 픽스처 - 스코프 픽스처에서 함수 픽스처 사용