I'm using Yii2-advanced-app. I'm writing a function which takes 2 parameters using post method & displays result in a Gridview with pagination. The screen is like this -
The problem I'm facing with this is - When I click on the 'next page' button in pagination bar, it loads the function again & gives me the blank form again, instead of showing the 2nd page. It's like this - .
My function is this -
public function actionReportMisc()
{
$model = new BanksDetail();
if($model->load(Yii::$app->request->post())) {
if($model->Process_ID != '' && $model->Bank_ID != '') {
if($model->Process_ID == 1) {
$searchModel = new BanksDetailSearch();
$bank = Banks::find()->select('ID')->where(['Account_Number' => $model->Bank_ID])->one();
if(count($bank) == 1) {
$queryParams = array_merge(array(),Yii::$app->request->getQueryParams());
$queryParams["BanksDetailSearch"]["Bank_ID"] = $bank->ID;
$dataProvider = $searchModel->search($queryParams);
$dataProvider->pagination->pageSize = 3;
if(count($dataProvider) > 0) {
return $this->render('misc', ['model' => $model, 'searchModel' => $searchModel, 'dataProvider' => $dataProvider]);
}
} else {
throw new \yii\web\HttpException(404, 'The selected Account does not exist. Please ensure that you have entered right account no. for Bank/Cashbox.');
}
} else if($model->Process_ID == 2) {
$searchModel = new CashboxesDetailSearch();
$cbx = Cashboxes::find()->select('ID')->where(['Account_Code' => $model->Bank_ID])->one();
if(count($cbx) == 1) {
$queryParams = array_merge(array(),Yii::$app->request->getQueryParams());
$queryParams["CashboxesDetailSearch"]["CashBoxes_ID"] = $cbx->ID;
$dataProvider = $searchModel->search($queryParams);
if(count($dataProvider) > 0) {
return $this->render('misc', ['model' => $model, 'searchModel' => $searchModel, 'dataProvider' => $dataProvider]);
}
} else {
throw new \yii\web\HttpException(404, 'The selected Account does not exist. Please ensure that you have entered right account no. for Bank/Cashbox.');
}
}
}
} else {
return $this->render('misc', ['model' => $model]);
}
}
I understand that, when I click on 'next page button', the function again initializes the form with empty values & returns empty fom. But need a suggestion to get it done or an another way to do it easily. Thanks in advance.
I solved the resp. problem by using get() instead of post(). It was suitable for my scenario, because I get those parameters each time during pagination too. Thanks for your kind help.
Related
Theres the action
public function actionEfetuarPedidoReserva($idQuarto){
$modelPedidoReservaQuarto = new PedidoReservaQuarto();
$modelPedidoReserva = new PedidoReserva();
$model = new ComodidadesExtra();
$modelListaComodidades = new ListaComodidadesQuarto();
$modelPedidoReservaQuarto->quartoId = $idQuarto;
if($modelPedidoReservaQuarto->save()){
$modelPedidoReserva->nPessoas = 2;
$modelPedidoReserva->preco = 70.00;
$modelPedidoReserva->reservaQuartoId = $modelPedidoReservaQuarto->id;
$modelPedidoReserva->userInfoId = Yii::$app->user->id;
if($modelPedidoReserva->save()){
$model->pedidoReservaId = $modelPedidoReserva->id;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['efetuar-pedido-reserva', 'idQuarto' => $idQuarto]);
}
return $this->render('../comodidades-extra/create', [
'model' => $model, 'modelLista' => $modelListaComodidades
]);
}
}
}
When i refresh page, it add the last pedidoreservaid inserted + 1;
i Would like to know if am i doing it the right way.
Your problem is that you create new instance of ComodidadesExtra each time when you call $model = new ComodidadesExtra();. Yii2 consider it as new independent row and you need to tell Yii2 that you should take existing row instead, using:
$model = ComodidadesExtra::find()
->where(['pedidoReservaId' => $modelPedidoReserva->id])
->one();
And your controller should look like:
if($modelPedidoReserva->save()){
if(null===($model = ComodidadesExtra::find()->where(['pedidoReservaId' => $modelPedidoReserva->id])
->one())) {
$model = new ComodidadesExtra();
}
$model->pedidoReservaId = $modelPedidoReserva->id;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['efetuar-pedido-reserva', 'idQuarto' => $idQuarto]);
}
return $this->render('../comodidades-extra/create', [
'model' => $model, 'modelLista' => $modelListaComodidades
]);
}
I'm completely lost as to why this is happening, and it happens about 50% of the time.
I have a check to see if a user exists by email and last name, and if they do, run some code. If the user doesn't exist, then create the user, and then run some code.
I've done various testing with dummy data, and even if a user doesn't exist, it first creates them, but then runs the code in the "if" block.
Here's what I have.
if (User::existsByEmailAndLastName($params->email, $params->lastName)) {
var_dump('user already exists');
} else {
User::createNew($params);
var_dump("Creating a new user...");
}
And here are the respective methods:
public static function existsByEmailAndLastName($email, $lastName) {
return User::find()->where([
'email' => $email,
])->andWhere([
'last_name' => $lastName
])->one();
}
public static function createNew($params) {
$user = new User;
$user->first_name = $params->firstName;
$user->last_name = $params->lastName;
$user->email = $params->email;
$user->address = $params->address;
$user->address_2 = $params->address_2;
$user->city = $params->city;
$user->province = $params->province;
$user->country = $params->country;
$user->phone = $params->phone;
$user->postal_code = $params->postal_code;
return $user->insert();
}
I've tried flushing the cache. I've tried it with raw SQL queries using Yii::$app->db->createCommand(), but nothing seems to be working. I'm totally stumped.
Does anyone know why it would first create the user, and then do the check in the if statement?
Editing with controller code:
public function actionComplete()
{
if (Yii::$app->basket->isEmpty()) {
return $this->redirect('basket', 302);
}
$guest = Yii::$app->request->get('guest');
$params = new CompletePaymentForm;
$post = Yii::$app->request->post();
if ($this->userInfo || $guest) {
if ($params->load($post) && $params->validate()) {
if (!User::isEmailValid($params->email)) {
throw new UserException('Please provide a valid email.');
}
if (!User::existsByEmailAndLastName($params->email, $params->lastName)) {
User::createNew($params);
echo "creating new user";
} else {
echo "user already exists";
}
}
return $this->render('complete', [
'model' => $completeDonationForm
]);
}
return $this->render('complete-login-or-guest');
}
Here's the answer after multiple tries:
Passing an 'ajaxParam' parameters with the ActiveForm widget to define the name of the GET parameter that will be sent if the request is an ajax request. I named my parameter "ajax".
Here's what the beginning of the ActiveForm looks like:
$form = ActiveForm::begin([
'id' => 'complete-form',
'ajaxParam' => 'ajax'
])
And then I added this check in my controller:
if (Yii::$app->request->get('ajax') || Yii::$app->request->isAjax) {
return false;
}
It was an ajax issue, so thanks a bunch to Yupik for pointing me towards it (accepting his answer since it lead me here).
You can put validation like below in your model:
public function rules() { return [ [['email'], 'functionName'], [['lastname'], 'functionforlastName'], ];}
public function functionName($attribute, $params) {
$usercheck=User::find()->where(['email' => $email])->one();
if($usercheck)
{
$this->addError($attribute, 'Email already exists!');
}
}
and create/apply same function for lastname.
put in form fields email and lastname => ['enableAjaxValidation' => true]
In Create function in controller
use yii\web\Response;
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
else if ($model->load(Yii::$app->request->post()))
{
//place your code here
}
Add 'enableAjaxValidation' => false to your ActiveForm params in view. It happens because yii sends request to your action to validate this model, but it's not handled before your if statement.
I'm new to the Yii framework, and the situation confused me. I have a main form in a view that it has some validations. In addition, I have a gridview inside a modal in this view that it is hidden until the end user click a button in order to choose a field. The problem appeared just when the boss told me to have some search field in the modal (I decided to use filter in gridview for this purpose). After traces I've found that the reason was form validation of the first form when the filter method of gridview is trying to send GET request to the server to receive grid rows that related just with the filter parameters, But it's not working maybe the failure is about my understanding of MVC pattern.
Anyway this is some part of my codes:
View:
/* this section placed inside a modal div beside the main form*/
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'filterUrl' => Yii::$app->urlManager->createUrl('catm/grid'),
'rowOptions' => function ($model, $key, $index, $grid){
return ['onclick' => 'setText(\''. $model['name'] . '\');$(\'#myModal\').modal(\'hide\')',
'style' => 'cursor: pointer',
];
}
]);
Controller:
public function actionCreate()
{
$modelCatm = new Catm();
$modelApplication = new \app\models\Application();
$modelBranch = new \app\models\Branch();
$modelConfig = new \app\models\Config();
$modelMedia = new \app\models\Media();
$modelMessage = new \app\models\Message();
$modelServiceConfig = new \app\models\ServiceConfig();
$searchMdl = new BranchSearch();
$dataPrv = $searchMdl->search(Yii::$app->request->queryParams);
$webroot = Yii::$app->basePath;
if ($modelCatm->load(Yii::$app->request->post())){
//}
//print_r($_GET);
$transaction=Yii::$app->db->beginTransaction();
try {
//Branch:
$modelBranch->attributes = $_POST['Branch'];
//echo $modelBranch->attributes['name'];
if ($modelBranch->findBySql('select * from branch where name =\'' . $modelBranch->attributes['name'] . '\'')->count()==0) {
//echo 'not exists!';
if(!$modelBranch->save(false)) {echo 'error in model branch'; return 0;};
}
//Cashless ATM:
$modelCatm->attributes = $_POST['Catm'];
if(!$modelCatm->save(false)) {echo 'error in model catm'; return 0;};
//Application:
/* file upload handling and saving the path to database*/
$modelApplication->attributes = $_POST['Application'];
$modelApplication->catm_id = $modelCatm->id;
$modelApplication->file = UploadedFile::getInstanceByName('Application[file]');
//echo $modelApplication->file->baseName;
$modelApplication->validate();
$modelApplication->file->saveAs('uploads/application/' . $modelApplication->file->baseName . '.' . $modelApplication->file->extension);
$modelApplication->filepath = $webroot . '/uploads/application/' . $modelApplication->file->name;
if(!$modelApplication->save(false)) {echo 'error in model application'; return 0;};
//Media:
/* file upload handling and saving the path to database*/
$modelMedia->attributes = $_POST['Media'];
$modelMedia->catm_id = $modelCatm->id;
$modelMedia->file = UploadedFile::getInstanceByName('Media[file]');
//echo $modelMedia->file->baseName;
$modelMedia->validate();
$modelMedia->file->saveAs('uploads/media/' . $modelMedia->file->baseName . '.' . $modelMedia->file->extension);
$modelMedia->filepath = $webroot . '/uploads/media/' . $modelMedia->file->name;
if(!$modelMedia->save(false)) {echo 'error in model media'; return 0;};
//Messages:
$modelMessage->attributes = $_POST['Message'];
$modelMessage->catm_id = $modelCatm->id;
if(!$modelMessage->save()) {echo 'error in model message'; return 0;};
$transaction->commit();
} catch (Exception $ex) {
$transaction->rollback();
}
return $this->render('view',[
'modelCatm' => $modelCatm,
'modelBranch' => $modelBranch,
'modelApplication' => $modelApplication,
'modelConfig' => $modelConfig,
'modelMedia' => $modelMedia,
'modelMessage' => $modelMessage,
'modelServiceConfig' => $modelServiceConfig,
]);
} else {
return $this->render('create', [
'modelCatm' => $modelCatm,
'modelBranch' => $modelBranch,
'modelApplication' => $modelApplication,
'modelConfig' => $modelConfig,
'modelMedia' => $modelMedia,
'modelMessage' => $modelMessage,
'modelServiceConfig' => $modelServiceConfig,
'searchModel' => $searchMdl,
'dataProvider' => $dataPrv,
]);
}
}
I will update the question with more information of my code after your helpful comments if it is required.
It has nothing to do with your understanding of MVC mate, Yii does a lot of things for you automatically but sometimes in cases like this you just need to get to do some things by hand.
Probably you need to change the form action in your controller to check if this is a form submission or a gridview navigation / filter and handle it differently. You need to check if some get params exist and bypass the form validation in that case.
I am using yii2 advanced template improved
Not sure if relevant to problem/a solution but to get to the category I have a form with some javascript which on change redirects the user to the category selected.
I have the following code which allows me to access the posts within that category id I go to localhost:8888/advanced/article/category?id=1
The problem at the minute is that if I call getCategoryName function in my model from my category view the id parameter isn't being passed to the model function therefore when using getCategoryName defaults to sport.
public function actionCategory($id)
{
$model = new Article();
$searchModel = new ArticleSearch();
$query = Article::find()
->where(['category' => $id]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
return $this->render('category', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model'=>$model,
]);
}
Then within my view I use the following which works to an extent in terms of executing the model function, however I am unsure on how to pass the parameter/current category id to the model function. The below code work for the _index & in the single article view.
<?= $model->CategoryName ?>
This is my model function
public function getCategoryName($category = null)
{
$category = (empty($category)) ? $this->category : $category ;
if ($category === self::CATEGORY_ECONOMY)
{
return Yii::t('app', 'Economy');
}
elseif ($category === self::CATEGORY_SOCIETY)
{
return Yii::t('app', 'Society');
}
else
{
return Yii::t('app', 'Sport');
}
}
Use something like this, in your view
$request = Yii::$app->request;
$id = $request->get('id');//get id from request or change according to your requirement
echo $model->getCategoryName($id);//full method name here
Try to use this. change === to ==:
public function getCategoryName($category = null)
{
$category = (empty($category)) ? $this->category : $category ;
if ($category == self::CATEGORY_ECONOMY)
{
return Yii::t('app', 'Economy');
}
elseif ($category == self::CATEGORY_SOCIETY)
{
return Yii::t('app', 'Society');
}
else
{
return Yii::t('app', 'Sport');
}
}
I want to add form validation if the ip_address duplicated just
stay on current page or show me any kind of message.
this is the model code
public function add_vote($option_id)
{
$this->db->insert($this->votes_table, array(
'option_id' => $option_id,
'ip_address' => $this->input->ip_address(),
'timestamp' => time()
));
return ($this->db->affected_rows() == 1) ? TRUE : FALSE;
}
this is the controler
public function vote($poll_id, $option_id)
{
if ( ! $this->poll_lib->vote($poll_id, $option_id))
{
$data['base_styles'] = 'public_html/res/css/base.css';
$data['title'] = 'Sorry an error occured';
$data['error_message'] = $this->poll_lib->get_errors();
$this->load->view('header');
$this->load->view('www/posts/postclose', $data);
}
else
{
redirect('posts', 'refresh');
}
}
hear if i add new vote it's shows me database error as the column is duplicate so i don't want to show that, if it redirect me to any other page will be great if stay on current page still ok or any pop up message.
Do a check before inserting into database.
public function add_vote($option_id)
{
$query = $this->db->get_where($this->votes_table, array('ip_address' => $this->input->ip_address()));
if($query->num_rows() < 1)
{ $this->db->insert($this->votes_table, array(
'option_id' => $option_id,
'ip_address' => $this->input->ip_address(),
'timestamp' => time()
));
return "Successfully Inserted";
}else{
return "Duplicate";
}
}
In your controller handle the response and display accordingly