new to Symfony and trying to understand something. I have index.twig.html and in it, I have a form
<form action="{{ path('SpecialAlertBundle_add') }}" method="post" enctype="multipart/form-data" class="addAlertForm">
<textarea class="addMargin" id="na_command" name="na_command" rows="3" cols="50" placeholder="A20APRLONLAX"></textarea>
<button type="button" class="btn btn-default" id="submit_alert" name="submit_alert">Submit</button>
{{ name }}
</form>
I wont add all the html, but its a normal form, not using Form Builder.
I have a route set up
SpecialAlertBundle_add:
pattern: /
defaults: { _controller: SpecialAlertBundle:Alert:add }
requirements:
_method: GET|POST
So that route displays my form ok when I go to localhost:8000. It also states which controller to use. As for the controller, I have
class AlertController extends Controller
{
public function addAction()
{
$request = $this->get('request_stack')->getCurrentRequest();
if ($request->request->has('submit_alert')) {
$name = $request->request->get('na_command');
} else {
$name = 'Not submitted yet';
}
return $this->render('SpecialAlertBundle:Page:index.html.twig', array(
'name' => $name
));
}
}
The first thing I want to clear up is that return in the controller. Is this the view I want it to render AFTER the form has been submitted?
Second thing is, at the moment, The {{name}} in the template is always displaying Not submitted yet. Even when I submit the form with data, nothing seems to happen. It seems that the button is doing nothing. Even when I look in the debug console, I see no request being made.
So I was hoping someone could advise me on what I am doing wrong here?
Thanks
First of all why don't you use Request directly in controller instead of request_stack? Request stack is mostly for injecting it to service (and not to inject request to the service).
So, you can do something like this:
public function addAction(Request $request)
{}
Then I'd suggest you to separate get request and post request. Just define two different routes.
For example:
SpecialAlertBundle_add:
pattern: /
defaults: { _controller: SpecialAlertBundle:Alert:add }
requirements:
_method: GET
SpecialAlertBundle_create:
pattern: /
defaults: { _controller: SpecialAlertBundle:Alert:create }
requirements:
_method: POST
After this you will have to change your form action value: set it to 'SpecialAlertBundle_create'
And it will be cleaner which one is now. After that you just don't need the checking on existence of 'submit_alert' property in request. You can assign the value of 'na_command' field to the $name:
$name = $request->get('na_command');
Related
note: I am new to Play Framework
Using this video tutorial and playlist, I manage to create a simple webapp.
Problem:
POST methods in routes file do not seem to execute the required POST code.
Given the routes file below, browsing to localhost:{port}/user/register requests a GET, thus rendering and returning the register view.
Filling in the register view fields, and clicking submit, refreshes the page (by clearing the input fields) and does show the expected "registered" text
If method="post" has been added to the form in the register view, an immediate 403 Forbidden page page is displayed.
Why isn't the "registered" text being shown, what am I missing (doing wrong) ?
Routes file:
GET / controllers.HomeController.index
GET /user controllers.LoginController.index()
GET /user/login controllers.LoginController.login()
POST /user/login controllers.LoginController.doLogin()
GET /user/register controllers.LoginController.register()
POST /user/register controllers.LoginController.doRegister()
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
Controllers:
HomeController
LoginController
LoginController methods:
public Result index() { return ok(views.html.user.index.render(User.getAllUsers())) }
public Result login() { return ok(login.render()); }
public Result doLogin() { return ok("registered"); }
public Result register() { return ok(register.render()); }
public Result doRegister() { return ok("registered"); }
Register View:
#()
<html>
<head>
<title>Register new User</title>
</head>
<body>
<h1>Register User</h1>
<br>
<br>
Enter Email Address: <input type="password" name="confirmPassword">
Enter Password: <input type="password" name="confirmPassword">
Confirm Password: <input type="password" name="confirmPassword">
<br>
<br>
<form action="#routes.LoginController.doRegister()">
<input type="submit" value="Register"/>
</form>
</body>
</html>
Console output error:
[warn] p.filters.CSRF - [CSRF] Check failed because no or invalid token found in body
[warn] p.filters.CSRF - [CSRF] Check failed with NoTokenInBody
I think you're correct you need to define the HTTP method (GET or POST) to be used when submitting the form data.
It's possible you're seen Forbidden because "By default, Play will require a CSRF check" See here?
Add the CSRF token to the request like this:
#import helper._
<form method="post" action="#CSRF(routes.LoginController.doRegister())">
...
Or in the body of the form:
<form method="post" action="#routes.LoginController.doRegister()">
#CSRF.formField
...
I keep getting this error "Some mandatory parameters are missing" and I can't find how to resolve it.
This is my DataController:
//use some models here for Trialdata, Sessions, Rat;
class DataController extends \BaseController {
//Some functions
public function destroy($id)
{
Trialdata::where('id', $id)->delete();
Sessions::where('id', $id)->update(array('sD_reason', 'Excluded'));
Sessions::where('id', $id)->delete();
Rat::where('id', $id)->update(array('sD_reason', Input::get('sD_reason')));
Rat::where ('id', $id)->delete();
//
}
}
This is my route:
Route::resource('data', 'DataController');
This is the form in my view:
{{Form::open(array('route' => 'data.destroy', $parameters = array($entry[0]->id)))}}
{{Form::label('sD_reason', 'Please specify the reasons of the exclusion');}}<br>
<input name="sD_reason" type="text" id="sD_reason">
<button type="button">No, thanks</button>
<button type="submit" href="#">Exclude</butfon>
{{ Form::close() }}
I've look around for similar problems and I believe it's in my Form::open but I can't find the proper syntax.
Try this:
{{ Form::open( array('route' => array('data.destroy', $entry[0]->id) ) ) }}
From the docs:
http://laravel.com/docs/html#opening-a-form
I want to save data to the database by clicking on a button in a view file.
I would like to achieve this by calling a method in my controller via POST.
It works but I have to pass some variables/parameters ( without having inputfields ) to the controller and that doesn't work.
this is my controller:
class CouplesController extends BaseController {
public function postCreate($var1)
{
Couple::create(array(
'name'=>'test',
'id1'=>$var1
));
return Redirect::to('couples')
->with('message','Your couple was created successfully!');
}
}
and this is my view:
{{ Form::open(array('action' => 'CouplesController#postCreate', $var1->'hello')) }}
<p>{{ Form::submit('Create') }}</p>
{{ Form::close() }}
probably I'm doing this completely wrong. I just don't know how to do this.
btw it doesn't have to be the POST method.
You are really close, within your view:
{{ Form::open(array('action' => 'CouplesController#postCreate', 'hello')) }}
<p>{{ Form::submit('Create') }}</p>
{{ Form::close() }}
This will generate a URL similar to:
<form method="POST" action="http://localhost/couples/create/hello" accept-charset="UTF-8">
Then the rest of your code should work without an issue, and $var1 should be set to the value of hello.
I just saw that the error with the missing parameter appears while having this route:
Route::post('couples/done', 'CouplesController#postCreate');
when I take this route out it gives me this error:
Unknown action [CouplesController#postCreate].
like it doesn't have access to the controller in the view itself.
:(
Imagine this scenario: in our company there is an employee that "play" around graphic,css,html and so on.
Our new project will born under symfony2 so we're trying some silly - but "real" - stuff (like authentication from db, submit data from a form and persist it to db and so on..)
The problem
As far i know, learnt from symfony2 "book" that i found on the site (you can find it here), there is an "automated" way for creating and rendering forms:
1) Build the form up into a controller in this way
$form = $this->createFormBuilder($task)
->add('task','text'),
->add('dueDate','date'),
->getForm();
return $this->render('pathToBundle:Controller:templateTwig',
array('form'=>$form->createview());
2) Into templateTwig render the template
{{ form_widget(form) }} // or single rows method
3) Into a controller (the same that have a route where you can submit data), take back submitted information
if($rquest->getMethod()=='POST'){
$form->bindRequest($request);
/* and so on */
}
Return to scenario
Our graphic employee don't want to access controllers, write php and other stuff like those. So he'll write a twig template with a "unconventional" (from symfony2 point of view, but conventional from HTML point of view) method:
/* into twig template */
<form action="{{ path('SestanteUserBundle_homepage') }}" method="post" name="userForm">
<div>
USERNAME: <input type="text" name="user_name" value="{{ user.username}}"/>
</div>
<div>
EMAIL: <input type="text" name="user_mail" value="{{ user.email }}"/>
</div>
<input type="hidden" name="user_id" value="{{ id }}" />
<input type="submit" value="modifica i dati">
</form>
Now, if into the controller that handle the submission of data we do something like that
public function indexAction(Request $request)
{
if($request->getMethod() == 'POST'){ // sono arrivato per via di un submit, quindi devo modificare i dati prima di farli vedere a video
$defaultData = array('message'=>'ho visto questa cosa in esempio, ma non capisco se posso farne a meno');
$form = $this->createFormBuilder($defaultData)
->add('user_name','text')
->add('user_mail','email')
->add('user_id','integer')
->getForm();
$form->bindRequest($request); //bindo la form ad una request
$data = $form->getData(); //mi aspetto un'array chiave=>valore
/* .... */
We expected that $data will contain an array with key,value from the submitted form.
We found that it isn't true. After googling for a while and try with other "bad" ideas, we're frozen into that.
So, if you have a "graphic office" that can't handle directly php code, how can we interface from form(s) to controller(s) ?
UPDATE
It seems that Symfony2 use a different convention for form's field name and lookup once you've submitted that.
In particular, if my form's name is addUser and a field is named userName, the field's name will be AddUser[username] so maybe it have a "dynamic" lookup method that will extract form's name, field's name, concat them and lookup for values.
Is it possible?
You can force Symfony2 to set the name of a form field, though I don't suggest it: $formBuilder->add('dummyfield', 'text', array( 'attr' => array('name' => 'yournamehere') ) );
Alternatively (also a bad idea), you can do this, which won't even let you use the form API: $this->getRequest()->get('whatever_the_field_name_is');
OR you can hackily add elements to the request based on the Sf2 generated names before binding it (copying the values that exist).
OR you can make use of the bind method of the form component (instead of bindRequest) as documented here.
But seriously...just use the formbuilder api. Your life will be easier, and isn't that what a framework is for? :)
Symfony 2 is based on twig as templating language. Let him use it :
{{ form_label(form.field) }}
will generate something like this :
<label for="field">field</label>
You can use all the available functions in order to render the form :
{{ form_label() }}
{{ form_widget() }}
{{ form_errors() }}
If you want to customize what is rendered by those functions, you can override twig templates as defined in the Symfony2 documentation.
Otherwise if you really want to something ugly, you can go for this kind of syntax :
{{ myform.vars.value.myField }}
Environment: JQuery Form Plugin, jQuery 1.7.1, Zend Framework 1.11.11.
Cannot figure out why jQuery won't parse my json object if I specify an url other than a php file.
The form is as follows:
<form id="imageform" enctype="multipart/form-data">
Upload your image <input type="file" name="photoimg" id="photoimg" />
<input type="submit" id ="button" value="Send" />
</form>
The javascript triggering the ajax request is:
<script type="text/javascript" >
$(document).ready(function() {
var options = {
type: "POST",
url: "<?php $this->baseURL();?>/contact/upload",
dataType: 'json',
success: function(result) {
console.log(result);
},
error: function(ob,errStr) {
console.log(ob);
alert('There was an error processing your request. Please try again. '+errStr);
}
};
$("#imageform").ajaxForm(options);
});
</script>
The code in my zend controller is:
class ContactController extends BaseController {
public function init() {
/* Initialize action controller here */
}
public function indexAction() {
}
public function uploadAction() {
if (isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST") {
$image = $_FILES['photoimg']['tmp_name'];
$im = new imagick($image);
$im->pingImage($image);
$im->readImage($image);
$im->thumbnailImage(75, null);
$im->writeImage('userImages/test/test_thumb.jpg');
$im->destroy();
echo json_encode(array("status" => "success", "message" => "posted successfully"));
}
else
echo json_encode(array("status" => "fail", "message" => "not posted successfully"));
}
}
When I create an upload.php file with the above code, and modify the url from the ajax request to
url: "upload.php",
i don't run into that parsing error, and the json object is properly returned. Any help to figure out what I'm doing wrong would be greatly appreciated! Thanks.
You need either to disable layouts, or using an action helper such as ContextSwitch or AjaxContext (even better).
First option:
$this->_helper->viewRenderer->setNoRender(true);
$this->_helper->layout->disableLayout();
And for the second option, using AjaxContext, you should add in your _init() method:
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('upload', 'json')
->initContext();
This will disable automatically disable layouts and send a json header response.
So, instead of your two json_encode lines, you should write:
$this->status = "success";
$this->message = "posted successfully";
and
$this->status = "fail";
$this->message = "not posted successfully";
In order to set what to send back to the client, you simply have to assign whatever content you want into view variables, and these variables will be automatically convert to json (through Zend_Json).
Also, in order to tell your controller which action should be triggered, you need to add /format/json at the end of your URL in your jQuery script as follow:
url: "<?php $this->baseURL();?>/contact/upload/format/json",
More information about AjaxContext in the manual.
Is the Content-type header being properly set as "application/json" when returning your JSON?