Related
I am trying to call a API URL using AJAX. I need to validate the response and update the DB, SO I need to return it to the controller.
Is there any way to do that. Here is my view, JS and controller code.
Here is my View Code where I have a separate URL for validation, which is the API URL
View
<?php $form = ActiveForm::begin([
'action' => ['users/renderstep3'],
'validationUrl' => 'API URL',
'options' => [
'class' => 'comment-form'
]
]); ?>
<?= $form->field($paymentmodel, 'customerId')->hiddenInput(['value'=> $userid])->label(false) ?>
<?= $form->field($paymentmodel, 'owner')->textInput(['maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
JS
jQuery(document).ready(function($) {
$('body').on('submit', '.comment-form', function(event) {
event.preventDefault(); // stopping submitting
var data = $(this).serializeArray();
data.splice(0,1);
var result = {};
for ( i=0 ; i < data.length ; i++)
{
key = data[i].name.replace("UserPaymentDetails[", "").slice(0,-1);
result[key] = data[i].value;
}
var url = $(this).attr('validationUrl');
$.ajax({
url: url,
type: 'post',
dataType: 'json',
data: JSON.stringify(result)
})
.done(function(response) {
return response;
})
.fail(function() {
console.log("error");
});
});
});
Controller Action
public function actionRenderstep3()
{
$model = new Users();
$detailsmodel = new UserDetails();
$paymentmodel = new UserPaymentDetails();
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$data = Yii::$app->request->post();
print_r($data) ; exit;
}
if ($paymentmodel->load(Yii::$app->request->post()) && $paymentmodel->validate())
{
$paymentmodel->Status = 0;
$paymentmodel->save();
return $this->redirect(['index']);
}
return $this->render('renderstep3', [
'model' => $model,
'detailsmodel' => $detailsmodel,
'paymentmodel' => $paymentmodel,
]); }
Thanks in advance!!
In your controller, you have to change the action like this in order to validate using Ajax. I have edited my answer. Please note that you can delete your custom js code in order to use like this.
// ... The View file
<?php
$form = ActiveForm::begin([
'action' => ['users/renderstep3'],
'enableAjaxValidation' => true,
'validationUrl' => 'API URL',
'options' => [
'class' => 'comment-form'
]
]);
?>
<?= $form->field($paymentmodel, 'customerId')->hiddenInput(['value'=> $userid])->label(false) ?>
<?= $form->field($paymentmodel, 'owner')->textInput(['maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
// ... Controller
public function actionRenderstep3()
{
$model = new Users();
$detailsmodel = new UserDetails();
$paymentmodel = new UserPaymentDetails();
if (Yii::$app->request->isAjax && $paymentmodel->load(Yii::$app->request->post())) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if ($paymentmodel->load(Yii::$app->request->post())) {
$paymentmodel->Status = 0;
$paymentmodel->save(false); // Validate false, because we did the validation before
return $this->redirect(['index']);
}
return $this->render('renderstep3', [
'model' => $model,
'detailsmodel' => $detailsmodel,
'paymentmodel' => $paymentmodel,
]);
}
You can find more information here
https://www.yiiframework.com/doc/guide/2.0/en/input-validation
<?php
$form = ActiveForm::begin([
'action' => ['users/renderstep3'],
'validationUrl' => 'API URL',//ajax validation hit to validationUrl if provide other wise validationUrl is action Url
'options' => [
'class' => 'comment-form'
]
]);
?>
and change some code in js
the below code calls befor form submit
$('body').on('beforeSubmit', '.comment-form', function(event)
In controller
In case of single model validation
if ($paymentmodel->load(Yii::$app->request->post())) {
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return yii\widgets\ActiveForm::validate($model);
}
$paymentmodel->Status = 0;
if ($paymentmodel->save(false)) {
return $this->redirect(['index']);
}
}
In case of multiple model validation
if ($model->load(Yii::$app->request->post())) {
$detailsmodel->load(Yii::$app->request->post());
$paymentmodel->load(Yii::$app->request->post());
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$return = yii\widgets\ActiveForm::validate($model);
$return = \yii\helpers\ArrayHelper::merge(yii\widgets\ActiveForm::validate($detailsmodel), $return);
$return = \yii\helpers\ArrayHelper::merge(yii\widgets\ActiveForm::validate($paymentmodel), $return);
return $return;
}
//here is data saving or logic
}
I have problem with my laravel project, when validator false return back function run well on localhost, but on the server it return to root url , somebody may help me figure it out?
My controller like this:
public function update(Request $request, $id)
{
if ($request->isMethod('get'))
return view('employees.form_edit', ['user' => User::find($id)]);
else {
$rules = [
'name' => 'required',
'full_name' => 'required',
'id_number' => 'required',
'date_of_birth' => 'required',
'avatar' => 'mimes:jpeg,jpg,png,gif|max:2048'
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator)
;
}
$user = User::find($id);
$user->name = $request->name;
$user->position = $request->position;
$user->full_name = $request->full_name;
$user->id_number = $request->id_number;
$user->date_of_birth = $request->date_of_birth;
$user->status = $request->status;
$img_current = 'upload/avatar/' .$request->input('img_current');
if (!empty($request->file('avatar'))) {
$file_name = $request->file('avatar')->getClientOriginalName();
$user->image = $file_name;
$request->file('avatar')->move('upload/avatar/',$file_name);
if (File::exists($img_current)) {
File::delete($img_current);
}
}else{
echo "no file";
}
$user->save();
return redirect('listEmployees');
}
}
My route:
Route::group(['prefix' => 'listEmployees'], function () {
Route::match(['get', 'post'], 'update/{id}', 'EmployeesController#update');
});
Try this code I have
CONTROLLER
public function update(Request $request, $id)
{
if ($request->isMethod('get'))
return view('employees.form_edit', ['user' => User::find($id)]);
else {
$_data = $request->validate([
'name' => ['required'].
'full_name' => ['required'],
'id_number' => ['required'],
'date_of_birth' => ['required'],
'avatar' => ['mimes:jpeg,jpg,png,gif', 'max:2048'],
'position' => ['nullable'],
'status' => ['nullable']
])
$img_current = 'upload/avatar/' .$request->input('img_current');
if (!empty($request->file('avatar'))) {
$file_name = $request->file('avatar')->getClientOriginalName();
$data['image'] = $file_name;
$request->file('avatar')->move('upload/avatar/',$file_name);
if (File::exists($img_current)) {
File::delete($img_current);
}
}else{
echo "no file";
}
$user = User::find($id);
$user->update($_data);
return redirect('listEmployees');
}
}
VIEW
#if ($errors->any())
<div class="alert alert-warning">
#foreach ($errors->all() as $error)
{{$error}} <br>
#endforeach
</div>
#endif
Before you go further with this problem you need to clean up your code a little bit.
First of all you dont need to check the request->method if you have already made the route "Route::update" (laravel takes care of it).
Second: use laravel form-request and make your controller much more cleaner and readable(php artisan make:request ModelNameRequest)
Third: you dont need to redirect user to manually if you want to redirect to back(), again laravel takes care of it, it will redirect back() if the validator fails with and array of $errors.
any ways this is the code that may work:
public function update(Request $request, $id)
{
$rules = [
'name' => 'required',
'full_name' => 'required',
'id_number' => 'required',
'date_of_birth' => 'required',
'avatar' => 'mimes:jpeg,jpg,png,gif|max:2048'
];
// if the validation failes, laravel redirects back with a collection of $errors
$this->validate($request->all(), $rules);
// you probably want to use User::create($request->only('input1', 'input2', ...);
$user = User::find($id);
$user->name = $request->name;
$user->position = $request->position;
$user->full_name = $request->full_name;
$user->id_number = $request->id_number;
$user->date_of_birth = $request->date_of_birth;
$user->status = $request->status;
$img_current = 'upload/avatar/' .$request->input('img_current');
// use a good package for storing your files like Mediable to make it easy.
if (!empty($request->file('avatar'))) {
$file_name = $request->file('avatar')->getClientOriginalName();
$user->image = $file_name;
$request->file('avatar')->move('upload/avatar/',$file_name);
if (File::exists($img_current)) {
File::delete($img_current);
}
}else{
//TODO: you should not echo some thing here, you should use session()->flash()
session()->flash('message', 'You did not select any file.');
}
$user->save();
return redirect('listEmployees');
}
i solve this problem by change redirect function to
return redirect()->action(
'EmployeesController#update', ['id' => $id]
)
thank all guy
I want to search field in my application. I have penerimaan_table. There are rm_code, quantity, bulan, price fields.
How to show my result like this:
rm_code bulan
k123 7
k123 4
k123 5
When I filter I want just show bulan 7 & 5
k123 7
k123 5
How can I do this?
This is my view:
<?php
use yii\helpers\Html;
use kartik\grid\GridView;
use kartik\export\ExportMenu;
/* #var $this yii\web\View */
/* #var $searchModel backend\models\PenerimaanSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Penerimaan Raw Material';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="penerimaan-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a('Tambah Penerimaan Raw Material', ['create'], ['class' => 'btn btn-success']) ?>
<?= Html::a('Import Penerimaan', ['import'], ['class' => 'btn btn-success']) ?>
</p>
<p><font color="red">Deskripsi Barang yang kosong merupakan Barang Baru!!</p></font>
<?php
echo ExportMenu::widget([
'dataProvider' => $dataProvider,
'columns' => [
// 'id',
'rm_code',
'rmCode.deskripsi_barang',
'saldo_awal',
'quantity',
'bulan',
//'price',
'total'
],
'showPageSummary' => true,
]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'kartik\grid\SerialColumn'],
// 'id',
'rm_code',
'rmCode.deskripsi_barang',
// 'saldo_awal',
'quantity',
'bulan',
[
'attribute' => 'price',
'label' => 'Price',
'footer' => $myAverage,
],
//'price',
[
'label' => 'Total',
'attribute' => 'total',
'pageSummary' => true,
// 'pageSummaryOptions' => ['id_layanan' => 'deskripsi'],
'value' => function ($model) {
if($model)
return $model->total ;
else
return 0;
}
],
['class' => 'kartik\grid\ActionColumn'],
],
'showPageSummary' => true,
]); ?>
<?php echo"Harga Rata-rata Barang adalah:";
$myAverage = 0;
$myTot =0;
$myCnt = 0;
$data = $dataProvider->getModels();
foreach ($data as $key => $value) {
$myTot += $value['price'];
$myCnt++;
}
if ($myCnt>0){
$myAverage = $myTot/$myCnt;
}
echo $myAverage; // your average displayed herre, you can place it wherever you want.
?>
<?php
$this->registerJs("
// 1. Dapatkan handle dari tabel gridview
table = $('div.grid-view > table');
// 2. Hitung kolom tertentu, pada contoh ini menghitung nilai total pada kolom ke 3
var sum = 0;
table.find('tbody').find('tr').each(function() {
sum += parseInt($(this).find('td:nth-child(4)').text());
});
// 3. Tampilkan hasil perhitungan pada tabel baris terakhir kolom ke 3
table.find('tfoot > tr > td:nth-child(4)').text(sum);
");
?>
</div>
Problem 1: the validators
Within your PenerimaanSearch-model remove the integer-validator for the bulan-field. And add two new ones as follows:
public function rules() {
//...
[['bulan'], 'integer', 'when'=>function($model) {
return strpos($model->bulan, '&') === false;
}],
[['bulan'], 'string', 'when'=>function($model) {
return strpos($model->bulan, '&') !== false;
}],
//...
}
This will only validate your field as an integer when no &is present. Otherwise it will use a string validator. The optimal way would be a regex-v& onle, but I'm sure you'll figure out how to do so.
Problem 2: functionality within the Search model
Again in the BulanSearch you can find the search()-method which is responsible for filtering the result by attributes. Remove all operations concerning the bulan-field and instead use the following:
public function search($params)
{
//...
if (!empty($this->bulan)) {
if (strpos($this->bulan, '&') !== false) {
$bulan = $this->bulan;
} else {
//filter with int
$bulan = explode('&', $this->bulan);
}
$this->andFilterWhere(['bulan'=>$bulan]);
}
//...
}
That should do the trick. The andFilterWhere decides itself whether to use an IN-condition (multiple values) or a regular comparison (single value).
This should do the trick! However, tell me if you have problems. I'll be happy to help!
In my project, I have an aggregation between, let's say, a University model and a Department model: a university have at least one department, while every department belongs to only one university.
I'd like to have a possibility to create a university model instance with some number of department model instances and the exact number of departments is not known in advance (but at least one must exist). So, when creating a university, I'd like to have a page with one default department and an "Add Department" button that would allow me by means of javascript to add any number of departments that I need.
The question is: how should I write the create view page using ActiveForm in order that my POST array has the following structure:
"University" => ["name" => "Sorbonne", "city" => "Paris"],
"Faculty" => [
0 => ["name" => "Medicine", "dean" => "Person A"],
1 => ["name" => "Physics", "dean" => "Person B"],
2 => ["name" => "Mathematics", "dean" => "Person C"],
...
]
that I then pass to Faculty::loadMultiple() method.
I've tried something like this
$form = ActiveForm::begin();
echo $form->field($university, 'name')->textInput();
echo $form->field($university, 'city')->textInput();
foreach ($faculties as $i => $faculty) {
echo $form->field($faculty, "[$i]name")->textInput();
echo $form->field($faculty, "[$i]dean")->textInput()
}
ActiveForm::end();
It works, but when adding new department by means of javascript (I just clone an html node that contains department input fields), I am forced to elaborate the numbers coming from variable $i of the above php script. And this is quite annoying.
Another possibility that I've tried was to get rid of variable $i and write something like
$form = ActiveForm::begin();
echo $form->field($university, 'name')->textInput();
echo $form->field($university, 'city')->textInput();
foreach ($faculties as $faculty) {
echo $form->field($faculty, "[]name")->textInput();
echo $form->field($faculty, "[]dean")->textInput()
}
ActiveForm::end();
In this way, cloning the corresponding node is very simple, but the generated POST array has wrong structure due to [] brackets.
Is it possible to modify the latter approach and to have the required structure of the POST array?
Use Yii2 dynamic form extension:
Installation
The preferred way to install this extension is through composer.
Either run:
composer require --prefer-dist wbraganca/yii2-dynamicform "dev-master"
Or add to the require section of your composer.json file:
"wbraganca/yii2-dynamicform": "dev-master"
Demo page: Nested Dynamic Form
Nested Dynamic Form Demo Source Code:
Source Code - View: _form.php
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use wbraganca\dynamicform\DynamicFormWidget;
?>
<div class="person-form">
<?php $form = ActiveForm::begin(['id' => 'dynamic- form']); ?>
<div class="row">
<div class="col-sm-6">
<?= $form->field($modelPerson, 'first_name')->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-6">
<?= $form->field($modelPerson, 'last_name')->textInput(['maxlength' => true]) ?>
</div>
</div>
<div class="padding-v-md">
<div class="line line-dashed"></div>
</div>
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper',
'widgetBody' => '.container-items',
'widgetItem' => '.house-item',
'limit' => 10,
'min' => 1,
'insertButton' => '.add-house',
'deleteButton' => '.remove-house',
'model' => $modelsHouse[0],
'formId' => 'dynamic-form',
'formFields' => [
'description',
],
]); ?>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Houses</th>
<th style="width: 450px;">Rooms</th>
<th class="text-center" style="width: 90px;">
<button type="button" class="add-house btn btn-success btn-xs"><span class="fa fa-plus"></span></button>
</th>
</tr>
</thead>
<tbody class="container-items">
<?php foreach ($modelsHouse as $indexHouse => $modelHouse): ?>
<tr class="house-item">
<td class="vcenter">
<?php
// necessary for update action.
if (! $modelHouse->isNewRecord) {
echo Html::activeHiddenInput($modelHouse, "[{$indexHouse}]id");
}
?>
<?= $form->field($modelHouse, "[{$indexHouse}]description")->label(false)->textInput(['maxlength' => true]) ?>
</td>
<td>
<?= $this->render('_form-rooms', [
'form' => $form,
'indexHouse' => $indexHouse,
'modelsRoom' => $modelsRoom[$indexHouse],
]) ?>
</td>
<td class="text-center vcenter" style="width: 90px; verti">
<button type="button" class="remove-house btn btn-danger btn-xs"><span class="fa fa-minus"></span></button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php DynamicFormWidget::end(); ?>
<div class="form-group">
<?= Html::submitButton($modelPerson->isNewRecord ? 'Create' : 'Update', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
Source Code - View: _form-rooms.php
<?php
use yii\helpers\Html;
use wbraganca\dynamicform\DynamicFormWidget;
?>
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_inner',
'widgetBody' => '.container-rooms',
'widgetItem' => '.room-item',
'limit' => 4,
'min' => 1,
'insertButton' => '.add-room',
'deleteButton' => '.remove-room',
'model' => $modelsRoom[0],
'formId' => 'dynamic-form',
'formFields' => [
'description'
],
]); ?>
<table class="table table-bordered">
<thead>
<tr>
<th>Description</th>
<th class="text-center">
<button type="button" class="add-room btn btn-success btn-xs"><span class="glyphicon glyphicon-plus"></span></button>
</th>
</tr>
</thead>
<tbody class="container-rooms">
<?php foreach ($modelsRoom as $indexRoom => $modelRoom): ?>
<tr class="room-item">
<td class="vcenter">
<?php
// necessary for update action.
if (! $modelRoom->isNewRecord) {
echo Html::activeHiddenInput($modelRoom, "[{$indexHouse}][{$indexRoom}]id");
}
?>
<?= $form->field($modelRoom, "[{$indexHouse}][{$indexRoom}]description")->label(false)->textInput(['maxlength' => true]) ?>
</td>
<td class="text-center vcenter" style="width: 90px;">
<button type="button" class="remove-room btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus"></span></button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
Source Code - Controller
<?php
namespace app\modules\yii2extensions\controllers;
use Yii;
use yii\helpers\ArrayHelper;
use yii\web\NotFoundHttpException;
use yii\web\Response;
use yii\widgets\ActiveForm;
use app\base\Model;
use app\base\Controller;
use app\modules\yii2extensions\models\House;
use app\modules\yii2extensions\models\Person;
use app\modules\yii2extensions\models\Room;
use app\modules\yii2extensions\models\query\PersonQuery;
/**
* DynamicformDemo3Controller implements the CRUD actions for Person model.
*/
class DynamicformDemo3Controller extends Controller
{
/**
* Lists all Person models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new PersonQuery();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Person model.
* #param integer $id
* #return mixed
*/
public function actionView($id)
{
$model = $this->findModel($id);
$houses = $model->houses;
return $this->render('view', [
'model' => $model,
'houses' => $houses,
]);
}
/**
* Creates a new Person model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$modelPerson = new Person;
$modelsHouse = [new House];
$modelsRoom = [[new Room]];
if ($modelPerson->load(Yii::$app->request->post())) {
$modelsHouse = Model::createMultiple(House::classname());
Model::loadMultiple($modelsHouse, Yii::$app->request->post());
// validate person and houses models
$valid = $modelPerson->validate();
$valid = Model::validateMultiple($modelsHouse) && $valid;
if (isset($_POST['Room'][0][0])) {
foreach ($_POST['Room'] as $indexHouse => $rooms) {
foreach ($rooms as $indexRoom => $room) {
$data['Room'] = $room;
$modelRoom = new Room;
$modelRoom->load($data);
$modelsRoom[$indexHouse][$indexRoom] = $modelRoom;
$valid = $modelRoom->validate();
}
}
}
if ($valid) {
$transaction = Yii::$app->db->beginTransaction();
try {
if ($flag = $modelPerson->save(false)) {
foreach ($modelsHouse as $indexHouse => $modelHouse) {
if ($flag === false) {
break;
}
$modelHouse->person_id = $modelPerson->id;
if (!($flag = $modelHouse->save(false))) {
break;
}
if (isset($modelsRoom[$indexHouse]) && is_array($modelsRoom[$indexHouse])) {
foreach ($modelsRoom[$indexHouse] as $indexRoom => $modelRoom) {
$modelRoom->house_id = $modelHouse->id;
if (!($flag = $modelRoom->save(false))) {
break;
}
}
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $modelPerson->id]);
} else {
$transaction->rollBack();
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('create', [
'modelPerson' => $modelPerson,
'modelsHouse' => (empty($modelsHouse)) ? [new House] : $modelsHouse,
'modelsRoom' => (empty($modelsRoom)) ? [[new Room]] : $modelsRoom,
]);
}
/**
* Updates an existing Person model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$modelPerson = $this->findModel($id);
$modelsHouse = $modelPerson->houses;
$modelsRoom = [];
$oldRooms = [];
if (!empty($modelsHouse)) {
foreach ($modelsHouse as $indexHouse => $modelHouse) {
$rooms = $modelHouse->rooms;
$modelsRoom[$indexHouse] = $rooms;
$oldRooms = ArrayHelper::merge(ArrayHelper::index($rooms, 'id'), $oldRooms);
}
}
if ($modelPerson->load(Yii::$app->request->post())) {
// reset
$modelsRoom = [];
$oldHouseIDs = ArrayHelper::map($modelsHouse, 'id', 'id');
$modelsHouse = Model::createMultiple(House::classname(), $modelsHouse);
Model::loadMultiple($modelsHouse, Yii::$app->request->post());
$deletedHouseIDs = array_diff($oldHouseIDs, array_filter(ArrayHelper::map($modelsHouse, 'id', 'id')));
// validate person and houses models
$valid = $modelPerson->validate();
$valid = Model::validateMultiple($modelsHouse) && $valid;
$roomsIDs = [];
if (isset($_POST['Room'][0][0])) {
foreach ($_POST['Room'] as $indexHouse => $rooms) {
$roomsIDs = ArrayHelper::merge($roomsIDs, array_filter(ArrayHelper::getColumn($rooms, 'id')));
foreach ($rooms as $indexRoom => $room) {
$data['Room'] = $room;
$modelRoom = (isset($room['id']) && isset($oldRooms[$room['id']])) ? $oldRooms[$room['id']] : new Room;
$modelRoom->load($data);
$modelsRoom[$indexHouse][$indexRoom] = $modelRoom;
$valid = $modelRoom->validate();
}
}
}
$oldRoomsIDs = ArrayHelper::getColumn($oldRooms, 'id');
$deletedRoomsIDs = array_diff($oldRoomsIDs, $roomsIDs);
if ($valid) {
$transaction = Yii::$app->db->beginTransaction();
try {
if ($flag = $modelPerson->save(false)) {
if (! empty($deletedRoomsIDs)) {
Room::deleteAll(['id' => $deletedRoomsIDs]);
}
if (! empty($deletedHouseIDs)) {
House::deleteAll(['id' => $deletedHouseIDs]);
}
foreach ($modelsHouse as $indexHouse => $modelHouse) {
if ($flag === false) {
break;
}
$modelHouse->person_id = $modelPerson->id;
if (!($flag = $modelHouse->save(false))) {
break;
}
if (isset($modelsRoom[$indexHouse]) && is_array($modelsRoom[$indexHouse])) {
foreach ($modelsRoom[$indexHouse] as $indexRoom => $modelRoom) {
$modelRoom->house_id = $modelHouse->id;
if (!($flag = $modelRoom->save(false))) {
break;
}
}
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $modelPerson->id]);
} else {
$transaction->rollBack();
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('update', [
'modelPerson' => $modelPerson,
'modelsHouse' => (empty($modelsHouse)) ? [new House] : $modelsHouse,
'modelsRoom' => (empty($modelsRoom)) ? [[new Room]] : $modelsRoom
]);
}
/**
* Deletes an existing Person model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$model = $this->findModel($id);
$name = $model->first_name;
if ($model->delete()) {
Yii::$app->session->setFlash('success', 'Record <strong>"' . $name . '"</strong> deleted successfully.');
}
return $this->redirect(['index']);
}
/**
* Finds the Person model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Person the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Person::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
i´m not getting run my application, i select the city then i need that the dropdown show the NEIGHBORHOODS associated with the city....
this is my getNeighborhoods:
public function pegarBairros ($cidades = null) {
$this->layout = 'json';
$result = array();
debug($_REQUEST['cidade']);
if (in_array($_REQUEST['cidade'], array_keys($this->cidades))) {
$bairros = $this->Cep->find('list', array('fields' => array('id', 'bairro'), 'conditions' => array('uf_sigla' => 'sp', 'cidade' => $this->cidades[$_REQUEST['cidade']]), 'order' => 'bairro', 'group' => 'bairro'));
sort($bairros);
foreach ($bairros as $id => $bairro)
if (!empty($bairro)) $result[$id] = $bairro;
} else $result[] = 'error';
$this->set('data', $result);
}
and this is my ajax:
$('#ImovelCidade').change(function(e) {
$('#ImovelBairro').html($('<option />').val('').text('Carregando...'));
$.getJSON(
"<?php echo Router::url(array('controller' => 'pages', 'action' => 'pegarBairros')) ?>",
{ "cidade" : $(this).val() },
function (data) {
$('#ImovelBairro').html($('<option />').val('').text('Selecione'));
$.each(data, function (chave, valor) {
$('#ImovelBairro').append($('<option />').val(chave).text(valor));
} );
}
);
});
this ajax call the function getNeigh...
this is my select city:
echo $this->Form->input('cidade', array('label' => 'Cidade', 'empty' => 'Selecione uma cidade', 'options' => $Cidades));
my before filter that received city:
public function beforeFilter() {
$this->loadModel('Cidade');
$this->cidade = $this->Cidade->find('list', array ('fields' => array('id','nome')));
$this->set('Cidades',$this->cidade);