This is my first time using Yii2 so i am confused on how it works. I have this card page in my views/people/card.php .However i can only access the page through web/people/card. Why?
I am able to link the button in card.php to _card.php (without changing the url) using controller but how do i link my button in _card.php to _data.php?
My controller
public function actionCard()
{
$dataProvider = new ActiveDataProvider([
'query' => People::find(),
]);
$model = '';
if (Yii::$app->request->post() && isset($_POST['card'])) {
if(isset($_POST['selection'])){
$model = People::find()->select('id, name, ic')->where(['id' => $_POST['selection']])->all();
$content = $this->renderPartial('_card',['model'=>$model]);
$selection = implode(',', $_POST['selection']);
}
return $this->render('_design', [
'dataProvider' => $dataProvider,
'model' => $model,
]);
}
First You can only access the page through web/people/card. because this is the route managed by yii (is one of the possibile routing way you can see more in this guide
Second how do you link button in _card.php to _data.php? (in another controller)
also for this you can do using the routing rules above. In this case you should add the controller name to the route(controller/view) eg:
$content = $this->renderPartial('data/_data',['model'=>$model]);
but remember is not a good practice to use view from different controller.
Related
Today I face a strange problem (as I face this first time so it is a strange problem for me). After saving the content of a model I just write the following line of code return route('organization'); so that it will redirect to the naming route organization after saving the content.
Once the content of the organization model saves it just print the URL of the page http//xyz.laravel/organization rather than printing the content of the page itself!
When I manually type and hit the dashboard URL it surprisingly prints the dashboard URL rather than loading the dashboard content! like the below image:
Everything was working fine before I tried to store the content of that model. Once the content is stored the application starts strange behavior. Here is the code of that model:
public function store(Request $request)
{
$validated = $request->validate([
'organization_name' => 'required|unique:organizations|max:255',
'abn_number' => 'required',
'address_one' => 'required|max:100',
'state' => 'required',
'post_code' => 'required'
]);
// check organization exist or not
$org = Organization::where('organization_name', $request->organization_name)->get();
if( count( $org ) > 0 ) {
//
} else {
$organization = new Organization();
$organization->organization_name = $request->organization_name;
$organization->abn_number = $request->abn_number;
$organization->address_one = $request->address_one;
$organization->address_two = $request->address_two;
$organization->state = $request->state;
$organization->post_code = $request->post_code;
$organization->created_by = Auth::user()->id;
$organization->created_at = Carbon::now();
$organization->save();
return route('organization');
}
}
Can anyone tell me what's actually happen and how can I fix this issue?
return route('organization'); will generate the URL link to the route and print it
You can use
return redirect()->route('organization);
You can get more info from https://laravel.com/docs/8.x/redirects
This is because you are not redirecting to that route but you are returning route url as a string, to redirect a user to a named route you can use global redirect() helper as below
return redirect()->route('organization'); instead of return route('organization');
for more see
documentation
I have several contact forms through my site. The main one (from the "Contact" section) works through an action in my "Clients" controller, and I have several other forms in other pages (in views from other controllers, where I send the form to the main controller's action and then redirect to the original form), and everything works just fine. The email notifications are being sent and the records are being saved into my database.
The problem came after I implemented a Recaptcha plugin. The plugin works correctly (as in "if you check the recaptcha, it works as intended; if you don't, it displays an error message"), but when I'm using the "secondary" forms, instead of redirecting back to the original starting page, it always redirects me to the page for the main controller's action (and I loose the info at the hidden fields where I'm registering the specific form the client is currently using).
I tried deactivating the redirect, but that doesn't work. The user is still "brought" to the main controller's page.
Then I searched (in google and stack overflow) for some solution, and in a similar question there was the answer "save your current url into a session and load it for the redirection", and it made sense.
However, when I tried saving it I found out the session is being saved after the process starts, so my session is saving the url after it jumps to the main action, instead of before submitting the form.
I tried saving the session in beforeFilter and beforeRender, and it still didn't work.
What can I do to save the url in the session before the form is submitted to the main action?
My main controller's action:
class ClientsController extends AppController
{
public function beforeFilter(\Cake\Event\Event $event)
{
parent::beforeFilter($event);
$route = $this->request->getParam('_matchedRoute');
$session = $this->request->getSession()->write('Origin',$route);
}
public function contact()
{
$cliente = $this->Clients->newEntity();
if ($this->request->is('post')) {
if ($this->Recaptcha->verify()) {
// Verify recaptcha
$client = $this->Clients->patchEntity($client, $this->request->getData());
if ($this->Clients->save($client)) {
$email = new Email();
$email->setProfile('default');
$email->setFrom($client->email)
->to('contact#server.com')
->setSubject('Contact form sent from: ' . $client->source)
->setEmailFormat('both')
->setViewVars([
'source' => $client->source,
'name' => $client->first_name . ' ' . $cliente->last_name,
'company' => $client->company,
'localphone' => $client->local_phone,
'email' => $client->email,
'comments' => $client->comments
])
->viewBuilder()->setTemplate('default','default');
$email->send([$client->comments]);
$this->Flash->success('Youyr message has been sent. We'll contact you soon!');
$this->redirect($this->referer());
} else {
$this->Flash->error('There was a problem with your Contact form. Please, try again!');
}
} else {
// user failed to solve the captcha
$this->Flash->error('Please, check the Google Recaptcha before proceeding.');
$this->redirect($this->request->getSession()->read('Origin'));
}
}
}
}
(The recaptcha plugin is loaded at my AppController's Initialize.)
And as an example, one of the forms in another controller's view where I'm calling the main controller's action:
<?= $this->Form->create('client',['url' => ['controller' => 'clients','action' => 'contact']]); ?>
<?= $this->Form->hidden('source',['value' => 'Product page']) ?>
<?= $this->Form->control('first_name', ['label' => 'First name:','required' => true]) ?>
<?= $this->Form->control('last_name', ['label' => 'Last name:','required' => true]) ?>
<?= $this->Form->control('email', ['label' => 'Email:','required' => true]) ?>
<?= $this->Form->control('local_phone', ['label' => 'Local phone:','maxlength' => 10,'required' => true]) ?>
<?= $this->Form->control('comments', ['label' => 'Comentarios:', 'rows' => 3]) ?>
<?= $this->Recaptcha->display(); ?>
<?= $this->Form->button('Send') ?>
<?= $this->Form->end(); ?>
You could use JavaScript on the frontend to add an event listener to hook the form submit button click.
In your event listener, save the current URL of the window to sessionStorage in the browser.
Then let the submit click event pass to the default action.
This solution will store the URL before it is changed to have the form field contents added to it.
For future visitors, this solution involves use of the following JavasCript concepts which the OP is already across but can be researched seperately:
add event listener
action = 'click'
window.href
sessionStorage
allow default
You could set the object your are listening to (the form submit button) in a number of ways. I usually give it an ID and specify the element using document.getElementById
More info:
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
https://www.w3schools.com/JSREF/prop_win_sessionstorage.asp
I'm using Yii2 and I want to create a web application with the ability to perform fast searches.
For example, when I type characters in a textbox, results displayed.
It's easy with ajax when we have only one language but how about in multilingual mode?
First set up multi language for your site there is doc for this.
Best way of auto support multi language for your site is using cookies variable for language. You can set up language cookies from any action as
public function actionLanguage()
{
if (isset($_POST['lang'])) {
$language = $_POST['lang'];
if (($langaugeModel = \app\models\Langauge::findOne(['name' => $language])) !== null) {
$varLang = [
'id' => $langaugeModel->id,
'name' => $langaugeModel->name,
'iso1' => $langaugeModel->iso1,
'iso2' => $langaugeModel->iso2
];
$cookies = new Cookie([
'name' => 'lang',
'value' => json_encode($varLang),
]);
yii::$app->getResponse()->getCookies()->add($cookies);
return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null));
} else {
throw new NotFoundHttpException('The requested langauge does not exist.');
}
} else {
return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null));
}
}
Here what I did was i placed all the language support of site in database and generate necessary cookies variable and placed it on client browser.
Next set up be before request event of your yii2 site in config/web.php file as
'as beforeRequest' => [
'class' => 'app\components\MyBehavior',
],
then create components\Mybehaviou.php file and place this code
namespace app\components;
use yii;
use yii\base\Behavior;
class MyBehavior extends Behavior
{
public function events(){
return [
\yii\web\Application::EVENT_BEFORE_REQUEST => 'myBehavior',
];
}
public function myBehavior(){
if (\yii::$app->getRequest()->getCookies()->has('lang')) {
$langIso = 'sdn';
\yii::$app->language = $langIso;
$langaugeVar = \yii::$app->getRequest()->getCookies()->getValue('lang');
$langauge = json_decode($langaugeVar);
$langIso = $langauge->iso2;
\yii::$app->language = $langIso;
}
}
}
This create your site language which depends on client because it depends on cookies of client.
Then create your search controller according to site language(\yii::$app->language)
for ajax search you can use select2 Widget. you can find demo and configuration on this link
I wanna ask about my problem. Before it I wanna tell you what I do, I have RenunganHarianController and I made actionIndex like this. I wanna render the non-logged-in user to login form
public function actionIndex()
{
$model = new LoginForm();
//check user Guest or not
if(Yii::$app->user->isGuest) {
return $this->render('/site/login', [
'model' => $model,
]);
}
$searchModel = new RenunganHarianSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
It's work, but when I try login from 'LoginForm' that rendered from that controller, I can't be logged in but if I try login from normal way, I can do that. Please help me, thank you
I am guessing that in your site/login view you have an ActiveForm with no specific action. If that is so, then the form's action is the same url that has been called, in your case yourcontroller/index (the actionIndex you have posted). The problem is that you have no logic in that action to handle te login process, which I guess is in your SiteController, actionLogin. You have two options here:
Redirect the user to site/login insted of rendering the view in your actionIndex
In your site/login view, specify the action for the form as Url::to('/site/login')
And yes, please, as suggested do not use capital letters as you did in the title.
I have two controllers, homepage and Security.
In the homepage, I am displaying one view and in the security, I am doing some things, and one of them is the email address validation.
What I would like is that when the email validation code is not valid, display the homepage with a flash message. For that, I will have to render the indexAction of the HomepageController, from the Security controller, by giving him as parameter the flash message.
How can this be done? Can I render a route or an action from another controleller?
Thank you in advance.
I believe the checking should not be done in the Security controller. Right place in my opinion is a separate validator service or right in the entity which uses the email address.
But to your question, you can call another controller's action with $this->forward() method:
public function indexAction($name)
{
$response = $this->forward('AcmeHelloBundle:Hello:fancy', array(
'name' => $name,
'color' => 'green',
));
return $response;
}
The sample comes from symfony2 documentation on: http://symfony.com/doc/2.0/book/controller.html#forwarding
I have found the solution, simply use the forward function by specifying the controller and the action nanme:
return $this->forward('MerrinMainBundle:Homepage:Index', array('flash_message'=>$flash_message));
redirectToRoute : Just a recap with current symfony versions (as of 2016/11/25 with v2.3+)
public function genericAction(Request $request)
{
if ($this->evalSomething())
{
$request->getSession()->getFlashBag()
->add('warning', 'some.flash.message');
$response = $this->redirectToRoute('app_index', [
'flash_message' => $request->getSession()->getFlashBag(),
]);
} else {
//... other logic
}
return $response;
}