Redirect to page a certain amount of times - Spring Boot - forms

I am trying to make a Quiz Creation application.
In the beginning, I ask the user to enter the quiz title, description, and the number of questions included in the quiz.
Based on the number of questions I want to redirect the user to the 'question and answers' page. I thought of adding another variable named 'count' which would keep the number of times the page is accessed so I can show the next or submit button.
I am not sure how to calculate the number of times the page is redirected and how to redirect the code to a certain page based on the number of questions.
This is the saveQuiz method in the QuizController class:
#PostMapping("/saveQuiz/{cid}")
public String saveQuiz(#PathVariable("cid") Long cid, #Valid #ModelAttribute Quiz quiz,
Model model, #RequestParam("questionNumber") int noOfQuestions) throws ParseException {
Chapter chapter = chapterService.findChapterById(cid);
quiz.setQuizName(quiz.getQuizName());
quiz.setGuidelines(quiz.getGuidelines());
quiz.setChapter(chapter);
quizService.saveQuiz(quiz);
model.addAttribute("quiz", quiz);
model.addAttribute("noOfQuestions", noOfQuestions);
return "redirect:/add_quiz_questions/"+quiz.getId();
}
Then in my QuestionController class I have the below methods
#Controller
public class QuestionController {
#Autowired
QuizService quizService;
#Autowired
QuestionService questionService;
#Autowired
AnswerService answerService;
private static int count = 0;
#GetMapping("/add_quiz_questions/{qid}")
public String addQuestions(#PathVariable("qid") Long qid, Model model) {
count++;
Quiz quiz = quizService.findQuizById(qid);
model.addAttribute("quiz", quiz);
model.addAttribute("count", count);
return "add_quiz_questions";
}
#PostMapping("/saveQuizQuestion/{qid}")
public String saveQuestions(#PathVariable("qid") Long qid, #Valid #ModelAttribute QuizForm quizForm,
Model model, #RequestParam("noOfQuestions") int noOfQuestions) throws ParseException {
Quiz quiz = quizService.findQuizById(qid);
Question question = new Question();
question.setQuestion(quizForm.getQuestion());
//Add answers
Set<Answer> answers = new HashSet<>();
Answer a = new Answer();
a.setAnswer(quizForm.getOption1());
a.setCorrect(1);
answers.add(a);
a.setAnswer(quizForm.getOption2());
a.setCorrect(0);
answers.add(a);
a.setAnswer(quizForm.getOption3());
a.setCorrect(0);
answers.add(a);
answerService.saveAnswers(answers);
question.setAnswers(answers);
questionService.saveQuestion(question);
Chapter chapter = quiz.getChapter();
Course course = chapter.getCourse();
Set<File> files = chapter.getFiles();
int nrFiles = files.size();
model.addAttribute("chapter", chapter);
model.addAttribute("course", course);
model.addAttribute("files", files);
model.addAttribute("numberOfFiles", nrFiles);
model.addAttribute("quiz", quiz);
if(count == noOfQuestions) //check if the page has been redirected as many times as there were questions then redirect to chapter page
return "redirect:/chapter_details/"+chapter.getId();
else
return "redirect:/add_quiz_questions/"+quiz.getId();
}
}
This is the Thymeleaf page:
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<div class="card">
<h5 class="card-header info-color white-text text-center py-4">
<strong>Quiz questions</strong>
</h5>
<div class="card-body px-lg-5">
<!-- Form -->
<form class="text-center" style="color: #757575;" th:action="#{/saveQuizQuestion/{qid}(qid=${quiz.id})}" method="post" th:object="${quizForm}">
<p>Create your quiz</p>
<!-- Question -->
<div class="md-form mt-3">
<input type="text" id="question" class="form-control" name="question">
<label for="question">Question</label>
</div>
<!-- Right answer -->
<div class="md-form">
<input type="text" id="ans1" class="form-control" name="option1">
<label for="ans1">Answer 1</label>
</div>
<!-- Answer 2 -->
<div class="md-form">
<input type="text" id="ans2" class="form-control" name="option2">
<label for="ans2">Answer 2</label>
</div>
<!-- Answer 3 -->
<div class="md-form">
<input type="text" id="ans3" class="form-control" name="option3">
<label for="ans3">Answer 3</label>
</div>
<input type="hidden" th:value="${count}" name="count"/>
<input type="hidden" th:value="${noOfQuestions}" name="noOfQuestions"/>
<button th:if="${noOfQuestions < count}" class="btn btn-outline-info btn-rounded btn-block z-depth-0 my-4 waves-effect" type="submit">Next</button>
<button th:if="${noOfQuestions == count}" class="btn btn-outline-info btn-rounded btn-block z-depth-0 my-4 waves-effect" type="submit">Submit</button>
</form>
<!-- Form -->
</div>
</div>
</html>
I believe the way that I am using the count variable is wrong but it's there just to give an idea. If anyone could help me clarify the question that I have, I'd be grateful.
Thank you in advance.

you can make a count variable in session with #SessionAttribute annotation.
and whenever they submit you will again set count variable to default value.

Related

Why are my dots removed when i post a form?

When I post my form, the points in my double are removed.
Does anyone have any idea what this is?
My model field:
[Display(Name = "Domeinnaam prijs:")]
public double DomainNamePrice { get; set; }
My HTML to fill the field in a form:
<div class="row">
<label class="col-lg-3" style="margin:auto; font-size: 120%;" asp-for="DomainNameLine"></label>
<div class="col-lg-9">
#Html.CheckBoxFor(i => i.DomainNameLine, new {#id = "DomainNameCheckbox", #name = "DomainNameLine", #onclick = "DomainNameCheck()"})
<span asp-validation-for="DomainNameLine" class="text-danger"></span>
</div>
</div>
<div id="DomainNameField" style="display:none;">
<div class="row">
<label class="col-lg-3" style="margin: auto; font-size: 120%;" asp-for="DomainNamePrice"></label>
<div class="col-lg-9">
<input asp-for="DomainNamePrice" class="form-control" />
<span class="text-danger" asp-validation-for="DomainNamePrice"></span>
</div>
</div>
</div>
For example, when I enter 14.99. I get 1499 as a result.
The form field
The result
Can someone help me?
Set this in your web.config
<system.web>
<globalization uiCulture="en" culture="en-US" />
You appear to be using a server that is setup with a language that uses comma's instead of decimal places. You can adjust the culture to one that uses the comma's in a way that your application is designed, such as en-US.
or you can add this statement on the page:
<%# Page uiCulture="en-US" culture="en-US" %>
Hope this helps.

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;
}
}

Spring boot controller not redirecting correctly

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

two subscribe forms on same page with mailchimp

I want to have two mailchimp forms ( linked to the same mailchimp list ) within the same landingpage in a Shopify Store. *it is a long landing page so I want them to be able to subscribe two times along the way.
It seems the second form does not work and the only think it does is refreshing the page. I am pretty sure there is a conflict with their ID´s because the two forms have the same ID ( id="mailchimp" ) but I believe it is neccesary for them to work.
I may have a very easy-to-resolve question but i have been struggling with it for a while. It seems there is no documentation about it ( apart from inserting one of the forms within an iframe -> I am not confortable with this solution because I want to record with GTM ( GA ) customer succesuful submitions etc. ).
The code for the forms ( snippet that it is called two times within the page ):
<!-- Newsletter Section -->
<section id="services" class="small-section bg-gray-lighter">
<div class="container relative">
<form class="form align-center newsdown" id="mailchimp">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="mb-20">
<input placeholder="Introduce tu email" class="newsletter-field form-control input-md round mb-xs-10" type="email" pattern=".{5,100}" required/>
<button type="submit" class="btn btn-mod btn-border-c btn-medium btn-round mb-xs-10">
Suscribe
</button>
</div>
<div id="subscribe-result"></div>
</div>
</div>
</form>
</div>
</section>
<!-- End Newsletter Section -->
What can I do to have these two identical forms working on the same page? Have in mind I don't have access to the javascript ( because mailchimp has Shopify app that makes this connection ).
If you wrap each mailchimp form in a ...., then run this script on the page, it will re-assign all IDs of the non-focused form, and re-bind the submit event. A bit hacky, but it works if you're in a bind.
$(document).ready(function() {
// only execute if confirmed more than 1 mailchimp form on this page
if ( $('.mc-form-instance').length > 1 ) {
$('.mc-field-group > .required').on('focus', function() {
var thisField = $(this);
// backup all mc-form ids on this page
$('.mc-form-instance [id]').each(function() {
var currentID = $(this).attr('id');
if ( currentID.indexOf('-bak') == -1 ) {
$(this).attr('id', currentID + '-bak');
}
});
// change the current form ids back to original state
var thisForm = thisField.closest('.mc-form-instance');
thisForm.find('[id]').each(function() {
var currentID = $(this).attr('id');
if ( currentID.indexOf('-bak') != -1 ) {
$(this).attr('id', currentID.replace('-bak', ''));
}
});
});
// re-bind
$.getScript('//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js');
}
});
As it appeared there were a conflict with two exact forms ( same javascript etc ) so I implemented the second form differently:
<!-- Newsletter Section -->
<section id="services" class="small-section bg-gray-lighter">
<div class="container relative">
<form action="YOURACTION;id=YOURID" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
<div class="row">
<div class="col-md-8 col-md-offset-2" style="text-align: center;">
<div class="newsletter-label font-alt">
¿Te interesa? Recibe más noticias y tutoriales exclusivos
</div>
<div class="mb-20">
<input name="EMAIL" id="mce-EMAIL" placeholder="Introduce tu email" class="newsletter-field form-control input-md round mb-xs-10 required email" type="email" pattern=".{5,100}" required/>
<input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button btn btn-mod btn-border-c btn-medium btn-round mb-xs-10">
</div>
<div id="mce-responses" class="clear">
<div class="response" id="mce-error-response" style="display:none"></div>
<div class="response" id="mce-success-response" style="display:none"></div>
</div>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_5307a1008b76c5446a7303622_18658ede2a" tabindex="-1" value=""></div>
<div class="form-tip">
<i class="fa fa-info-circle"></i> Pocos emails, pero de calidad. Nunca Spam. Te servirán.
</div>
<div id="subscribe-result"></div>
</div>
</div>
</form>
</div>
</section>
<!-- End Newsletter Section -->
<script type='text/javascript' src='//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js'></script><script type='text/javascript'>(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';fnames[3]='MMERGE3';ftypes[3]='dropdown';fnames[4]='MMERGE4';ftypes[4]='phone';fnames[5]='MMERGE5';ftypes[5]='url';fnames[7]='MMERGE7';ftypes[7]='text';fnames[6]='MMERGE6';ftypes[6]='birthday';fnames[8]='MMERGE8';ftypes[8]='text';fnames[9]='MMERGE9';ftypes[9]='radio';}(jQuery));var $mcj = jQuery.noConflict(true);</script>
<!--End mc_embed_signup-->

One click to trigger several search forms?

I have 1 main search form with a submit button and several secondary search forms with submit buttons.
What I would like to do is when I enter text and click on the submit button of the main search form, the same text gets copied in all of the secondary search forms and all the submit buttons of the secondary search forms get automatically hit.
The HTML code for the mains earch form is shown below:
<form action="query.php" method="get">
Search: <input type="text" name="item" size="30">
<input type="submit" value="send">
</form>
One of the several secondary search forms is shown below:
<FORM action="http://www.dpbolvw.net/interactive" method="GET" target="_blank">
<div style="float: left; padding: 0 3px 0 0;">
<INPUT type="text" name="src" size="9"
value="<?php
$input = $_GET['item'];
echo $input;?>" style="width: 110px; height: 22px;margin:0; padding: 0; font-size:140%;">
</div>
<div style="float: left; padding: 0 3px 0 0;">
<input type="image" name="submit" value="GO" src="http://images.guitarcenter.com/Content/GC/banner/go.gif"
alt="Search" style="font-size:140%">
/div>
<input type="hidden" name="aid" value="1234"/>
<input type="hidden" name="pid" value="1234"/>
<input type="hidden" name="url" value="http://www.guitarcenter.com/Search/Default.aspx"/>
</form>
Notice the php code that I put in the "value" field of the secondary search form:
<?php
$input = $_GET['item'];
echo $input;?>
This automatically copies the text that I entered in the main search form into the secondary search form. I thus figured out how to do that.
The problem is to "simulate" an "Enter" keystroke or a click on the "GO" button with the mouse on the secondary search form when the user hits the Enter key or hits the "SEND" button with the mouse on the main search form.
Thank you for your insight!
I'm not sure what the point of that would be, It looks like all of these are search forms all pointing to different sites. Web browsers won't allow that. They can navigate to one page at a time. When you post a form to a page you are navigating to that page. Therefore, you are trying to navigate to several pages at once. It's like trying to be in Paris and London at the same time. I don't see how your plan will work the way you're describing it.
That said, You can use client-side javascript to call
document.forms[0].submit();
so if you can come up with a plan that does not involve trying to have the user see all the different search results in one window, you could try this on your first form...
<form action="query.php" method="get" onSubmit="document.forms(1).Submit();">
You should use AJAX (JQuery) as Brandon Suggested. Read http://docs.jquery.com/Events/submit
Example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(document).ready(function(){
$("#submit").click(function() {
//Do you stuff here like triggering other submits
//Like:
$("input#submit2").click();
$("input#submit3").click();
return false;
});
});
</script>
</head>
<body>
<form action="javascript:alert('success!');">
<div>
<input type="text" />
<input type="submit" id="submit" />
</div>
</form>
<form >
<div>
<input type="text" />
<input type="submit" id="submit2" />
</div>
</form>
<form >
<div>
<input type="text" />
<input type="submit" id="submit3" />
</div>
</form>
</body>
</html>
Take a look at the submit() event in jQuery. That is going to be your key.
I am assuming that you are planning on submitting via ajax? Otherwise it is futile.
So you could do something like this-
Give all of your forms a certain class, let's call it 'ajax_search_forms'. So now you can actually hook into the submit event.
$('.ajax_search_forms').submit(function(){
var search_string = $('input[name=src]').val();
$('.ajax_search_forms').each(function(){
$.ajax({
url : $(this).attr('action'),
data : 'search_string=' + search_string,
success : function(html){
// Do something with the result
}
});
});
// Return false is VERY important so that the form submission does not continue
return false;
});