Bonjour,
Voila je rencontre un petit problème avec mon code.
Ce que je fais
Donc pour la gestion du profil de l'utilisateur, j'ai fait une page profile qui contient 3 formulaires sous forms de tabs bootstrap.
Dans un premier temps, j'avais fait un controller qui détectait quel form était soumit pour le traiter, mais ça semblait posé problème, alors j'ai fait dans mon controller une fonction qui affiche le profil, et 3 autres qui reçoivent le submit en ajax. ça semble fonctionner car par exemple pour l'email il l'enregistre bien si je le modifie via le formulaire.
Ce que j'obtiens
Mais le souci c'est que le fait de faire en ajax, j'ai perdu au passage le controle des erreur et l'affichage de celles-ci...
Voici le code de tous ça =>
Profilecontroller
<?php
namespace App\Controller;
use App\Entity\UserLanguage;
use App\Service\LanguagesProvider;
use App\Service\CountryProvider;
use App\Form\ProfileAccountType;
use App\Form\ProfileMeType;
use App\Form\ProfileLanguageType;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Twig\Environment;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class ProfileController extends Controller
{
/**
* Get page profile
* @IsGranted("ROLE_USER")
*/
public function getProfile(Environment $twig, Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
// user
$user = $this->getUser();
//Entity Manager
$em = $this->getDoctrine()->getManager();
// Build the forms
$tab1 = $this->createForm(ProfileAccountType::class, $user, array( 'action' => $this->generateUrl('profileAccount')));
$tab2 = $this->createForm(ProfileMeType::class,$user, array( 'action' => $this->generateUrl('profileMe')));
$tab3 = $this->createForm(ProfileLanguageType::class, array( 'action' => $this->generateUrl('profileLanguage')));
/*
Avant ajax commenter au cas où
// If submit
if ($request->isXmlHttpRequest()) {
if ($request->request->has('profile_account')) {
$tab1->handleRequest($request);
}
if ($request->request->has('profile_me')) {
$tab2->handleRequest($request);
}
if ($request->request->has('profile_language')) {
$tab3->handleRequest($request);
}
// Handle account form
if ($tab1->isSubmitted() && $tab1->isValid()) {
//Get Password submitted
$passwordSubmit = $tab1->get('password')->getData();
// Encode
$password = $passwordEncoder->encodePassword($user, $passwordSubmit);
// Control and set
if ($passwordSubmit != null AND $password != $user->getPassword()) {
$user->setPassword($password);
}
//Save
$em->persist($user);
$em->flush();
// Handle me form
} else if ($tab2->isSubmitted() && $tab2->isValid()) {
//Gender
$gender = $tab2->get('gender')->getData();
// Control and set
if ($tab2->get('gender') != null AND $tab2->get('gender') != $user->getGender()) {
$user->setGender($gender);
}
//Save
//$em->persist($user);
//$em->flush();
// Handle language form
} else if ($tab3->isSubmitted() && $tab3->isValid()) {
}
}
*/
// View
return new Response($twig->render('/home/profile.twig', array(
'user'=>$user,
'tab1'=>$tab1->createView(),
'tab2'=>$tab2->createView(),
'tab3'=>$tab3->createView(),
)
));
}
/**
* Ajax profileAccount
* @IsGranted("ROLE_USER")
* @method({"POST"})
* @param Request $request
* @return JsonResponse
*/
public function profileAccountAction(Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
if ($request->isXmlHttpRequest()) {
// user
$user = $this->getUser();
// Entity Manager
$em = $this->getDoctrine()->getManager();
$tab1 = $this->createForm(ProfileAccountType::class, $user, array( 'action' => $this->generateUrl('profileAccount')));
$tab1->handleRequest($request);
// Form Submitted
if ($tab1->isValid()) {
//Get Password submitted
$passwordSubmit = $tab1->get('password')->getData();
// Control and set
if ($passwordSubmit != null ) {
// Encode
$password = $passwordEncoder->encodePassword($user, $passwordSubmit);
if ($password != $user->getPassword()) {
$user->setPassword($password);
}
}
//Save
$em->persist($user);
$em->flush();
return new JsonResponse(array('message' => $errorCollection));
} else {
//dump($tab1->getErrors());
/*$errorCollection = array();
foreach($errors as $error){
$errorCollection[] = $error->getMessageTemplate();
};*/
return new JsonResponse(array('message' => $tab1->getErrors()));
}
} else {
return new JsonResponse(array('message' => 'not XmlHttpRequest'));
}
}
/**
* Ajax profileMe
* @IsGranted("ROLE_USER")
*/
public function profileMeAction(Request $request)
{
}
/**
* Ajax profileLanguage
* @IsGranted("ROLE_USER")
*/
public function profileLanguageAction(Request $request)
{
}
}
Exemple de formType pour la tab Account
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\RadioType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
use Symfony\Component\Intl\Intl;
class ProfileAccountType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
/* Tab My account */
->add('username', EmailType::class, array(
'label' => 'profile.account.email', 'required'=> true
))
->add('nickname', TextType::class, array(
'label' => 'profile.account.nickname', 'required'=> true
))
->add('password', RepeatedType::class, array(
'type' => PasswordType::class,
'invalid_message' => 'profile.account.invalidPassword',
'mapped' =>false,
'required' => false,
'first_options' => array('label' => 'profile.account.password'),
'second_options' => array('label' => 'profile.account.repeatPassword')
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::class
));
}
public function getName() {
return 'profile_account';
}
}
Twig
{% extends 'layout/base.twig' %}
{% block stylesheets %}
<link href="{{ asset('css/home/profile.css') }}" rel="stylesheet">
{% endblock %}
{% block content %}
<div class="container">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item ">
<a class="nav-link active" id="account-tab" data-toggle="tab" href="#account" role="tab" aria-controls="account" aria-selected="true">{{ 'profile.account.tab'|trans }}</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#me" role="tab" aria-controls="profile" aria-selected="false">{{ 'profile.me.tab'|trans }}</a>
</li>
<li class="nav-item">
<a class="nav-link" id="language-tab" data-toggle="tab" href="#language" role="tab" aria-controls="language" aria-selected="false">{{ 'profile.language.tab'|trans }}</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<!-- account -->
<div class="tab-pane fade show active" id="account" role="tabpanel" aria-labelledby="account-tab">
{{ form_start(tab1, {'attr': {'id': 'profile_account'}}) }}
<div class="form-group ">
{{ form_row(tab1.username, {attr: {class: 'form-control'} }) }}
</div>
<div class="form-group ">
{{ form_row(tab1.nickname, {attr: {class: 'form-control'} }) }}
</div>
<div class="form-group ">
{{ form_row(tab1.password, {attr: {class: 'form-control'} }) }}
</div>
<div id="errorAccount" class="form-group alert alert-danger"></div>
<button type="submit" id="btnAccount" class="btn btn-md btn-secondary yellowButton">{{ 'profile.btnSave'|trans }}</button>
<!-- add token CSRF (hidden) -->
{{ form_rest(tab1) }}
{{ form_end(tab1) }}
</div>
<!-- me -->
<div class="tab-pane fade" id="me" role="tabpanel" aria-labelledby="profile-tab">
{{ form_start(tab2, {'attr': {'id': 'profile_me'}}) }}
<div class="form-group ">
{{ form_row(tab2.avatar, {attr: {class: 'form-control'} }) }}
</div>
<div class="form-group ">
{{ form_row(tab2.presentation, {attr: {class: 'form-control'} }) }}
</div>
<div class="form-group ">
{{ form_row(tab2.country, {attr: {class: 'form-control'} }) }}
</div>
<div class="form-group ">
{{ form_row(tab2.city, {attr: {class: 'form-control'} }) }}
</div>
<div class="form-group ">
{{ form_row(tab2.gender, {attr: {class: 'form-control'} }) }}
</div>
<button type="submit" id="btnMe" class="btn btn-md btn-secondary yellowButton">{{ 'profile.btnSave'|trans }}</button>
<!-- add token CSRF (hidden) -->
{{ form_rest(tab2) }}
{{ form_end(tab2) }}
</div>
<!-- language -->
<div class="tab-pane fade" id="language" role="tabpanel" aria-labelledby="contact-tab">
{{ form_start(tab3, {'attr': {'id': 'profile_language'}}) }}
<div class="form-group">
{{ form_row(tab3.allLanguages, {attr: {class: 'form-control'} }) }}
</div>
<div class="form-group">
{{ form_row(tab3.level, {attr: {class: 'form-control'} }) }}
</div>
<button type="submit" id="btnLanguage" class="btn btn-md btn-secondary yellowButton">{{ 'profile.btnSave'|trans }}</button>
<!-- add token CSRF (hidden) -->
{{ form_rest(tab3) }}
{{ form_end(tab3) }}
</div>
</div>
</div>
{% endblock %}
{% block javascripts %}
<script type="text/javascript" src="{{ asset('js/profile.js') }}" ></script>
{% endblock %}
profile.js
/* Profile tabs */
$(document).ready(function () {
/* Form Account tab */
$("#profile_account").submit(function (e) {
var isvalidate = $("#profile_account")[0].checkValidity();
if (isvalidate) {
$.post('profileAccount',$("#profile_account").serialize(),function(data) {
console.log(data.message);
$('#errorAccount').text(data.message);
}, 'JSON');
}
e.preventDefault();
});
});
Voilà, merci pour votre aide