Symfony3 - My handwritten post form don't work - forms

I'm trying to learn how to work with Symfony3.
I'm trying to make a simple form to connect. The form is succefully redirecting me to my page /login so that is super. But it don't sent to the page the post informations :/ Do you know how to do ?
This is my controller's code :
public function showAction(Request $request){
$motDePasse = $request->request->get("motDePasse", "");
$identifiant = $request->request->get("identifiant", "");
if($motDePasse != "" && $identifiant != ""){
// I make my user object and put it in $_SESSION
}
return $this->render("login/show.html.twig", [
"identifiant" => $identifiant
]);
}
And there is my twig code :
{% extends "::base.html.twig" %}
{% block body %}
<div id='loginBox'>
<div class='center'>
<div class='logo'></div>
<h1>HyperPlanning</h1>
<form action="{{ path('login') }}" method='post'>
<input name='identifiant' type='text' placeholder='Identifiant' value="{{ identifiant }}"><br/>
<input name='motDePasse' type='password' placeholder='Mot de passe'><br/>
<input name='remember' type='hidden' value='0'><br>
<input name='remember' type='checkbox' value='1' checked> <span>Rester connecter</span><br>
<input type='submit' value='Se connecter'>
</form>
</div>
</div>
{% endblock %}

I don't have a configured Symfony3 project on my laptop but Symfony v2.7. However, I assume the script is going to work in Symfony3 as well.
I have a DefaultController with the actions login and manageLogin. The first action contains the above html form and the second makes a dump of $request. Both actions have as route name the respective actionName. In the html form I am using as action="..." the route name of the manageLoginAction.
When submitting the form the manageLoginAction is rendered.
DefaultController:
<?php
// [...]
class DefaultController extends Controller
{
// [...]
/**
* #Route("/konto/login", name="login")
* #Template()
*/
public function loginAction(Request $request)
{
return array(
'base_dir' => realpath($this->container->getParameter('kernel.root_dir').'/..'),
);
}
/**
* #Route("/konto/manageLogin", name="manageLogin")
* #Template()
*/
public function manageLoginAction(Request $request)
{
dump($request);
die;
}
// [...]
}
login.twig.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}
<div id='loginBox'>
<div class='center'>
<div class='logo'></div>
<h1>HyperPlanning</h1>
<form action="{{ path('manageLogin') }}" method='post'>
<input name='identifiant' type='text' placeholder='Identifiant' value="Identifier"><br/>
<input name='motDePasse' type='password' placeholder='Mot de passe'><br/>
<input name='remember' type='hidden' value='0'><br>
<input name='remember' type='checkbox' value='1' checked> <span>Rester connecter</span><br>
<input type='submit' value='Se connecter'>
</form>
</div>
</div>
{% endblock %}
{% block javascripts %}{% endblock %}
</body>
dump($request):

Related

NoReverseMatch Error, Django can't verify the edit page

$I have no solution for this error , please i need support, it gives noreversematch and it seems it cant reach my edit-page , the following if full details of the coding , thank you
$ Edit link to edit page:
{% if post.created_by == user %}
<div class="mt-3">
<a class="btn btn-success float-end"
href="{% url 'edit_post' post.topic.board.pk post.topic.pk post.pk %}">Edit</a>
</div>
{% endif %}
$ views.py
#method_decorator(login_required, name='dispatch')
class PostUpdateView(UpdateView):
model = Post
fields = ['message']
template_name = 'edit_post.html'
pk_url_kwarg = 'post_id'
context_object_name = 'post'
def form_valid(self, form):
post = form.save(commit=False)
post.updated_by = self.request.user
post.updated_date = timezone.now()
post.save()
return redirect('topic_posts', board_id=post.topic.board.pk, topic_id=post.topic.pk)
$ urls.py
path('<int:board_id>/topics/<int:topic_id>/posts/<int:post_id/edit',
views.PostUpdateView.as_view(), name="edit_post"),
$html of the edit-page
<div class="container container-newtopic w-50">
<h1>Edit Post</h1>
<br>
{% include 'parts/alerts.html' %}
<div aria-label="breadcrumb">
<ol class="breadcrumb n1-head">
<li class="breadcrumb-item">Boards</li>
<li class="breadcrumb-item"><a href="{% url 'topics' post.topic.board.pk
%}">
{{post.topic.board.name}}</a></li>
<li class="breadcrumb-item active" aria-current="page"><a href="">Edit
Post</a></li>
</ol>
</div>
<form method="POST" action="" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{next}}">
{% include 'includes/form.html' %}
<button type="submit" name="btnaddtopicdj"
class="btn main-btn w-100 rounded-pill mt-5">Save Changes
</button>
</form>
</div>
$ error message:
NoReverseMatch at /boards/3/topics/20
Reverse for 'edit_post' with arguments '(3, 20, 23)' not found. 1 pattern(s) tried:
['boards/(?P<board_id>[0-9]+)/topics/(?P<topic_id>[0-9]+)/posts/<int:post_id/edit\\Z']
Reverse for 'edit_post' with arguments '(3, 20, 23)' not found. 1 pattern(s) tried:
['boards/(?P<board_id>[0-9]+)/topics/(?P<topic_id>[0-9]+)/posts/<int:post_id/edit\\Z']
href="{% url 'edit_post' post.topic.board.pk post.topic.pk post.pk %}">Edit</a>

My form is not populating when there is some validation error in the input data. Laravel Collective

Hope yo are all doing great.
I am using Laravel 5.3 and a package LaravelCollective for form-model binding.
I have subjects array that I want to validate and then store in database if there is no error in the input data.
The following snippets show the partial view of form, other views, rules for validations and controller code.
UserProfile.blade.php
<!-- Panel that Adds the Subject - START -->
<div class="col-md-12">
<div class="panel panel-default" id="add_Subject_panel">
<div class="panel-heading">Add Subject(s):</div>
<div class="panel-body">
{!! Form::open( array('method'=>'post', 'url'=>route('user.store.subject', 1)) ) !!}
#include('user.partials.subjects', ['buttonText'=>'Add Subject(s)'])
{!! Form::close() !!}
</div>
</div>
</div>
<!-- Panel that Adds the Subject - END -->
subjects.blade.php
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<div class="subject-list">
<div class="input-group subject-input">
<input type="text" name="name[]" class="form-control" value="" placeholder="Subject" />
<span class="input-group-btn">
<span class="btn btn-default">Primary subject</span>
</span>
</div>
</div>
<div class="text-right">
<br />
<button type="button" class="btn btn-success btn-sm btn-add-subject"><span class="glyphicon glyphicon-plus"></span> Add Subject</button>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4 text-right">
<button type="submit" class="btn btn-primary">
{{ $buttonText }} <i class="fa fa-btn fa-subject"></i>
</button>
</div>
</div>
#push('scripts')
{{-- <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> --}}
<script src="{{ asset('scripts/jquery-2.2.4.min.js') }}" type="text/javascript" charset="utf-8" async defer></script>
<script>
$(function()
{
$(document.body).on('click', '.btn-remove-subject', function(){
$(this).closest('.subject-input').remove();
});
$('.btn-add-subject').click(function()
{
var index = $('.subject-input').length + 1;
$('.subject-list').append(''+
'<div class="input-group subject-input" style="margin-top:20px; margin-bottom:20px;">'+
'<input type="text" name="name['+index+']" class="form-control" value="" placeholder="Subject" />'+
'<span class="input-group-btn">'+
'<button class="btn btn-danger btn-remove-subject" type="button"><span class="glyphicon glyphicon-remove"></span></button>'+
'</span>'+
'</div>'
);
});
});
</script>
#endpush
I want to validate all the subjects passed as an array to the controller using a custom created form request. the following is the code for that form request
SubjectRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SubjectRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
// dd("Rules Area");
foreach($this->request->get('name') as $key => $val)
{
$rules['name.'.$key] = 'required|min:5|max:50';
}
// dd($rules);
return $rules;
}
public function messages()
{
// dd('Message Area. . .');
$messages = [];
foreach($this->request->get('name') as $key => $val)
{
$messages['name.'.$key.'.required'] = ' Subject Name '.$key.'" is required.';
$messages['name.'.$key.'.min'] = ' Subject Name '.$key.'" must be atleast :min characters long.';
$messages['name.'.$key.'.max'] = ' Subject Name '.$key.'" must be less than :max characters.';
}
// dd($messages);
return $messages;
}
}
the following is the code for controller method I am using to store inputted array data to database.
public function storeSubjects(SubjectRequest $request)
{
$data = $request->all();
// save logic
dd($data);
}
Problem:
My form is not populating when there is some validation error in the input data.
After getting validation errors, my input fields are blank.
Problem
In subject.blade.php, your code looks like
<input type="text" name="name[]" class="form-control" value="" placeholder="Subject" />
Your fields are not populating because you have left value attribute blank.
Solution:
Pass the old value to solve your problem.
<input type="text" name="name[]" class="form-control" value="{{old('name[]')}}" placeholder="Subject" />
Use Form Model Binding instead
https://laravelcollective.com/docs/5.3/html#form-model-binding
{{ Form::model($user, [....]) }}
{{ Form::text('firstname', null, [...]) }}
{{ Form::close() }}

Flask form routing

I'm struggling with a Flask App that gives me Bad Request on a form submission. I've been through the little bit of documentation from Flask and a number of SO pages. I'm sure there's something simple I'm missing.
In a nutshell, I've developed a template to receive the form called 'placeindex.html'. The form 'name' data all matches. If I change the name of 'placeindex.html' to 'index.html' it works fine, even though I'm pointing to the 'placeindex.html' file. Code below (view):
#app.route('/add_place', methods=['GET', 'POST'])
def add_place():
username = session['username']
placename = request.form['place']
address = request.form['address']
city = request.form['city']
state = request.form['state']
zipcode = request.form['zipcode']
alias = request.form['alias']
searchword = request.args.get('key', '')
print(searchword)
Place(session['username']).new_place(placename, address, city, state, zipcode, alias, username)
return render_template('placeindex.html')
placeindex.html:
{% extends "layout.html" %}
{% block place %}
<h2>Home</h2>
{% if session.username %}
<h3>Add new 'placeindex'</h3>
<form action="{{ url_for('add_place') }}" method="post">
<dl>
<dt>Name:</dt>
<dd><input type="text" size="30" name="place"></dd>
<dt>Address:</dt>
<dd><input type="text" size="30" name="address"></dd>
<dt>City:</dt>
<dd><input type="text" size="30" name="city"></dd>
<dt>State:</dt>
<dd><input type="text" size="2" name="state"></dd>
<dt>Zip Code:</dt>
<dd><input type="text" size="10" name="zipcode"></dd>
<dt>Nickname:</dt>
<dd><input type="text" size="30" name="alias"></dd>
</dl>
<input type="submit" value="Save">
</form>
{% endif %}
<br>
<h3>My Places</h3>
{% include "display_posts.html" %}
{% endblock %}
I've stripped out all the validation code to try to figure this out.
layout.html (in case it helps):
<!doctype html>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
<div class="page">
<div class="metanav">
{% if session.username %}
Logged in as {{ session.username }}
{% endif %}
Home
{% if not session.username %}
Register
Login
{% else %}
Profile
Logout
Places
Trips
Delegates
{% endif %}
</div>
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
{% block body %}{% endblock %}
{% block post %}{% endblock %}
{% block place %}{% endblock %}
{% block trip %}{% endblock %}
</div>
Once I open the 'index.html' version of the file and send form data, it refreshes to the correct file, but I can't go there directly without the BAD REQUEST page.
Thanks
The issue is that you are accessing request.form without checking if request.form is populated. form contains arguments in the body of the HTTP request ... and GET requests don't have a body.
As discussed in Form sending error, Flask - when Flask is asked for a form variable that doesn't exist it throws an error ... just like an ordinary Python dictionary does.
The solution in your case is to wrap all of your data-processing code inside of a conditional:
if request.method == "POST":
# code accessing request.form here
So the general structure is:
#app.route('/add_place', methods=['GET', 'POST'])
def add_place():
if request.method == "POST":
username = session['username']
placename = request.form['place']
# ... snip ...
# Note that this is not under the `if`
# so we'll *always* return this template's HTML.
return render_template('placeindex.html')

Render issue when validation fail with 2 forms on the same page

i need to render 2 forms on the same page. To do this, I have 2 actions in my controller, the first one manage the form 1 and render the entire page, the second manage the form 2 and render only this form.
The second action is called in twig with a :
{% render (controller("AppBundle:User:secondForm")) %}
Both are rendered, both work, excepted when the validation of the form 2 fail. The Controller return the user to the form with form errors but instead of returning to the entire page, it only render the form.
My code look like this :
First action:
/**
* #Route("/profile/global-page", name="global_page")
*/
public function Global1Action(Request $request)
{
[.......]
$process = $formHandler->process($user);
if ($process) {
$request->getSession()->getFlashBag()->add('success', 'ok');
return $this->redirect($this->generateUrl('an_url'));
}
return $this->render('entire_page.html.twig', array(
'form' => $form->createView(),
));
}
then Twig global (entire_page.html.twig):
{% extends 'base.html.twig' %}
{% block content %}
{#FlashBags#}
{% include 'components/alert.html.twig' with {'type':'success'} %}
<div class="col-md-offset-3 col-md-6">
<div class="col-md-12 row">
<div class="panel panel-profil">
<div class="panel-heading">
<h3 class="panel-title">form 1</h3>
</div>
<div class="panel-body">
<form action="{{ path('global_page') }}" method="POST" class="form-horizontal text-center">
{{ form_widget(form) }}
<button type="submit" name="submit" class="btn btn-main button-sm">Go</button>
</form>
</div>
</div>
</div>
</div>
{% render (controller("AppBundle:User:secondForm")) %}
{% endblock %}
then SecondForm action:
/**
* #Route("/profile/second-form", name="second_form")
*/
public function secondFormAction(Request $request)
{
[.......]
$process = $formHandler->process($user);
if ($process) {
$request->getSession()->getFlashBag()->add('success', 'ok');
return $this->redirect($this->generateUrl('an_url'));
}
return $this->render('only_form2.html.twig', array(
'form' => $form->createView(),
));
}
and finaly the second twig (only_form2.html.twig):
<div class="col-md-offset-3 col-md-6">
<div class="col-md-12 row">
<div class="panel panel-profil" style="margin-top: 10px;">
<div class="panel-heading">
<h3 class="panel-title"> second form panel </h3>
</div>
<div class="panel-body">
<form action="{{ path('second_form') }}" {{ form_enctype(form) }} method="POST">
{{ form_widget(form) }}
<button type="submit" name="submit" class="btn btn-main button-sm">Go 2</button>
</form>
</div>
</div>
</div>
I don't understand how to return the user to the entire page (with form errors) instead of rendering only the second form when it's validation fail.
Thank you !
Edit: I found this post which explain how to have 2 forms in one controller. Answer below seems to not work with Symfony 2.8
You can use a multi form action. Something like this :
public function multiformAction()
{
$form1 = $this->get('form.factory')->createNamedBuilder($formTypeA, 'form1name')
->add('foo', 'text')
->getForm();
$form2 = $this->get('form.factory')->createNamedBuilder($formTypeB, 'form2name')
->add('bar', 'text')
->getForm();
if('POST' === $request->getMethod()) {
if ($request->request->has('form1name') {
// handle the first form
}
if ($request->request->has('form2name') {
// handle the second form
}
}
return array(
'form1' => $form1->createView(),
'form2' => $form2->createView()
);
}
See this post. And this question
To solve this issue you need to send Form request to action where render whole page (Global1Action). Not to action where second form is created.
You will need also move both forms handling to Global1Action.
To change second form action use this method:
$form->setAction($this->generateUrl('global_page'))
Or you can implement ajax handling for second form (if you need to keep it's logic in separate action).

How to submit comments in Symfony2?

I want to submit a comment in main page then redirect to this page.
This is my action:
public function submitcommentAction(Request $request)
{
$user=$this->get('security.context')->getToken()->getUser();
$uid=$user->getId();
$comment=new comment();
//$comment->setCafe();
$form=$this->createFormBuilder($comment)
->add('cafe','hidden')
->add('description','textarea')
->getForm();
if($request->getMethod()=='POST')
{
$form->bind($request);
if($form->isValid())
{
$comment->setCafe($form['cafe']->getData());
$comment->setUser($uid);
$comment->setDescription($form['description']->getData());
$em=$this->getDoctrine()->getEntityManager();
$em->persist($comment);
$em->flush();
// return $this->redirect($this->generateUrl('showcofe'));
var_dump($em);
exit();
}
}
$r='error';
return $this-> render('CafeManagementBundle:Default:simple.html.twig',array('r'=>$r));
}
and this is my twig:
<div class="new-comment">
<div class="new-comment-text"> :your comment
<div>
<form id="comment-form" method="post" action={{path('subcomment')}}" {{form_enctype(form1)}}">
<ul class="smallbuttons">
<input type="hidden" id="form_cafe" name="form[cafe]" value="{{cafe.id}}" />
{{form_widget(form1.description)}}
<div style="display:none">{{ form_rest(form1) }}</div>
<p><a id="clickbotton1" href="javascript:document.getElementById('form1').submit()" class="btn_smallorange edit2">submit</a></p>
</ul>
</form>
</div>
</div>
</div>
I don't know how to pass hidden field(cafe) to controller. Plus would you please tell me, whether my controller is correct?