How to pass id from "input select" to its action? - php

Hello guys let me explain:
$this->view->form = new Application_Form_Kursdaty();
$url = $this->view->url(
array(
'action' => 'details',
'controller' => $this->getRequest()->getControllerName(),
'module' => $this->getRequest()->getModuleName(),
'id' => #####SELECTFIELD[selected]######
),
'default',
true
);
$this->view->form->setAction($url);
I basically want my select field to redirect to page which i choose.
I dont really know what to do, please help!

If your form is instance of Zend_Form and populated with sent data then you can use $form->getValue($nameOfField) or $form->getElement($elementName)->getValue()

Here's your problem!
The value of the select element is not set until after the submit button is pressed. So you don't have access to the value until after the post.
So a way to do what you want to do in PHP would be to use 2 actions. The first action takes the post and performs the validation then you could take the data and forward it to the action of your choice depending on the value of that select.
public function formAction() {
$form = new Form();
$form->setAction('/url');
if ($this->_request->isPost()){
if ($form->isValid($this->_request->getPost()){
$select = $form->getValue('select');
switch($select) {
case ('value1') :
$this->_forward('action');
break;
case ('value2') :
$this->_forward('action');
break;
default :
$this->_forward('action');
}
}
} else {
$this->view->form = $form
}
This might be the kind of work flow you would look at for the first action. You'll need to work out the details but a _forward should be doable in this instance as it should perform the redirect without losing the current request object.

Related

Validate field in form - check if "product" exists in CakePhp 3

I've got problem with field validation.
I would like to validate form through model. I want to check if field with some value exists.
I would like to block using some titles more than once.
For example
if field "Site" with title "Main" exists in database, you can't validate form.
If it doesn't exist, you can pass it.
I would like to allow user to add just one "Site" with title "Main", but he can add "Site" with any other title in any case.
Have you got some idea how to solve it?
I think you have two options.
(1) Setup an Ajax request to the server.
To do so:
Create a function, that responds to an Ajax request, in your SiteController named checkName()
public function checkName($name) {
// allow ajax requests
$this->request->allowMethod(['ajax']);
// perform your check within the db
$isExistent = [...];
// prepare the response
$response = ['name' => $name, 'isExistent' => $isExistent];
if ($this->request->isAjax()){
$this->autoRender = false;
$this->response->disableCache();
$this->response->type(['json' => 'application/json']);
$this->response->body(json_encode($response));
}
}
Add the route to your routes file with the option '_ext' => 'json'
Prepare your Javascript Ajax function that call the route you have defined and attach it on the onchange attribute of your input field. (see this link for a simple example: http://www.w3schools.com/jquery/ajax_ajax.asp)
(2) Make the 'name' field of the Site table unique.
To do so you could add the following function to your SiteTable class
public function buildRules(
RulesChecker $rules
) {
$rules->add($rules->isUnique(['name']));
return $rules;
}

Yii2:redirect to specific action from submit button

I am not able to redirect a custom form to specific action.
What I am trying is
<?= Html::submitButton( 'delete-selected' ,['class' => 'btn btn-primary']) ?>
here delete-selected is my custom action in controller appointment.
I have also tried like this:
public function actionDeleteForm()
{
return $this->render('delete');
return $this->redirect(['delete-selected']);
}
public function actionDeleteSelected()
{
Appointment::deleteAll(['doctor_name' =>4]);
return $this->redirect(['index']);
}
What I am trying to do is actually delete some records using the form. The form name is delete having a select drop-down field.
I want to post the data to action deleteselected and use the $_POST variable in the delete query.
How can I do this?
Thanks.
Any submit button that you put on your form will submit to the url specified in the action parameter of the form. If you haven't specified one, then Yii will use the current controller/action of the form. If you want to override this behavior, then you will need to specify an action for the form. e.g.
$form = ActiveForm::begin([
'action' => 'appointment/delete-selected'
]);
in actionDeleteForm you have
return $this->render('delete');
before
return $this->redirect(['delete-selected'])
this second instruction will never be executed because you have already made a return to the function and then control has already been returned to the caller
This is somewhat a note for Joe Miller's answer. If you are supposed to override the form's action with an action of a controller, make sure you make the value of 'action' as an array:
$form = ActiveForm::begin([
'action' => ['appointment/delete-selected']
]);
It will treat the action as a route to action delete-selected in controller appointment.

CakePHP prepopulate form with data from a link

Assume I'm in my items controller.
Ok say I am in my view action (the url would be something like /items/view/10012?date=2013-09-30) which lists a list of items that belongs to a client on a given date.
I want to link to add a new item. I would use the htmlhelper like so:
echo $this->Html('action'=>'add');
In my add action I have a form which has fields like client_id and item_date.
When I'm in my view action I know these values as I am viewing the items for a specific client on a specific date. I want to pass these variables to my add action so it will prefill those fields on the form.
If I add a query string in my link ('?' => array('client_id'=>$client_id)) it breaks the add action as it will give an error if the request is not POST. If I use a form->postLink I get another error as the add action's POST data must only be used for adding the record, not passing data to prefill the form.
I basically want to make my link on the view page pass those 2 variables to the add action in the controller so I can define some variables to prefill the form. Is there a way to do this?
Here is my add controller code. It may differ in content a bit from my question above as I have tried to simplify the question a bit but the concept should still apply.
public function add(){
if ($this->request->is('post')) {
$this->Holding->create();
if ($this->Holding->save($this->request->data)) {
$this->Session->setFlash(__('Holding has been saved.'), 'default', array('class' => 'alert alert-success'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Unable to add your holding.'), 'default', array('class' => 'alert alert-danger'));
}
$this->set('accounts', $this->Holding->Account->find('list'));
$sedol_list = $this->Holding->Sedol->find('all', array(
'fields' => array(
'id', 'sedol_description'
),
'recursive' => 0,
'order' => 'description'
)
);
$this->set('sedols', Hash::combine($sedol_list, '{n}.Sedol.id', '{n}.Sedol.sedol_description') );
}
Why not use proper Cake URL parameters?
echo $this->Html->link('Add Item', array(
'action' => 'add',
$client_id,
$item_date
));
This will give you a much nicer URL like:
http://www.example.com/items/add/10012/2013-09-30
And then in your controller, you modify the function to receive those parameters:
public function add($client_id, $item_date) {
// Prefill the form on this page by manually setting the values
// in the request data array. This is what Cake uses to populate
// the form inputs on your page.
if (empty($this->request->data)) {
$this->request->data['Item']['client_id'] = $client_id;
$this->request->data['Item']['item_date'] = $item_date;
} else {
// In here process the form data normally from when the
// user has submitted it themselves...
}
}

cakePHP pagination and passedArgs

I am trying to build in a "search" box on a results page in my cakephp app. The page uses the cakePHP pagination component to show and "page" results. This is perfect, but I am having difficulties to get the next part to work.
The desired outcome:
A cakephp form (post) with an input box and a couple of select boxes, including a date selector so that I can select between dates. The user should be able to populate these fields and submit
On submit, the user selection should change the cakePHP pagination conditions in the controller
In the view I want the pagination bar to keep record of the user selection, so that when I filter through different pages, it keeps the users search. I understand this can be achieved using $this->passedArgs, hence why I am using post and not get.
The code:
// Form:
<?php
echo $this->Form->create('search', array('class' => false));
echo $this->Form->input('searchFor');
echo $this->Form->input('dateFrom');
echo $this->Form->input('dateTo');
echo $this->Form->end();
?>
// Controller:
if($this->request->is("post")) {
$filters = $this->request->data["search"];
$this->passedArgs["searchFor"] = $filters["searchFor"];
$this->passedArgs["dateFrom"] = $filters["dateFrom"]." 00:00:00";
$this->passedArgs["dateTo"] = $filters["dateTo"]." 00:00:00";
// Assign search parameters:
if($this->passedArgs["searchFor"] != "") {
$conditions["Model.field LIKE"] = "%".$this->passedArgs["searchFor"]."%";
}
$conditions["Model.created >="] = $this->passedArgs["dateFrom"];
$conditions["Model.created <="] = $this->passedArgs["dateTo"];
} else {
$conditions = array("Result.status_id >=" => 12);
}
$this->paginate = array(
'conditions' => $conditions,
'order' => array('Result.created ASC'),
'limit' => 20
);
$this->set("results",$this->paginate("Model");
// The view file:
<?php
$this->Paginator->options(array('url' => $this->passedArgs));
?>
Where I am now:
The initial page loads with all of the results
When I populate the search boxes it does return my results
The problem:
I am convinced the way I am doing it is incorrect as I now need to do 2 checks, a) being if results has been posted and b) check if there is passedArgs available. I am 100% convinced this is not the right way of doing it.
Let's say I have 2 free form fields for search, say name and surname, if I leave surname blank my url would be written as below, and this does not look or appear to be correct. That means I have to assign default values to ensure the items below does not happen, which does not appear to be very dynamic.
http://localhost/site/controller/action/surname:0/name:John/date:0/
On refresh it says the page does not exist because the posted values is not available anylonger.
usually I proceed like this in the controller:
//transform POST into GET
if($this->request->is("post")) {
$url = array('action'=>'index');
$filters = array();
if(isset($this->data['searchFor']) && $this->data['searchFor']){
//maybe clean up user input here??? or urlencode??
$filters['searchFor'] = $this->data['searchFor'];
}
//redirect user to the index page including the selected filters
$this->redirect(array_merge($url,$filters));
}
$conditions = array();
//check filters on passedArgs
if(isset($this->passedArgs["searchFor"])){
$conditions["Model.field LIKE"] = "%".$this->passedArgs["searchFor"]."%";
}
//paginate as normal
$this->paginate = array(
'conditions' => $conditions,
'order' => array('Result.created ASC'),
'limit' => 20
);
The idea is to transform the POST sent by your form into GET. so you wont have problems with the paginator nor the refresh
Hope this helps
What you want can be done a lot more simple and DRY by using this search plugin.
It automates what you want more or less plus it already can do more than your code.
So I suggest you to use the plugin directly or take a look at it how it does the trick. :)

Zend Framework: Can I use an add view script for editing too?

I have a simple Zend Framework that has a view script to add records to the database. This is a silly question IMHO, but how can I use the add view script to edit the record as well??
I have played around with a few scenarios to no avail.
Thanks,
Steve
Per Matt S' comment, the method you're looking for is Zend_Form::populate(). There are some notes about it in the documentation: Populating and Retrieving Values.
Basically, you use it like this in the controller:
$form = new Form_Person();
// get the data from somewhere
if($id = $this->getRequest()->getParam('id') && $model->find($id)) {
// really, use data from the model here
// but the populate() -method can take any array as an argument
$form->populate(array(
'name' => 'Dolph',
'age' => '52'
));
}
$this->view->form = $form;
and in your view, as usual:
<?= $this->form ?>
So the array could be for example the result of Zend_Db_Table_Row_Abstract::toArray() with column names matching to the names you gave the form elements.

Categories