Spring boot controller not redirecting correctly - forms

I am experiencing a problem with the redirect of the method below in my controller class.
When I click on the submit button it does not redirect me to http://localhost:8080/manager/customers but it redirects to http://localhost:8080/customer/1/manager/customers
Note: the 1 is the customer id that I choose to add orders to
Am I doing something wrong??
#PostMapping(value = "/customer/{id}/orders")
public String projectAddOrders(#PathVariable("id") Long customerId, #RequestParam Long orderId, Model model) {
Order order = orderService.findOrderById(orderId);
Customer customer = customerService.findCustomerById(customerId);
if (customer != null) {
if (!customer .hasOrder(order)) {
customer .getOrders().add(order);
}
customerService.saveCustomer(customer );
model.addAttribute("customer", customerService.findCustomerById(customer Id));
model.addAttribute("orders", orderService.getAllOrders());
return "redirect:manager/customers";
}
return "redirect:manager/customers";
}
This is the HTML from:
<form th:action="#{/customer/{id}/orders(id=${customer.id})}" method="post">
<div class="row">
<div class="col-25">
Customer name: <b th:text="${customer.name}" /><br/>
</div>
</div>
<div class="row">
Customer orders:
<b><span th:each="order, iterStat : ${customer.orders}">
<span th:text="${order.name}"/><th:block th:if="${!iterStat.last}">,</th:block>
</span></b>
</div>
</div>
<br/>
<div class="row">
<div class="col-25">
<label for="user">Add Order</label>
</div>
<div class="col-75">
<select name="orderId">
<option th:each="order: ${orders}"
th:value="${order.id}"
th:text="${order.name}">
</option>
</select>
</div>
</div>
<div class="row">
<input type="submit" value="Add Order">
</div>
</form>

Try turning
return "redirect:manager/customers";
into
return "redirect:/manager/customers";
Mind the slash between 'redirect:' and 'manager'.
Does it work?

I fixed it by adding
registry.addViewController("**/manager/customers").setViewName("redirect:/manager/customers");
in my ApplicationWebMvcConfigurerAdapter implements WebMvcConfigurer class

Related

Handler method not firing when called by form in Razor Pages

I've gone through dozens of articles, docs, and stack overflow questions (even the one with a similar intro)regarding the same issues but it still persists.
I've tried this with putting the functions in the .cshtml.cs page and on the .cshtml page, named and unnamed handler names, different framework for sending emails, and adding an empty action field in the form along with other fixes but the issue seems to be that the handler method itself is not firing while the form is submitting. Any and all help is appreciated and please let me know if more information is needed.
My HTML form:
<form method="POST" asp-page-handler="email">
<!-- Name input-->
<div class="form-floating mb-3">
<input class="form-control" name="clientName" type="text" placeholder="Enter your name..." required/>
<label for="name">Full name*</label>
</div>
<!-- Email address input-->
<div class="form-floating mb-3">
<input class="form-control" name="clientEmail" type="email" placeholder="name#example.com" required/>
<label for="email">Email address*</label>
</div>
<!-- Phone number input-->
<div class="form-floating mb-3">
<input class="form-control" name="clientPhone" type="tel" placeholder="(123) 456-7890"/>
<label for="phone">Phone number</label>
</div>
<!-- Message input-->
<div class="form-floating mb-3">
<textarea class="form-control" name="clientMessage" type="text" placeholder="Enter your message here..." style="height: 10rem" required></textarea>
<label for="message">Message*</label>
</div>
<!-- Submit Button-->
<div class="d-grid"><button class="btn btn-primary btn-xl" type="submit" value="submit">Submit</button></div>
</form>
My functions as they are currently:
public void OnPostEmail()
{
var clientEmail = Request.Form["clientEmail"];
var clientName = Request.Form["clientName"];
var clientPhone = Request.Form["clientPhone"];
var clientMessage = Request.Form["clientMessage"];
sendEmail(clientEmail, clientName, clientPhone, clientMessage);
}
public void sendEmail(string clientEmail, string clientName, string clientPhone, string clientMessage)
{
var errorMessage = "";
try
{
// Initialize WebMail helper
WebMail.SmtpServer = "smtp.google.com";
WebMail.SmtpPort = 587;
WebMail.UserName = "***#gmail.com";
WebMail.Password = "MYPASSWORD";
WebMail.From = "***#gmail.com";
WebMail.EnableSsl = true;
// Send email
WebMail.Send(to: clientEmail,
subject: $"Request from: + {clientName}",
body: $"{clientMessage}\nPhone: {clientPhone}\nEmail: {clientEmail}"
);
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
}

storing form and rout

I have problem on storing form . All my efforts will be damaged if I could not solve it.
The GET method is not supported for this route. Supported methods: POST.
what happen now :
1.When I press on register which is linked to this rout :
Route::POST('/jobs/apply/{id}/', [JobseekerController::class,'applyforjob'])->name('aplpy1');
there will be two scenarios:
if the user has cv it will register the user directly.(works)
if the user has not cv it will direct the user to create cv view .(works)
This is a part of create cv view :
<form method="POST" action="{{route('storing')}}" enctype=multipart/form-data>
#csrf
<input type="hidden" name=job_id value= {{$s}}>
#if (count($errors) > 0)
<div class="alert alert-danger alert-dismissible fade show">
<strong>Opps!</strong> Something went wrong, please check below errors.<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
#endif
<div class="card-body">
<div class="container">
<!------ Include the above in your HEAD tag ---------->
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="accordion" class="checkout">
<div class="panel checkout-step">
<div> <span class="checkout-step-number">1</span>
<h4 class="checkout-step-title"> <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" > Personal Information</a></h4>
</div>
<div id="collapseOne" class="collapse in">
<div class="checkout-step-body">
<div class="row mt-3 pr-3">
<div class="col-6 ">
<strong>Full Name:</strong>
{!! Form::text('FName', null, array('placeholder' => 'Full Name','class' =>
'form-control pb-4')) !!}
</div>
<div class="col-6">
<div class="row mt-3 mr-2">
<strong>Nationality:</strong>
<select name="Nationality" class="custom-select">
#foreach(\App\Models\Nationality::all() as $nation)
<option value="{{$nation->name}}">{{$nation->name}}</option>
#endforeach
</select>
</div>
<div class="form-group ">
<button type="submit" name="submit" class="btn btn-primary ">{{ __('APPLAY') }}</button
</div>
<input type="hidden" name=job_id value= {{$s}}>
</form>
2.Now Here is the problem:
If I fill all the fields on the form correctly and click apply it works , but if there is missing field or anything not filled as it should be and then click apply , although there is validation on controller it does not work it gives this error:
The GET method is not supported for this route. Supported methods: POST.
Although I am using Post this my rout that I use to store the form
Route::POST('/jobsapply', [JobseekerController::class,'store'])->name('storing');
This my controller for storing:
public function store(Request $request )
{
$this->validate($request, [
'FName' => 'required|alpha|regex:/^([^"!\*\\]*)$/',
'Nationality' => 'required',
]);
$input = $request->all();
$input = $request->except(['_token']);
$cv = new cv();
if ($this->cvsave($cv, $request )) {
$data = Job::all();
$cv = auth()->user()->cv;
return view ('show',compact('cv' ,'data'))->with('success', 'CV created successfully.');
}
$data = Job::all();
return view('show')->with('Failed!', 'error');
}
public function cvsave(cv $cv, Request $request)
{
$cv->FName = $request->FName;
$cv->Nationality = $request->Nationality;
if ($cv->save()) {
$application = new JobApplication;
$id=$request->job_id;
$jobs = Job::find($id)->get();
$application->job_id =$request->job_id;
$user = User::find(auth()->user()->id);
$application->user_id = auth()->user()->id;
$cv = auth()->user()->cv;
$i= $cv->id;
$application->cv_id = $i;
$application->save();
\Session::flash('success', 'Thank you for applying! Wait for the company to respond.!');
return true;
}
return false;
}
I could not know the reason, I have read lots of stuff but still the same error

how to define an entity inside the function symfony 5

for exemple this is my function :
/**
* #Route("/companyProfile/{id_Adresse}/{id_Employes}/{id_Contact}", name="company_profile")
* #ParamConverter("Adresse", options={"mapping": {"id_Adresse" : "id"}})
* #ParamConverter("Employes", options={"mapping": {"id_Employes" : "id"}})
* #ParamConverter("Contact", options={"mapping": {"id_Contact" : "id"}})
*/
public function index(Adresse $adresse , Employes $employes , Contact $contact,ContactRepository $contactrepository, EmployesRepository $employesrepository , AdresseRepository $adresserepository ): Response
{
$contactform=$this->createForm(ContactType::class, $Contact);
$employesform=$this->createForm(EmployesType::class, $Employes);
$adresseform=$this->createForm(AdresseType::class, $Adresse);
return $this->render('companyProfile.html.twig', [
'Contact' => $contactrepository->findAll(),
'Employes' => $employesrepository->findAll(),
'Adresse' => $adresserepository->findAll(),
'contactform'=>$contactform->createView(),
'employesform'=>$employesform->createView(),
'adresseform'=>$adresseform->createView()
]);
}
as you can see i declare all my entity in the parameter but i need to add all there ids in the route and that's not what i need , i just want my route to be like this :
/*
*#Route ("/companyProfile", name="company_profile")
*/
thanks in advance for all your answer
The param converter goal is the retrieve an entity from a route parameter. My guess is that you want to get all this entities but not with their ids in the route.
To do so, you will need to get the repository for each of your entity and then get them here. There is a question still : how do you know which entity do you want?
Here is an exemple of your action
/**
* #Route("/companyProfile", name="company_profile")
*/
public function index(ContactRepository $contactRepository, EmployesRepository $employesRepository , AdresseRepository $adresseRepository): Response
{
$contactform = $this->createForm(ContactType::class, $contactRepository->find($contactId);
$employesform = $this->createForm(EmployesType::class, $employesRepository->find($employesId);
$adresseform = $this->createForm(AdresseType::class, $adresseRepository->find($adresseId);
return $this->render('companyProfile.html.twig', [
'Contact' => $contactrepository->findAll(),
'Employes' => $employesrepository->findAll(),
'Adresse' => $adresserepository->findAll(),
'contactform'=>$contactform->createView(),
'employesform'=>$employesform->createView(),
'adresseform'=>$adresseform->createView()
]);
}
You still need a way to get all this new ids variables, but I can't help you more with the given informations.
i tried a different way to display them but when i want to edit for exemple contact , it dosen't work and they show me this error:
An exception has been thrown during the rendering of a template ("Notice: Undefined index: Contact").
here's a screenshot:
enter image description here
and here's my code :
/**
* #Route("/companyProfile/", name="company_profile")
*/
public function index(): Response
{
$Contact = $this->getDoctrine()
->getRepository(Contact::class)
->findAll();
$Employes = $this->getDoctrine()
->getRepository(Employes::class)
->findAll();
$Adresse = $this->getDoctrine()
->getRepository(Adresse::class)
->findAll();
return $this->render('companyProfile.html.twig', [
'Contact' => $Contact,
'Employes' => $Employes,
'Adresse' => $Adresse,
]);
}
this is the edit function:
/**
* #Route("/UpdateContact/{id}",name="editcontact")
*/
public function EditContact(Contact $contact , Request $request ,ManagerRegistry $manager)
{
$contactform=$this->createForm(ContactType::class, $contact);
$contactform->handleRequest($request);
if($contactform->isSubmitted() && $contactform->isValid())
{
$manager = $this->getDoctrine()->getManager();
$manager->persist($contact);
$manager->flush();
return $this->redirectToRoute('company_profile');
}
return $this->render('companyProfile.html.twig', [
'contactform'=>$contactform->createView()
]);
}
and last my twig :
<div class="boxed-list margin-bottom-60">
<div class="boxed-list-headline">
<h3><i class="icon-material-outline-business-center"></i> les contactes d'entreprise</h3>
</div>
</br>
{% for Contact in Contact %}
<div class="listings-container compact-list-layout">
<ul class="list-group">
<li class="list-group-item">
<h3>Contact</h3>
</br></br>
<div class="container pt-3">
<h5>Responsable:</h5>
<p>{{Contact.responsable}}</p>
<h5>N° de tele:</h5>
<p>{{Contact.telephone}}</p>
<h5>Addresse email:</h5>
<p>{{Contact.email}}</p>
<h5>Note:</h5>
<p>{{Contact.note}}</p>
<div class="centered-button margin-top-35">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
Modifier
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- Form -->
<form method="post" id="add-note">
<div class="form-group">
<label for="nom">Responsable:</label>
<input type="text" class="form-control" placeholder="{{Contact.responsable}}" id="nom">
</div>
<div class="form-group">
<label for="tele">N° de tele:</label>
<input type="text" class="form-control" placeholder="{{Contact.telephone}}" id="telephone">
</div>
<div class="form-group">
<label for="email">Email address:</label>
<input type="email" class="form-control" placeholder="{{Contact.email}}" id="email">
</div>
<label for="note">Note:</label>
<textarea name="textarea" cols="10" placeholder="{{Contact.note}}" class="with-border"></textarea>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button><i class="icon-material-outline-arrow-right-alt"></i>
</div>
</div>
</div>
</div>

Why validation is not working?

corporate.html
<form #f="ngForm" name="corporateProfileForm" ng-submit="corporateFrmSave(objDS, objDSCurrency)" novalidate="">
<div class="row form-group">
<div class="col-md-12" >
<input type="text" *ngIf="formData" [(ngModel)]="formData.Corporate_Id" id="corpid" title="Corporate ID" tab-index="1" name="corpid" maxlength="20" #corpid="ngModel" required/>
<label for="corp"><b>Corporate ID</b></label>
<div *ngIf="corpid.invalid && (corpid.dirty || corpid.touched)" class="alert alert-danger">
<div *ngIf="corpid.errors.required">
Name is required.
</div>
<div *ngIf="ncorpidame.errors.minlength">
Name must be at least 4 characters long.
</div>
<div *ngIf="corpid.errors.forbiddenName">
Name cannot be Bob.
</div>
</div>
</div>
</div>
</form>
Iam getting error message as
ERROR TypeError: Cannot read property 'invalid' of undefined
Make sure you define your variable with this structure:
TS file
export class ContactComponent implements OnInit {
myform: any;
corpid: FormControl;
constructor() {
}
ngOnInit() {
this.createFormControls();
this.createForm();
}
createFormControls() {
this.corpid= new FormControl('', Validators.required);
}
createForm() {
this.myform = new FormGroup({
corpid: this.corpid,
});
}
HTML file
<div class="md-form form-sm form-group"
[ngClass]="{
'invalid': corpid.invalid && (corpid.dirty || corpid.touched),
'valid': corpid.valid && (corpid.dirty || corpid.touched)
}">
<i class="fa fa-user prefix"></i>
<input
type="text" id="corpid" class="form-control"
required
[formControlName]="'corpid'">
<label for="corpid" class="">Your corpid</label>
</div>
<div class="form-control-feedback"
*ngIf="corpid.errors && (corpid.dirty || corpid.touched)">
<p *ngIf="corpid.errors.required">corpid is required</p>
</div>
It's hard to tell because issue is not in your HTML snipped but in .ts file.
I hope my Code will be helpfull
The issue is with the *ngIf, so when that condition is checked, Angular renders the rest of the template, and while the small fraction of time while *ngIf is being evaluated, your template reference variable corpid does not exist, so it will throw an error when trying to check the validation intially.
Wrap the input field with the validation div's inside the *ngIf instead of applying it only on the input field.
<div class="row form-group" *ngIf="formData">
<input [(ngModel)]="formData.Corporate_Id" id="corpid" ... >
<!-- more code here... -->
</div>
DEMO

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() }}