I don't want to use the FormHelper from CakePHP, because I want to use some Ajax in my app.
How can I pass the data from the form to the Controller? I'm using $.post from jQuery but I always get an error.
Thanks!
You can use Ajax with the CakePHP Form Helper.
In your view file .ctp put:
echo $this->Form->create('Model', array('id'=>'YourFormId', array('default'=>false)));
echo $this->Form->input('field');
echo $this->Form->submit('Save');
echo $this->Form-->end
Notice in your form->create your passing a default=>false which tells the form to not do a normal "Submit".
At the bottom of your view file .ctp put:
$data = $this->Js->get('#YourFormId')->serializeForm(array('isForm' => true, 'inline' => true));
$this->Js->get('#YourFormId')->event(
'submit',
$this->Js->request(
array('action' => 'yourAction', 'controller' => 'yourController'),
array(
'update' => '#flash',
'data' => $data,
'async' => true,
'dataExpression'=>true,
'method' => 'POST'
)
)
);
echo $this->Js->writeBuffer();
The above is CakePHP JS helper to help you write Ajax and Javascript which PHP. It basically grabs the form data that is being submitted and serializes it and passed it to /yourcontroller/youraction via ajax. The update=>#flash is telling Cake to Update the #flash div after the action is done.
Remember in your Controller to have public
public $helpers = array('Js');
public $components = array('RequestHandler');
-- jQuery --
$.post('<?=$this->Html->url(array('controller'=>'xxx','action'=>'yyy'))?>', {a:1,b:2});
-- cakePHP --
function yyy() {
$a = $this->request->data['a'];
$b = $this->request->data['b'];
}
Related
For example we have this ActiveForm implementation in a sample view:
<?php $form = ActiveForm::begin(); ?>
<?=$form->field($model, 'first_name')->textInput(['maxlength' => true]); ?>
<?=$form->field($model, 'last_name')->textInput(['maxlength' => true]); ?>
<div id="additional-form-fields"></div>
<a href="#" id="load-additional-form-fields">
Load more fields
</a>
<?php ActiveForm::end(); ?>
Now, I want to add more ActiveField / ActiveForm fields inside this form and place them in the #additional-form-fields element with Ajax, I'd do a simple jQuery callback:
$('#load-additional-form-fields').click(function() {
$.get('/site/additional-fields', {}, function(data) {
$('#additional-form-fields').html( data );
});
});
And the action additional-fields inside SiteController would be something as:
public function actionAdditionalFields() {
$model = new User;
return $this->renderAjax('additional-fields', [
'model' => $model,
// I could pass a 'form' => new ActiveForm, here, but it's a big NO-NO!
]);
}
And this works perfectly, only if I don't use any other ActiveField fields inside this action's view:
<?=$form->field($model, 'biography')->textInput(['maxlength' => true]); ?>
<?=$form->field($model, 'country')->textInput(['maxlength' => true]); ?>
<?=$form->field($model, 'occupation')->textInput(['maxlength' => true]); ?>
Of course, I have to pass or instatiate $form somehow in this view, but it's NOT an option to use another ActiveForm::begin() / ActiveForm::end() anywhere inside this view since it will create another <form> tag and thus when I inject the Ajax response, I'll end up with with a <form> inside a <form> ...
Now, my question is as follows: Since I want to use ActiveForm, how can I share an instance of the ActiveForm through out multiple requests?
Is it doable / possible, if so, please help me realize how?
So far I have tried to put $form inside a session, but that's definitelly not working and not an option. Different than that, I've tried when passing parameters to renderAjax:
[
'model' => $model,
'form' => new ActiveForm,
]
In this case I get the following:
Form fields are created as they should with appopriate names and id's.
jQuery is loaded again (at the bottom of the response: <script src="..."> ... you get the idea)
I don't get the generated JavaScript for validation.
Is there anyway to share an instance of $form?
Okay, I have manage to do this, so I'll post the solution here and I'll open an issue on Github - might be useful in future versions.
1. Updates in yii2\widgets\ActiveForm.php
I've added a following property to the ActiveForm class:
/**
* #var boolean whether to echo the form tag or not
*/
public $withFormTag = true;
And I've changed run() method into this (check for // <-- added):
public function run()
{
if (!empty($this->_fields)) {
throw new InvalidCallException('Each beginField() should have a matching endField() call.');
}
$content = ob_get_clean();
if($this->withFormTag) { // <-- added
echo Html::beginForm($this->action, $this->method, $this->options);
} // <-- added
echo $content;
if ($this->enableClientScript) {
$id = $this->options['id'];
$options = Json::htmlEncode($this->getClientOptions());
$attributes = Json::htmlEncode($this->attributes);
$view = $this->getView();
ActiveFormAsset::register($view);
$view->registerJs("jQuery('#$id').yiiActiveForm($attributes, $options);");
}
if($this->withFormTag) { // <-- added
echo Html::endForm();
} // <-- added
}
Thus if we instantiate a form like this:
$form = ActiveForm::begin([
'withFormTag' => false,
]);
It will not echo a <form> tag, but will render all ActiveField items and it will create their respective JavaScript/jQuery validators if $this->enableClientScript = true;.
2. Updates in my local view/file
After applying the previous fix in the base class, I needed to do the following in my view:
<?php $form = ActiveForm::begin([
'withFormTag' => false,
'id' => 'w0',
]); ?>
I had to pass the id parameter since every next instance of the ActiveForm class is incremented by 1, and I want my JavaScript/jQuery validators to be applied to the parent form, which by default starts from 0 -> w0.
And this is what did the trick!
Here's the Github issue as well: https://github.com/yiisoft/yii2/issues/12973
I am very new to Symfony, so question might seem a little simple, but I need a help.
I have generated new bundle.
I have added a new route in Me\MyBundle\Resources\config\routing.yml:
my_homepage:
pattern: /
defaults: { _controller: MeMyBundle:Default:index }
Bundle controller looks in simple like this:
namespace Me\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
$form = $this->createFormBuilder()
->getForm()
;
return $this->render('MeMyBundle::index.html.twig', array(
'form' => $form->createView(),
'param1' => 'some_string_1',
'param2' => 'another string',
));
}
}
In the twig template I can read and process proper params, as I want.
Whole action happens in the generated form, where there are AJAX requests routed to another controller.
What I want to achieve is create a new custom form field, which could be reued in same form multiple times, with different params.
For example, I would like my indexAction() would have looked like this:
public function indexAction()
{
$paramsArr_1 = array(
'param1' => 'some_string_1',
'param2' => 'another string',
);
$paramsArr_2 = array(
'param1' => 'some_string_2',
'param2' => 'another fine string',
);
$form = $this->createFormBuilder()
->add(myCustomField, $paramsArr_1)
->add(myCustomField_2, $paramsArr_2)
->getForm()
;
return $this->render('MeMyBundle::index.html.twig', array(
'form' => $form->createView()
));
}
Yes, I did see this article, but it did not help me much. I could not get it working.
Any help is much appreciated.
From what I know form fields extends the base form class, so your 'myCustomField' can be another form actually.
Check this: http://symfony.com/doc/current/reference/forms/types/form.html
As you know each Form object has attached an object to it, so instead of your arrays you could create a new object with those values set on it, and then add that form how many times your want with objects containing different data.
can i pass form dropdown value in my controller and after this, i can send the value in my DB table....please help me i m new in cakephp here is my job_content.ctp
echo'<div class="AcceptButtonFormData">';
echo $this->Form->create('Job' ,array('action' => 'view'));
$ipr_value=array('0'=>0.0,'1'=>.1,'2'=>.2,'3'=>.3);
echo $this->Form->input('IPR_teeth_pair12',array('type' => 'select','name'=>'drop12', 'options' => $ipr_value,'default'=>0));
echo $this->Form->input('IPR_teeth_pair23',array('type' => 'select','name'=>'drop23', 'options' => $ipr_value,'default'=>0));
echo $this->Form->input('IPR_teeth_pair34',array('type' => 'select','name'=>'drop34', 'options' => $ipr_value,'default'=>0));
echo $this->Form->end();
echo '</div>'
yes you can save it. As per above form this will post to you controller action in view
public function view() {
// Has any form data been POSTed?
if ($this->request->is('post')) {
// If the form data can be validated and saved...
if ($this->Job->save($this->request->data)) {
// Set a session flash message and redirect.
$this->Session->setFlash('JobSaved!');
$this->redirect('/jobs');
}
}
// If no form data, find the recipe to be edited
// and hand it to the view.
$this->set('jobs', $this->Job->findAll());
}
below is just sudo code you can change as per you need and for more understanding you can visit cakephp.org
I am using $this->Js->submit to pass a value to my controller asynchronously and than update a div (id = #upcoming). Somehow I cannot save/retrieve the value of the field 'test' which is passed to my controller. Firebug tells me that the correct value is passed. What am I doing wrong?
View file (playlist.ctp):
echo $this->Form->create('Add', array('url' => array('controller' => 'Gods', 'action' => 'add')));
echo $this->Form->input('test');
echo $this->Js->submit('Addddd', array(
'url' => array(
'controller' => 'Gods',
'action' => 'add'
),
'update' => '#upcoming'
));
echo $this->Form->end();
echo $this->Js->writeBuffer(array('inline' => 'true'));
Controller action:
public function add()
{
$this->autoLayout = false;
$this->layout = 'ajax';
$link = $this->request->data['Add']['test'];
$this->set('test',$link);
}
And its view file (add.ctp):
<?php
echo $test;
?>
Thanks for your help!
have you tried pr($link) in the controller method? Or just send it to a log file if you prefer that. That way you can see if the data is received.
If so, I think there is nothing returned because of
$this->autoLayout = false;
Try it without this. It will still call the ajax layout instead of the default.
Otherwise you have to manualy call the render function
$this->render('add');
EDIT
As explained in the comments below, make sure your views are in the right place. (that would be the view folder associated with the controller)
I created a static option list in a page and I want to validate using JavaScript instead of AJAX:
<?php echo $form->labelEx($model,'emlevel'); ?>
<?php
echo $form->radioButtonList($model,'emlevel',
array('L'=>'Low','M'=>'Moderate','X'=>'Low Moderate', 'H'=>'High'),
array('separator' => " " ));
?>
<?php echo $form->error($model,'emlevel'); ?>
function chk()
{
// first I checked the value for emlevel to verify it get the value or not
//but it shows undefined
alert (document.forms["ConsultationNew"] ["ConsultationNew[enc_type]"].value);
if (document.forms["ConsultationNew"]["ConsultationNew[emlevel]"].value == null) {
alert ('choose one EMlevel'); return false;
}
}
I am not able to get value by document.getelement ....value. it shows undefined
You probably want to use CActiveForm. Clientside validation is configured as follows:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'login-form',
'enableAjaxValidation'=>false,
'enableClientValidation'=>true,
'clientOptions' => array (
'validateOnSubmit' => true,
'validateOnChange' => true,
'validateOnType' => true,
),
)); ?>
As you are working in Yii already, I would definitely use CActiveForm for client-side validation (and also for Ajax and server-side validation). It works like a charm. You must have better things to do than to reinvent the wheel in programming validation in Javascript.