Input an enum value in a form as hidden using thymeleaf - spring-mvc

I would like to fill an form input hidden using a value of an Enum:
Enum:
public enum TipoEndereco {
Residencial, Comercial
}
Summarizing the html code, i've tried to use the form input like this:
<input type="hidden" th:field="*{endereco[0].tipoEndereco}" th:value="Residencial"/>
But unfortunately, this field is being recorded as null. The others fields that don't use Enum in this way, are being recorded normal. I've used Enum to fill an option, but directly as input type hidden isn't working. I'm using thymeleaf.

Related

HtmlInputText Name property is not working and replace by ID

I am creating a series of input text controls from asp.net codebehind. I am using the below code, but this code doesn't set the name attribute in input control instead ID is set to the name attribute of input control. How to make name attribute different from ID.
HtmlInputText sno = new HtmlInputText();
sno.ID = "txtSno" + j;
sno.Name = "txtSno-name";
sno.Value = snoList[i].ToString();
sno.Attributes.Add("class", "form-control");
cellsno.Controls.Add(sno);
This is the final html which is rendered
<input name="txtSno1" type="text" id="txtSno1" value="1" class="form-control">
Expected is
<input name="txtSno-name" type="text" id="txtSno1" value="1" class="form-control">
You can't change the name property of the input using the HtmlInputText object's Name property.As mentioned in Microsoft docs here
Use the Name property to determine the unique identifier name for an
HtmlInputControl. In this implementation, the get accessor returns the
value of the Control.UniqueID property. However, the set accessor does
not assign a value to this property.

ASP CORE: #Html.ValidationMessage migration to asp-validation-for or similar tag helper

How to setup the asp-validation-for with string value, not with expression?
I want to migrate the multiselect list:
#Html.ListBox("Privileges", ViewBag.PrivilegesMultiSelectList as MultiSelectList)
#Html.ValidationMessage("Privileges", "")
to
<select multiple="multiple" name="Privileges" asp-items="#ViewBag.PrivilegesMultiSelectList"></select>
<span asp-validation-for="Privileges" class="text-danger"></span>
But the last line is invalid:
Error CS1061 '...Model' does not contain a definition for 'Privileges'
and no accessible extension method 'Privileges' accepting a first
argument of type '..Model' could be found (are you missing a using
directive or an assembly reference?)
I want to stay using tag-helper because of consistency.
This asp-validation-for="Privileges" is trying to look for Privileges property in your model (not ViewBag). If it doesn't exist, it will give you that error. That line is the equivalent of ValidationMessageFor(), and afaik there's no equivalent in .net core for ValidationMessage().
Have a look at the asp-validation-for tag helper, which as stated should align with the name of another taghelper.
How to setup the asp-validation-for with string value, not with expression?
Again, there's no equivalent for ValidationMessage() it in TagHelpers. So you can just use #Html.ValidationMessage().
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-2.2
it's important to recognize that Tag Helpers don't replace HTML Helpers and there's not a Tag Helper for each HTML Helper.
You could also just write your own tag helper with the ValidationMessage HtmlHelper
Some advice from the docs regarding ViewBags:
We don't recommend using ViewBag or ViewData with the Select Tag Helper. A view model is more robust at providing MVC metadata and generally less problematic.
A better approach:
You will need to add the selected Privilege(s) to your model that you wish to return.
public class CustomViewModel {
[Required]
public string Privilege { get; set; } // update if you want to return multiple privileges
public List<SelectListItem> PrivilegesMultiSelectList { get; set; }
}
and then use that in your View #model CustomViewModel.
Using asp-for="Privilege" on your select, it becomes m => m.Privilege.
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-2.2
The asp-for attribute value is a special case and doesn't require a
Model prefix, the other Tag Helper attributes do (such as asp-items)
You can then just write it as such:
<select asp-for="Privilege" asp-items="#Model.PrivilegesMultiSelectList"></select>
<span asp-validation-for="Privilege" class="text-danger"></span>
I hope this helps.

view Calendar Objects in thymeleaf forms as date types

I have a user object, and the User is having a field DOB (Date of Birth) I have stored that field as a calendar inside the User BO.
Something like this:
public class UserBO {
private Calendar dateOfBirth;
public Calendar getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Calendar dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
}
Now I need to display this field as a Date field in thymeleaf and not a text field. I need a date field since I like the date picker :)
This is what I have so far
<label class="col-xs-2">Date of Birth</label>
<div class="col-xs-2">
<input type="date" class="form-control" th:field="*{dateOfBirth}" placeholder="Date of Birth" />
</div>
But this gives me the output as
this is not what I am expecting. I am expecting an actual date to be populated from the service but its showing me this as above.
I have read about Seralization & deserialization of Calendar objects and writing some sort of converters but I did not get full context why is this required. plus when I have seen examples with
input type="text" and the dates are populated correctly. SO can some one please guide me what is the fundamentals for this conversion and and example of how this should be done would be nice.
thanks
Firstly you need not use Calendar. A simple java.util.Date is sufficient.
So you can use bootstrap datepicker for client side date picker. Suppose the format the date picker expects is mm/dd/yyyy, then you can use Thymeleaf expression object to format the dateOfBirth as ${#dates.format(dateOfBirth, 'MM/dd/yyyy')}
Note that the format used by Thymeleaf is similar to the one used by SimpleDateFormat and the one used by Datepicker can be found from the docs here
When you are using input elements of type date, the date value should be always formatted as yyyy-mm-dd. The displayed date format will be chosen based on the set locale of the user's browser.
Try this code:
<input type="date" value="10/14/2016" class="form-control" id="dateOfBirth"
th:value="${#calendars.format(dateOfBirth,'yyyy-MM-dd')}" th:name="dateOfBirth" />

Pass Signed In user name to AngularJS controller using model binding

I am trying to pass the signed in user name in the application to an angular controller. I am already passing other parameters using model-binding like this and works perfectly
<input class="form-control" type="text" id="argOne" name="argOne" ng-model="viewModel.test.argumentOne" />
I tried passing the user name using a hidden input but I get an undefined value on the controller
<input class="form-control" type="hidden" id="argTwo" name="argTwo" ng-model="viewModel.test.argumentTwo" value=#UserManager.GetUserName(User) />
I've seen similar examples here, but nothing specific when getting a value directly from the UserManager class from ASP.NET core
Update: I am not asking how to display the Signed in user, the question is how can I pass that value to the angular controller using model binding like shown in the first line of code on the question, but with a hidden field or something similar that the user can't see
According to what you want to do, I'd suggest you to use scope variables to keep the username rather than keeping it in a hidden field. As what you want to keep is a username I'm assuming that you may need to use it in various controller throughout your angularjs app. So I'd rather keep it in application scope to take advantage of scope inheritance.
So What I'm suggesting looks like this :
In the HTML, you assign the username to the pertinent scope variable $rootScope.username :
<html ng-app="myApp" ng-init="$rootScope.username='#UserManager.GetUserName(User)'">
....
<div ng-controller="myController">
Your Username is : {{$rootScope.username}}
</div>
I the JS you can use it everywhere:
var app = angular.module('myApp',[]);
app.controller('myController',function(){
// you can use $scope.username in this code and it would be inherited from the $rootScope.username
...
});
you should change your code to this
var user = UserManager.GetUserName(User)
if(user)
{
$scope.userName = user;
}
<input class="form-control" type="hidden" id="argTwo" name="argTwo" ng-model="userName" />

TextBoxFor producing a blank field

I have a weird problem in my MVC app.
When the user selects a date from a drop down, it clears the StartDate and EndDate fields.
I have the following fragment of code:
<label>Start date: #Model.StartDate</label>
#Html.TextBoxFor(s => s.StartDate)
The weird thing is that you can wee where I'm outputting it in the label, the date comes out there. The textbox is unpopulated.
I've checked the produced markup and the textbox is not being populated.
<label>Start date: 19/05/2013</label>
<input id="StartDate" name="StartDate" type="text" value="" /> <br />
What am I missing here?
To add a little bit more information, when the page is initially populated the default start and end date are output. There is a bit of jQuery that empties those fields when a <select> is changed. If I comment that bit out then the fields retain their previous values as opposed to blank. Essentially, whatever is submitted to the server is output rather than the value in the model.
Essentially, whatever is submitted to the server is output rather than the value in the model.
This behaviour is actually by design. The idea being that generally the user would expect to see in the text box what they submitted to the server.
See here for a detailed explanation, and a work around.
Instead of doing this
<label>Start date: #Model.StartDate</label>
#Html.TextBoxFor(s => s.StartDate)
You should do this
<label id="someId"></label>
#Html.TextBoxFor(s => s.StartDate,new{#id="startdate"})
and using jquery on change event on your textbox you can set lablel
$("#startdate").change(function(){
var date="Start Date:"+$(this).val();
$("#someid").html(date);
});
Thinks that your model is a class named What like this:
public class What
{
public string StartDate { get; set; }
}
Then, think that your application is "MyApplication", you need to add to the view as if the view is stronglytyped:
#using MyApplication.Models;
#inherits System.Web.Mvc.WebViewPage<What>
Then all should we run as you expect

Resources