Persist information from controller to Thymeleaf and then send it to another controller (thymeleaf and Spring Boot - spring-boot

I'm working in a recovery password form with Spring Boot and Thymeleaf, the process is that the backend sends a link to the user with a token, this token is saved in a DB with the user information. The user clicks the link and the backend validate the token, if it's correct it redirects with the user information to the "new pass" form where the user has to introduce a new password and repeat it. When the user introduces the passwords and press save, it sends the information to the back end, with the userId it searches the register and changes the password.
In the controller where I validate the token when the user presses the link, I search the users' information and I build and usersRecoverPassDto with the userId and the passwords null and organize the model object to send it to the "new pass" form like this:
PasswordManagmentPostDto passManagment = new PasswordManagmentPostDto();
passManagment.setUserId(userId);
model.addAttribute ("passInfo", passManagment);
In the "new pass" form I received the correct information:
passInfo={
userId: 123456,
newPassword: null,
repeatePassword: null
}
The "new pass" form I code is like this:
<form action="#" th:action="#{/password/recovery}" th:object="${passInfo}" method="post">
<div class="mb-2 mr-sm-2 mb-sm-0 position-reNew pass:</label>
<input type="password" th:field="*{newPassword}" placeholder="Contraseña" class="form-control">
</div>
<div class="mb-2 mr-sm-2 mb-sm-0 position-relative form-group">
<label for="repeatePass" class="mr-sm-2">Repeat pass:</label>
<input type="password" th:field="*{repeatNewPassword}" placeholder="Repita contraseña" class="form-control"/>
</div>
<div class="mb-2 mr-sm-2 mb-sm-0 mt-3 position-relative form-group">
<input name="submit" type="submit" value="Save" class="inputButton btn btn-success "/>
</div>
</form>
I enter the two passwords and press the button Save but in the controller, I receive the next object:
passInfo={
userId: null,
newPassword: password,
repeatePassword: password
}
The userId parameter is just a parameter that passes without any modification and without being shown but I don't know how to persist this value from the controller to the view and then to the other controller.
I trayed adding another input to the new pass form:
<input type="text" th:field="*{userId}" th:value="*{userId}" placeholder="userId" class="form-control"/>
And I did nothing with this input, just put the two passwords and press the save button and it worked, I received the object with the correct information.
Of course, the userId parameter must not be shown in the form or modified.
Can someone help me, please?
Thank you very much in advance

OLD ANSWER
Use a hidden input:
<input type="hidden" id="userId" name="userId" th:value="*{userId}" />
This is part of what hidden inputs are for, to maintain data that should be sent back to the controller, but isn't something for the user to see / change.
NEW ANSWER
Per our discussion in the comments, it sounds like the appropriate approach is to retain the user's token on the front end. Pass that token to the controller when submitting the form, then look up the user by that token to reset the password.

Related

Thymeleaf: Partially set values to model object from outside the form tags

I have an model object that I send to front end. I populate that object inside the form. What I want to know is that if I can partially populate that object from a different event before user submits his/her form?
Example:
Entity:
public class Participant {
public String username;
public boolean taskCompleted;
}
Thymeleaf Form:
<form th:object="${participant}" th:action="#{/join}" method="post">
<input type="text" th:field="*{username}" >
<button type="submit">Join!</button>
</form>
Before submitting the form, I give users a task, like clicking a button on a different part of the page. If they do it, I want to do something like taskCompleted = true of the same participant object. Is that possible?
Use a hidden input in your form:
<form th:object="${participant}" method="post">
<input type="text" th:field="*{username}" >
<input type="hidden" th:field="*{taskCompleted}" />
<button type="submit">Join!</button>
</form>
When the user clicks a button, use JavaScript to set the value of the hidden input to true.
<!-- This button flips the value of taskCompleted to true -->
<button onclick="document.getElementById('taskCompleted').value = 'true';">Do the task first!</button>

How to keep the fields of a form after being redirected by login or registration in Laravel?

The business logic is as follows:
Fill out the form to publish a card.
Click on publish card button.
Publish if only if the user is authenticated.
If you are not authenticated, request to log in with the option to register.
If the user is registered or logged in, redirect to the form keeping the fields filled.
This is the logic of what I want to do
Note:
I currently show the login view if it is not authenticated with the help of laravel's Authentication Middleware.
The login view has the option to register.
I do not have much experience in laravel, I would like you could be explicit in your answer.
Try this one
<input type="text" class="form-control" placeholder="Name" name="name" required value="{{ old('name') }}">
this keep old value when you return page.
if you want redirect page with data, use Compact.
for example
$data["name"] = "name"
$data["gender"] = "something"
return view('your blade file path', compact('data'));
and on blade file
<input type="text" class="form-control" placeholder="Name" name="name" required value="{{ $data['name'] }}">

Thymeleaf set default value [duplicate]

I am programming in Spring and using Thymeleaf as my view, and am trying to create a form where users can update their profile. I have a profile page which lists the user's information (first name, last name, address, etc), and there is a link which says "edit profile". When that link is clicked it takes them to a form where they can edit their profile. The form consists of text fields that they can input, just like your standard registration form.
Everything works fine, but my question is, when that link is clicked, how do I add the user's information to the input fields so that it is already present, and that they only modify what they want to change instead of having to re-enter all the fields.
This should behave just like a standard "edit profile" page.
Here is a segment of my edit_profile.html page:
First Name:
Here is the view controller method that returns edit_profile.html page:
#RequestMapping(value = "/edit", method = RequestMethod.GET)
public String getEditProfilePage(Model model) {
model.addAttribute("currentUser", currentUser);
System.out.println("current user firstname: " + currentUser.getFirstname());
model.addAttribute("user", new User());
return "edit_profile";
}
currentUser.getFirstname() prints out the expected value, but I'm getting blank input values in the form.
Thanks.
Solved the problem by removing th:field altogether and instead using th:value to store the default value, and html name and id for the model's field. So name and id is acting like th:field.
I'm slightly confused, you're adding currentUser and a new'd user object to the model map.
But, if currentUser is the target object, you'd just do:
<input type="text" name="firstname" value="James" th:value="${currentUser.firstname}" />
From the documentation:
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html
I did not have a form with input elements but only a button that should call a specific Spring Controller method and submit an ID of an animal in a list (so I had a list of anmials already showing on my page). I struggled some time to figure out how to submit this id in the form. Here is my solution:
So I started having a form with just one input field (that I would change to a hidden field in the end). In this case of course the id would be empty after submitting the form.
<form action="#" th:action="#{/greeting}" th:object="${animal}" method="post">
<p>Id: <input type="text" th:field="*{id}" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>
The following did not throw an error but neither did it submit the animalIAlreadyShownOnPage's ID.
<form action="#" th:action="#{/greeting}" th:object="${animal}" method="post">
<p>Id: <input type="text" th:value="${animalIAlreadyShownOnPage.id}" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>
In another post user's recommended the "th:attr" attribute, but it didn't work either.
This finally worked - I simply added the name element ("id" is a String attribute in the Animal POJO).
<form action="#" th:action="#{/greeting}" th:object="${animal}" method="post">
<p>Id: <input type="text" th:value="${animalIAlreadyShownOnPage.id}" name="id" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>

Thymeleaf - how to populate input field if a value present?

I have a Spring boot application with a flow like this.
A new user register get registered
He/She receives a verification email
When the user clicks on the verification URL he/she will be redirected to the login page.
It's all good up to this point but what I want to do is when user gets to login page, I want to populate user's email into the email field and let user to enter his/her password to continue.
My email field looks like this:
<input type="email"
id="userLoginFormEmail"
class="form-control mb-4"
th:field="*{email}"
placeholder="Your email" required />
When the user gets redirected to login page, I'm adding user's email to model attribute like this:
model.addAttribute("userEmail", userEmail);
return "user/login";
So, how do I pre populate email field is userEmail attribute is not null?
UPDATE
I have an alert in the login page which appears fine when an activation url visited. It look like this
<div class="alert alert-info mt-5" role="alert" th:if="${userEmail != null}">
<strong>Your account is activated. Please login to proceed.</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
So, userEmail works fine but still can't show it in the email field.
In the controller, set the users email on the userEmail object (before the page is rendered).
Add the attribute th:value="userEmail" to the input field in the template

How to disable the validation of some fields in Joomla 3 registration

I'm building the website based on Joomla 3. I need to disable the validation of the fields: name, username, password1 (the second, because the first is password2) and email2 and use email1 as username (I installed the plugin Email for user authorization).
I have tried to remove these fields in file components/com_users/models/forms/registration.xml but the validation is still remaining. If I don't remove them but only change the rows required="true" to false for these fields the registration doesn't work at all and any user stored in the DB. How can I disable these fields?
It's not an easy workaround, and you will need some basic knowledge of Joomla and PHP, but I'll try to explain it to you as simple as i can.
>>> Creating view template override
First of all you will need to create your Registration view template override (to keep it Joomla update proof). To do so, create folder /templates/YOUT_TEMPLATE/html/com_users/registration and copy /components/com_users/views/registration/tmpl/default.php file there.
From now on you can modify registration output in your template folder.
>>> Modifying registration form output
By default Joomla takes all fields from form file /components/com_users/models/forms/registration.xml, where they are defined, and outputs them in a view. But if we don't want to use ALL the fields, we need to output fields manually.
My example code only output E-mail and Password fields for registration. Here's a sample code to do so: (default.php file)
<?php
defined('_JEXEC') or die;
JHtml::_('behavior.keepalive');
?>
<div class="grid_8" id="register_block">
<div class="content_block">
<h1>Registracija</h1>
<div class="login<?php echo $this->pageclass_sfx?>">
<form id="member-registration" action="<?php echo JRoute::_('index.php?option=com_users&task=registration2.register'); ?>" method="post" enctype="multipart/form-data">
<div>
<div class="login-fields">
<label id="jform_email1-lbl" for="jform_email1">E-mail:</label>
<input type="text" name="jform[email1]" id="jform_email1" value="" size="30">
</div>
<div class="login-fields">
<label id="jform_password1-lbl" for="jform_password1">Password:</label>
<input type="password" name="jform[password1]" id="jform_password1" value="" autocomplete="off" size="30">
</div>
<button type="submit" class="button"><?php echo JText::_('JREGISTER');?></button>
<input type="hidden" name="option" value="com_users" />
<input type="hidden" name="task" value="registration2.register" />
<?php echo JHtml::_('form.token');?>
</div>
</form>
</div>
</div>
</div>
Please note, that I've also replaced task value from registration.register to registration2.register, I did this to bypass some of validation rules using my own controller.
>>> Creating controller override
Locate file /components/com_users/controllers/registration.php and create a copy of it called registration2.php in same folder.
Open file registration2.php and change It's class name from UsersControllerRegistration to UsersControllerRegistration2
From now on Joomla registration form will use this class to create a new user.
Find a method called register and find this line:
$requestData = JRequest::getVar('jform', array(), 'post', 'array');
This is where Joomla get's registration form data. Add the following lines:
$requestData['name'] = $requestData['email1'];
$requestData['username'] = $requestData['email1'];
$requestData['email2'] = $requestData['email1'];
$requestData['password2'] = $requestData['password1'];
It will add missing registration info, and help you pass validation.
NOTE: This is a sample code, to show the main logic. If anyone has a better solution, I'd be more than happy to hear it.
Following same idea, a simpler solution might be just including hidden inputs with values in com_users\views\registration\tmpl\default.php above
<button type="submit" class="btn btn-primary validate"><?php echo JText::_('JREGISTER');?></button>
add
<input type="hidden" id="jform[username]" name="jform[username]" value="username" />
<input type="hidden" id="jform_name" name="jform[name]" value="name" />
It would pass the validation and you would no longer need to override controllers etc.

Resources