Remove file in form if constraint violation - forms

I'm followed the tutorial to manage the upload of multiple files http://growingcookies.com/easy-multiple-file-upload-in-symfony-using-the-collectiontype-field/
The system for uploading multiple files works fine.
I added a constraint to allow only certain types of files and to set a maximum size.
When this constraint is enabled, the uploaded files are still present in the form but they are actually delete.
The javascript code always displays the files as present when in fact they are no longer present :
The buttons to delete the files are still present ..
Do you know how I can completely delete the form files in case of a constraint violation while displaying the error message ? Or do you have a better way to upload multiple files with constraints in Symfony 4 ?
My twig :
{% extends '#Ticketing/base.html.twig' %}
{% block title %}{{ 'New Ticket'|trans({}, 'TicketingBundle') }}{% endblock %}
{% block header %}<h1>{{ 'New Ticket'|trans({}, 'TicketingBundle') }}</h1>{% endblock %}
{% block form_group_class -%}
col-sm-8
{%- endblock form_group_class %}
{% block main %}
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
{% form_theme form 'bootstrap_4_layout.html.twig' _self %}
<div class="box box-danger">
<div class="box-header with-border">
<h3 class="box-title">{{ 'Create a new ticket'|trans({}, 'TicketingBundle') }}</h3>
</div>
{% form_theme form 'bootstrap_3_horizontal_layout.html.twig' _self %}
{{ form_start(form, {'attr': {'class': 'form-horizontal'} }) }}
<div class="box-body">
<div class="hr-line-dashed"></div>
<div id="filesProto" data-prototype="{{ form_widget(form.documents.vars.prototype)|e }}"></div>
<div class="form-group">
<label class="col-sm-2 control-label" for="ticket_form_documents">Pièce-jointe</label>
<div class="col-sm-8" id="filesBox">
{% set pos = 0 %}
{% for doc in form.documents %}
<div class="row">
<div class="col col-xs-1" id="jsRemove{{ pos }}" style="">
<button type="button" class="btn btn-danger" onclick="removeFile($(this));"><i class="fa fa-times" aria-hidden="true"></i></button>
</div>
<div class="col col-xs-11" id="jsPreview{{ pos }}">{{ doc.vars.value.name }}</div>
<div style="display:none">
{{ form_widget(doc) }}
</div>
</div>
{% set pos = pos + 1 %}
{% endfor %}
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<div class="col-md-offset-2 col-sm-8">
<button id="dropbutton" class="btn bg-ticketing btn-flat form-control" type="submit">
{{ 'Submit the ticket'|trans({}, 'TicketingBundle') }}
</button>
</div>
</div>
<!-- /.box-footer -->
{{ form_end(form) }}
</div>
<script>
var fileCount = '{{ form.documents|length }}';
var removeButton = "<button type='button' class='btn btn-danger btn-xs' onclick='removeFile($(this));'><i class='fa fa-times' aria-hidden='true'></i></button>";
function removeFile(ob)
{
ob.parent().parent().remove();
}
function createAddFile(fileCount)
{
// grab the prototype template
var newWidget = $("#filesProto").attr('data-prototype');
// replace the "__name__" used in the id and name of the prototype
newWidget = newWidget.replace(/__name__/g, fileCount);
newWidget = "<div style='display:none'>" + newWidget + "</div>";
hideStuff = "";
hideStuff += "<div class='col col-xs-1' id='jsRemove" + fileCount + "' style='display: none;'>";
hideStuff += removeButton;
hideStuff += "</div>";
hideStuff += "<div class='col col-xs-11' id='jsPreview" + fileCount + "'>";
hideStuff += "</div>";
hideStuff += "<div class='col-sm-8'>";
hideStuff += "<button type='button' id='jsBtnUpload" + fileCount + "' class='btn btn-default'>";
hideStuff += "<i class='fa fa-plus'></i> {{ 'Pièce-jointe' | trans }}";
hideStuff += "</button>";
hideStuff += "</div>";
$("#filesBox").append("<div class='form-group'>" + hideStuff + newWidget + "</div>");
// On click => Simulate file behaviour
$("#jsBtnUpload" + fileCount).on('click', function(e){
$('#ticket_form_documents_' + fileCount + '_file').trigger('click');
});
// Once the file is added
$('#ticket_form_documents_' + fileCount + '_file').on('change', function() {
// Show its name
fileName = $(this).prop('files')[0].name;
$("#jsPreview" + fileCount).append(fileName);
// Hide the add file button
$("#jsBtnUpload" + fileCount).hide();
// Show the remove file button
$("#jsRemove" + fileCount).show();
// Create another instance of add file button and company
createAddFile(parseInt(fileCount)+1);
});
}
$(document).ready(function(){
createAddFile(fileCount);
fileCount++;
});
</script>
{% endblock %}
The code is available here: https://github.com/oanalivia/Multiple-File-Upload-in-Symfony-using-the-CollectionType-Field

one banale solution would be to adapt the output and just filter the docs out, that don't have a value.
{% for doc in form.documents %}
{% if doc.vars.value %} {### <-- new 1/2 ###}
<div class="row">
<div class="col col-xs-1" id="jsRemove{{ pos }}" style="">
<button type="button" class="btn btn-danger" onclick="removeFile($(this));"><i class="fa fa-times" aria-hidden="true"></i></button>
</div>
<div class="col col-xs-11" id="jsPreview{{ pos }}">{{ doc.vars.value.name }}</div>
<div style="display:none">
{{ form_widget(doc) }}
</div>
</div>
{% set pos = pos + 1 %}
{% endif %} {### <-- new 2/2 ###}
{% endfor %}
if you're using a fairly new version of twig (>= 2.10, I believe), you can also only modify the first line of that section:
{% for doc in form.documents|filter(doc => doc.vars.value) %}

Related

How can I keep data previously entered in a Symfony form?

I want to keep data that have been entered in fields belonging to a form. I made this form so that the user creates an event. The reason is I included an other form to create a post address, so when the user submit his new address, he retrieves the information previously entered.
Do you have any idea how I can do this ?
(I apologize for all the bootstrap classes in my code.)
event_create.html.twig
{% extends 'base.html.twig' %}
{% block main %}
<div class="events">
<h1 class="display-2 text-center event_form_title">Création d'une nouvelle sortie ou d'une nouvelle activité</h1>
{{ form_start(eventform, {'attr' : {'class' : 'admin_form', 'novalidate': 'novalidate'}}) }}
<div class="d-flex justify-content-center">
<div id="eventform">
<div class="mb-3">
<p>Type</p>
{{ form_widget(eventform.category, {'value' : category.id} ) }}
</div>
<div class="mb-3">
<p>Titre</p>
{{ form_widget(eventform.title) }}
</div>
<div class="mb-3">
<p>Description</p>
{{ form_widget(eventform.description, {'attr' : {'rows' : '3'}} ) }}
</div>
<div class="mb-3 d-none">
<p>Langue à partiquer</p>
{{ form_widget(eventform.spokenlanguage) }}
</div>
<div class="mb-3" id="dateselection">
<p>Date</p>
{{ form_widget(eventform.start.date) }}
</div>
<div class="d-sm-flex justify-content-center">
<div class="d-flex justify-content-center justify-content-sm-end me-sm-3">
<div class="mb-3">
<p>Début</p>
{{ form_widget(eventform.start.time, {'attr' : {'class' : 'time_event'}} ) }}
</div>
</div>
<div class="d-flex justify-content-center justify-content-sm-start">
<div class="mb-3">
<p>Fin</p>
{{ form_widget(eventform.end, {'attr' : {'class' : 'time_event'}} ) }}
</div>
</div>
</div>
<div class="mb-3">
<p>Adresse</p>
{{ form_widget(eventform.address) }}
</div>
<button type="button" onclick="hideAddressButton(); showLocationForm();" class="btn btn-lg btn-outline-secondary w-100 mt-4 mb-5" id="showaddress">Créer une adresse</button>
<div class="d-flex justify-content-center" id="eventsubmit">
{{ form_widget(eventform.save, {'label': "Je valide", 'attr' : {'class' : 'btn btn-lg btn-outline-primary w-100 mb-5'}} ) }}
</div>
<div class="d-flex justify-content-center">
<span class="me-2"><</span> Retour à la liste
</div>
</div>
</div>
</div>
{{ form_end(eventform) }}
<!-- Sélectionner/Ajouter une langue -->
{{ form_start(languageform, {'attr' : {'id' : 'languageform', 'class' : 'mb-3'}}) }}
<p>Langue à pratiquer</p>
{{ form_widget(languageform.code, {'attr': {'onChange': 'selectLanguage();'} }) }}
{{ form_widget(languageform.name, {'attr': {'class': 'd-none'} }) }}
{{ form_widget(languageform.save, {'attr': {'class': 'd-none'} }) }}
{{ form_end(languageform) }}
<ul class="language_names d-none">
{% for language in languages %}
<li class="language_name">{{ language.name }}</li>
{% endfor %}
</ul>
<ul class="language_ids d-none">
{% for language in languages %}
<li class="language_id">{{ language.id }}</li>
{% endfor %}
</ul>
<!-- Créer/Ajouter une adresse -->
{{ form_start(locationform, {'attr' : {'id' : 'locationform'}}) }}
<hr>
<h1 class="display-2 mb-5">Création d'un lieu de rendez-vous</h1>
<div class="d-flex justify-content-center">
<div>
<div class="mb-3">
<p>Nom du lieu</p>
{{ form_widget(locationform.name) }}
</div>
<div class="d-sm-flex justify-content-center">
<div class="d-flex justify-content-center justify-content-sm-end me-sm-3">
<div class="mb-3">
<p>Numéro</p>
{{ form_widget(locationform.number, {'attr' : {'class' : 'numbers_address'}}) }}
</div>
</div>
<div class="d-flex justify-content-center justify-content-sm-start">
<div class="mb-3">
<p>Rue</p>
{{ form_widget(locationform.street, {'attr' : {'class' : 'texts_address'}}) }}
</div>
</div>
</div>
<div class="d-sm-flex justify-content-center">
<div class="d-flex justify-content-center justify-content-sm-end me-sm-3">
<div class="mb-3">
<p>Code postal</p>
{{ form_widget(locationform.zipcode, {'attr' : {'class' : 'numbers_address'}}) }}
</div>
</div>
<div class="d-flex justify-content-center justify-content-sm-start">
<div class="mb-3">
<p>Ville</p>
{{ form_widget(locationform.city, {'attr' : {'class' : 'texts_address'}}) }}
</div>
</div>
</div>
<div class="mb-3">
<p>Grande ville</p>
{{ form_widget(locationform.bigcity) }}
</div>
<button type="button" onclick="hideBigCityButton(); showBigCityForm();" class="btn btn-lg btn-outline-secondary w-100 mt-4" id="showbigcity">Ajouter une grande ville</button>
<div id="bigcity">
{% include "front/create/bigcity.html.twig" %}
</div>
<div class="d-flex justify-content-center my-5">
{{ form_widget(locationform.save, {'label': "Enregistrer une nouvelle adresse", 'attr' : {'class' : 'btn btn-lg btn-outline-primary w-100'}} ) }}
</div>
</div>
</div>
<hr>
{{ form_end(locationform) }}
{% endblock %}
EventController.php
<?php
namespace App\Controller\Front;
class EventController extends AbstractController
{
#[Route('/create/event/category/{id}', name: 'event_create', methods: ['GET', 'POST'])]
public function createEvent(
Request $request,
Category $category,
LanguageRepository $languageRepository,
CountryRepository $countryRepository,
EntityManagerInterface $entityManagerInterface,
UserRepository $userRepository,
LocationRepository $locationRepository
){
$languages = $languageRepository->findAll();
$language = new Language();
$languageform = $this->createForm(EventLanguageType::class, $language);
$languageform->handleRequest($request);
if ($languageform->isSubmitted() && $languageform->isValid()) {
$entityManagerInterface->persist($language);
$entityManagerInterface->flush();
}
$connected = $this->getUser();
$useremail = $connected->getUserIdentifier();
$user = $userRepository->findOneBy(['email' => $useremail]);
$location = new Location();
$locationform = $this->createForm(LocationType::class, $location);
$locationform->handleRequest($request);
if ($locationform->isSubmitted() && $locationform->isValid()) {
$location->setOrganizer($user);
$entityManagerInterface->persist($location);
$entityManagerInterface->flush();
}
$bigcity = new BigCity();
$bigcityform = $this->createForm(BigCityType::class, $bigcity);
$bigcityform->handleRequest($request);
if ($bigcityform->isSubmitted() && $bigcityform->isValid()) {
$entityManagerInterface->persist($bigcity);
$entityManagerInterface->flush();
}
$countries = $countryRepository->findAll();
$country = new Country();
$countryform = $this->createForm(NewCountryType::class, $country);
$countryform->handleRequest($request);
if ($countryform->isSubmitted() && $countryform->isValid()) {
$entityManagerInterface->persist($country);
$entityManagerInterface->flush();
}
$event = new Event();
$eventform = $this->createForm(EventType::class, $event, [
'addresses' => $locationRepository->findBy(['organizer' => $user])
]);
$eventform->handleRequest($request);
if ($eventform->isSubmitted() && $eventform->isValid()) {
$event->setOrganizer($user);
$entityManagerInterface->persist($event);
$entityManagerInterface->flush();
$participation = new Participation();
$participation->setParticipant($user);
$participation->setEvent($event);
$entityManagerInterface->persist($participation);
$entityManagerInterface->flush();
return $this->redirectToRoute('participations');
}
return $this->renderForm('front/event/create.html.twig', [
'eventform' => $eventform,
'languageform' => $languageform,
'languages' => $languages,
'locationform' => $locationform,
'bigcityform' => $bigcityform,
'countryform' => $countryform,
'countries' => $countries,
'category' => $category
]);
}
This is my trial with AJAX, but it does not work :
<script>
// I bring values entered in form and I send it with Ajax
inputs = document.querySelectorAll(["input", "select"]);
function saveDatas(){
let xhr = new XMLHttpRequest();
xhr.open("POST", "https://jsonplaceholder.typicode.com/posts", false);
xhr.setRequestHeader("Content-type", "application/json");
post = {
title: document.getElementById('event_title').value,
description: document.getElementById('event_description').value,
};
xhr.send(JSON.stringify(post));
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status <= 299) {
data = JSON.parse(xhr.response)
}
}
}
for (var i = 0 ; i < inputs.length; i++) {
inputs[i].addEventListener('click', saveDatas);
}
// I retrieve values and I entered them in form fields
languageform = document.getElementById('languageform');
function retrieveDatas(){
let xhr = new XMLHttpRequest();
xhr.open("GET", "https://jsonplaceholder.typicode.com/posts", false);
xhr.send();
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status <= 299) {
posts = JSON.parse(xhr.response)
posts.forEach((post) => {
document.getElementById('event_title').value = post.title;
document.getElementById('event_description').value = post.description;
})
}
}
}
languageform.addEventListener('submit', retrieveDatas);
</script>
I'm not sure to understand. You have a lot of ways to do it. You can use ajax and javascript (Stimulus is very good and documented on SymfonyCast) to avoid to reload page and create your new address. With Stimulus, your data-controller sent an ajax request, create the new address and update its own content.
You can merge your forms (so all data are sent) with two buttons (so you know which button has been push and which action is triggered. Then in your controller, you create the new address and send back all other data.
A third solution is to read this answer. It could help you.
IMO, the first solution is more user friendly.

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>

Flask-paginate + MongoDB full text search Error $search had wrong type when hitting page 2

Having an issue with flask-paginate & pyMongo/MongoDB full text search. Pagination works well for me until the user tries to search for a 'post' in the database. It will display the first 6 (as I've set it in my case) results that there are but once you want to navigate to page 2 it throws an error reading:
pymongo.errors.OperationFailure: "$search" had the wrong type. Expected string, found null, full error: {'operationTime': Timestamp(1600978481, 2), 'ok': 0.0, 'errmsg': '"$search" had the wrong type. Expected string, found null', 'code': 14, 'codeName': 'TypeMismatch', '$clusterTime': {'clusterTime': Timestamp(1600978481, 2), 'signature': {'hash': b'\xd6b\xe7\x8eI\xa5\xea[\xb2\x0e5Y\xa2\xf3\x93R\xc6\xc1\xc4\x06', 'keyId': 6862628668309504003}}}
The same issue arises if I try and filter the search results using .sort("param", 1) - I've removed this 'feature' since but this is the same error I've encountered.
Werkzeug notes that the issue arises on line 63 in my search() route ie. pagination = Pagination(...).
My routes.py:
#app.route('/search', methods=("GET", "POST"))
def search():
page = request.args.get(get_page_parameter(), type=int, default=1)
per_page = 6
search_request = request.form.get("search")
all_posts = mongo.db.posts.find({"$text": {"$search": search_request}}).skip((page-1) * per_page).limit(per_page)
pagination = Pagination(
page=page, per_page=per_page,
total=all_posts.count(), record_name='all_posts')
return render_template('search.html', all_posts=all_posts, pagination=pagination, search_request=search_request)
My search.html template:
<div class="row">
{% for post in all_posts %}
<div class="col s12 l4">
<div class="card card-panel hoverable">
<div class="card-image center-align">
<img src="{{post.image_url}}" class="card-img">
</div>
<div class="card-content">
<h4 class="card-title">{{post.title}}</h4>
<p>{{post.description}}</p>
<p class="read-time">{{post.read_time}} minute(s), {{post.views}} views</p>
</div>
<div class="card-action">
Read
</div>
</div>
</div>
{% endfor %}
{% if all_posts.count() == 0 %}
<div class="center-align">
<h3>No posts found</h3>
</div>
{% endif %}
</div>
<!-- Pagination -->
<div class="row center-align">
{% if all_posts.count() > 1 %}
{{ pagination.info }}
{% endif %}
{{ pagination.links }}
Thanks for your help.

Symfony2 - display form error in bootstrap tooltip

I would like to display form error message inside bootstrap tooltip.
<div class="btn-upload" data-toggle="tooltip" data-html="true" data-title="{% if document.documentFile.vars.errors|length > 0 %}<span class='text-danger'>{{ form_errors(document.documentFile) }}</span>{% endif %}">
It should display form error inside tooltip on icon.
But message is displayed like this:
Now if I change {{ form_errors(document.documentFile) }} to "TEST MESSAGE":
So the problem is form error rendering inside tooltip. Any ideas how to fix it?
The {{ form_errors(document.documentFile) }} renders HTML with " that breaks your div.
Consider doing this :
<div class="btn-upload" data-toggle="tooltip" data-html="true" id="error-tooltip">
<script type="text/html" id="form-error">
{% if document.documentFile.vars.errors|length > 0 %}
<span class='text-danger'>{{ form_errors(document.documentFile) }}</span>
{% endif %}
</script>
<!-- ... -->
</div>
And, in your JS :
$('#error-tooltip').data('tooltip', $('#form-error').html());
I finally figured out a simplier way to achieve it by foreaching errors of document.documentFile.vars.errors. A little bit similar way to Favian's answer but without rewriting a block.
<div class="btn-upload" data-toggle="tooltip"
{% if document.documentFile.vars.errors|length > 0 %}
data-html="true"
data-title="<span class='text-danger'>
{% for error in document.documentFile.vars.errors %}
{{ error.message }}
{% endfor %}
</span>"
{% endif %}
>
Works just fine!
By default, the errors are rendered inside an unordered list:
<ul>
<li>The file is to large bla bla bla</li>
</ul>
To override how errors are rendered for all fields, simply copy, paste and customize the form_errors fragment.
<div class="btn-upload" data-toggle="tooltip" data-html="true" data-title="{% if document.documentFile.vars.errors|length > 0 %}<span class='text-danger'>
{% block form_errors %}
{% spaceless %}
{% if errors|length > 0 %}
{% for error in document.documentFile %}
{{ error.message }}
{% endfor %}
{% endif %}
{% endspaceless %}
{% endblock form_errors %}
</span>{% endif %}">
</div>

Get form from rendered controller

I have such problem with symfony2.
I have base.html.twig and this base is the template for others twigs.
I want to render controller, which contains form with locale-type input field.
The form will be used to change language of site.
My LanguageController:
<?php
namespace Soczewki\PlatformaBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class LanguageController extends Controller {
public function createAction(Request $Request)
{
$form = $this->createFormBuilder()
->setMethod('POST')
->setAction(null)
->add('locale', 'locale', array(
'label' => ' ',
'choices' => array('pl' => 'Polski', 'de' => 'Deutsch', 'en' => 'English'),
'data' => $this->getRequest()->getLocale(),
'required' => true))
->add('submit', 'submit')
->getForm();
$form->handleRequest($Request);
if($form->isValid()) {
$this->getRequest()->setLocale('en');
}
return $this->render("SoczewkiPlatformaBundle::myForm.html.twig",
array(
'form' => $form->createView(),
'req' => $r
));
}
}
The whole base.html.twig:
<html>
<head>
<title>{% block pageTitle %}{% endblock %}</title>
{#js#}
<script src="{{ asset('bundles/soczewkiplatforma/js/jquery.js') }}"></script>
<script src="{{ asset('bundles/soczewkiplatforma/js/bootstrap.js') }}"></script>
{#/js#}
{% block stylesheets %}
<link href="{{ asset('bundles/soczewkiplatforma/css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ asset('bundles/soczewkiplatforma/css/my-style.css') }}" rel="stylesheet">
{% endblock stylesheets %}
</head>
<body>
{% if app.security.getToken().getUser().getAuthKey() is defined %}
{% if app.security.getToken().getUser().getAuthKey() is not empty %}
{% set diff = ( app.security.getToken().getUser().getEndDate()|date('U') - "now"|date('U') ) / 3600 %}
<div style="width: 300px; height: 140px; position: absolute; bottom: 90px; right: 50px;" class="alert alert-danger alert-error">
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<strong>Uwaga!</strong> Twoje konto nadal nie zostało aktywowane!<br />
Pozostało Ci: <span class="badge">{{ diff[0:2] }} godzin {{ ( diff[3:] * 60 )[0:2] }} minut </span>
<br /><br />
<button type="button" class="btn btn-danger">Wpisz kod</button>
<button type="button" class="btn btn-default" data-dismiss="alert">Zamknij</button>
</div>
{% endif %}
{% set hasParams = app.request.get('id') %}
{% if hasParams is empty %}
{% set currentPath = url( app.request.attributes.get( '_route', app.request.attributes.get('_route_params'))) %}
{% else %}
{% set currentPath = url( app.request.attributes.get( '_route', app.request.attributes.get('_route_params')),{'id': 0} ) %}
{% endif %}
{% set dirs = currentPath|split('/') %}
{% set flag = "" %}
{% set url = "" %}
<ol class="breadcrumb">
<li>Główna</li>
{% for key, dir in dirs %}
{% if url is not empty %}
{% set url = url ~ '/' ~ dir %}
{% else %}
{% set url = url ~ dir %}
{% endif %}
{% if flag == true %}
{% if '=' in dir %}
{% set _temp = dir|split('=') %}
{% else %}
{% set _temp = dir|split(' ') %}
{% endif %}
{% if key + 1 == dirs|length %}
<li class="active"> {{ _temp[0]|capitalize|replace('-',' ') }} </li>
{% else %}
<li> {{ _temp[0]|capitalize|replace('-',' ') }} </li>
{% endif %}
{% endif %}
{% if dir == 'app_dev.php' %}
{% set flag = true %}
{% endif %}
{% endfor %}
<li class="dropdown" style="float: right !important;">
Zalogowano jako: {{ app.security.getToken().getUser().getName() }} <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>Moje konteło</li>
<li>Wyloguj</li>
</ul>
</li>
</ol>
{% else %}
<ol class="breadcrumb">
<li>Główna</li>
<!--- logowanie --->
<li class="dropdown" style="float: right !important;">
Zaloguj <span class="caret"></span>
<div class="dropdown-menu" style="padding: 15px; padding-bottom: 0px; left: -200px;">
<form action="{{ path('login_check') }}" method="post">
<label for="username">Email/NIP:</label>
<input type="text" id="username" name="_username" />
<br />
<label for="password">Hasełko:</label>
<input type="password" id="password" name="_password" />
<br /><br />
<button type="submit">Loguj do Afganistanu</button>
</form>
</div>
</li>
<!--- log ---->
</ol>
{% endif %}
{{ render(controller('SoczewkiPlatformaBundle:Language:create')) }}
{% block pageContainer %}
{% endblock %}
</body>
</html>
Nothing shows and I get too any error.
Why is it like that?
// codes updated
myForm.html.twig:
{{ dump(req) }}
{{ form(form) }}
and LocaleListener.php:
<?php
namespace Soczewki\PlatformaBundle\Translations;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocaleListener implements EventSubscriberInterface
{
private $defaultLocale;
public function __construct($defaultLocale = 'pl')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
// try to see if the locale has been set as a _locale routing parameter
if ($locale = $request->attributes->get('_locale')) {
$request->getSession()->set('_locale', $locale);
} else {
// if no explicit locale has been set on this request, use one from the session
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
}
}
public static function getSubscribedEvents()
{
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
);
}
}
You have created a situation where you are calling the same method an infinite amount of times until the page just dies.
You original base is being rendered which is in the end rendering the SoczewkiPlatformaBundle::base.html.twig template. Within this template a render() is calling an action that is then rendering the SoczewkiPlatformaBundle::base.html.twig template, which then calls the render(), which then render SoczewkiPlatformaBundle::base.html.twig, and on and on...
You need to specify a template for the form to be rendered in rather than the base and then call that in your changeAction.
For example...
Soczewki\PlatformaBundle\Controller\LanguageController
public function changeAction(Request $Request)
{
// ..
return $this->render("SoczewkiPlatformaBundle:Locale:change_form.html.twig",
array(
'form' => isset($form) ? $form->createView() : null,
));
}
SoczewkiPlatformaBundle:Locale:change_form.html.twig
{{ form_start(form, {'method': 'POST', 'action': 'your_locale_change_route' }) }}
{{ form_row(form.locale) }}
{{ form_end(form) }}
Your next problem would be that your changeAction isn't actually performing an action (apart from creating a form), although you may just be wanting that page to show before you get to that part.
You need to add this code where you want that the form appear
{{ form(form) }}
Edited after the comments below;
Create a file named myForm.html.twig and put in SoczewkiPlatformaBundle;
Now write this code inside:
{{ form(form) }}
now your controller should be:
public function changeAction(Request $Request)
{
$form = $this->createFormBuilder()
->add('locale', 'locale', array(
'label' => 'user.locale',
'required' => true,
'choices' => array('en' => 'English', 'de' => 'Deutsch', 'pl' => 'Polish')
))
->getForm();
$form->handleRequest($Request);
return $this->render("SoczewkiPlatformaBundle::myForm.html.twig",
array(
'form' => $form->createView(),
));
}