MVC3 Validation on view remains invalid due to DropDownList - asp.net-mvc-3

I've had to add a manual DropDownList within my Create View giving the user 2 options of 'input '.
Now the validation doesn't work when I come to save the information even though my code is now:
<div class="editor-field">
<select name="type" id="type">
<option value></option>
<option value="1" id="apple">Apple</option>
<option value="2" id="banana">Banana</option>
</select>
<span class="field-validation-valid" data-valmsg-for="type" data-valmsg-replace="true"></span>
How do I get the built in validation back on the 'Type'field. I have this as 'Required' within the model class.

your drop-down Name and ID should be a property of your model.
<select name="type" id="type">
include type as a Property in your Model and make it required.
public class myModel{
[Required]
public string type{get; set;}
}
being type a c# keyword I would suggest you to use something else as your property name for example "FruitDD"

Related

thymeleaf replacing th:field to comply with th:selected

I appreciate your passing by my post. I have searched here in StackOverFlow and google as well to fix my following code:
My HTML code:
<form th:action="#{/surgerywaitinglist/saveToWaitinList}"
th:object="${waitinglistDTO}" method="POST">
.
.
.
<select name="departmentName"
th:field="*{department.departmentName}"
th:with="departmentName = ${waitinglistDTO.department.departmentName}"
class="form-control" id="departmentJS">
<option value="" th:selected="selected"
th:disabled="disabled">select option
</option>
<option th:each="department: ${departments}"
th:value="${department.departmentName}"
th:text="${department.departmentName}">
</option>
</select>
.
.
.
<input type="submit" value="Save" class="btn btn-primary" />
</form>
form other posts like this post I found out that th:field and th:selected do not work together; in fact, th:field needs to be replace with something else. Notice that the th:object holds another object (from Department class) ...
My DTO class:
public class WaitinglistDTO {
private Long waitingListId;
#NotBlank(message = "Please enter a procedure")
private String waitingListProcedure;
private String waitingListDiagnosis;
private Long waitingListPatientId;
private Long waitingListSurgeonId;
private Long waitingListDepartmentId;
#DateTimeFormat(iso=ISO.DATE)
private Date waitingListAdditionDate;
#DateTimeFormat(iso=ISO.DATE)
private Date waitingListActualBookingDate;
private Patient patient;
private Surgeon surgeon;
private Department department;
Could you help me figure this out?
Many thanxxxxx :)
...
Update:
The following image explains how it should look,,, however, the default option should be the select option which should be somehow disabled
This is the result I get when I apply the suggested code of Rafael da Silva ,, you can see the pre-selected option is the first option rather than the select option option :)
you can do like this:
<select name="departmentName" th:field="*{department.departmentName}" th:with="departmentName = ${waitinglistDTO.department.departmentName}" class="form-control" id="departmentJS">
<option selected="selected" disabled="disabled">select option</option>
<option th:each="department : ${departments}" th:value="${department.departmentName}" th:text="${department.departmentName}"></option>
</select>
this worked for me.
I don't see why you would add the selected to the blank option, the first option is always selected if your model object has nothing set and if it does normal behaviour would be to have that item selected, which th:field should resolve.
In case you want the select to always start at the default option, even if the model has another value or want to set it some other way. you can set th:id="*{department.departmentName}" and th:name="*{department.departmentName}" and than manualy handle th:selected.
As a side note theres no need to use the th version th:selected="selected" if using static values just selected or selected="selected would sufice in that case
Edit with code, not tested as i don't have my work pc where i am.
If you want to always have the first option selected even when editing with previous data
<select name="departmentName" th:name="*{department.departmentName}" th:id="*{department.departmentName}" class="form-control" id="departmentJS">
<option selected disabled>select option</option>
<option th:each="department : ${departments}" th:value="${department.departmentName}" th:text="${department.departmentName}"></option>
</select>
If you want to fill with existing data but default to the first option
<select name="departmentName" th:field="*{department.departmentName}" class="form-control" id="departmentJS">
<option disabled>select option</option>
<option th:each="department : ${departments}" th:value="${department.departmentName}" th:text="${department.departmentName}"></option>
</select>
I'm not 100% sure on the use of disabled but i think it should work, personally i would just leave it selectable and enforce a #notnull on your bean in controller validation.
the th:with annotation does nothing asfar i can see, what th:with is used for is defining a new variable for all elements nested inside the elment you define it on. example:
<div th:with="newVar='someString'">
<span th:text="${newVar}"></span>
</div>

Get DropDownList value into POST method

I am working on this ASP.NET Core MVC where I have this DropDownLisit which gets its values from Controller using ViewBag.DishTypes. However, upon submitting the form, the POST method is not getting the value of the option selected in the DropDownList. The code snippets are as follows:
Controller: GET Method
var allDishTypes = _context.DishType
.ToList()
.Select(dt => new SelectListItem { Value = dt.DishTypeId.ToString(), Text = dt.DishTypeName.ToString() }).ToList();
ViewBag.DishTypes = allDishTypes;
return View();
View
<form asp-controller="Home" asp-action="AddMenuItems">
<div class="row">
<label class="my-1 mr-2" for="inlineFormCustomSelectPref">Dish Type</label>
<div class="input-group">
<div class="fg-line form-chose">
<label asp-for="DishTypeId" class="fg-labels" for="DishTypeId">Dish Type</label>
<select asp-for="DishTypeId" asp-items="ViewBag.DishTypes" class="form-control chosen" data-placeholder="Choose Dish Type" required name="dishtype" id="dishtype">
<option value=""></option>
</select>
</div>
</div>
....
Controller: POST Method
[HttpPost]
public IActionResult AddMenuItems([Bind("DishTypeId, DishName, Cost")] Dishes dishesObj)
{
....
}
the POST method is not getting the value of the option selected in the DropDownList
Note that you specified a name=dishtype within your code. By this way, the field name is
always the same as this name attribute, i.e, dishtype instead of DishTypeId, which will not be recognized by ASP.NET Core by default.
To fix that issue, simply remove that attribute such that it uses asp-for to generate the name attribute automatically:
<select asp-for="DishTypeId" asp-items="ViewBag.DishTypes"
class="form-control chosen" data-placeholder="Choose Dish Type" required
name="dishtype" id="dishtype"
>
<option value=""></option>
</select>

Why it appears the erro Non-static method should not be called statically in this context?

Im trying to use this package " dannyvankooten/laravel-vat" to load a select menu with the countries and then validate the vat number inserted in the input type text.
So I have this in a form:
<div class="form-group font-size-sm">
<select class="form-control" name="country" id="country">
#foreach($countries as $country)
<option value="{{$country}}">{{$country}}</option>
#endforeach
</select>
</div>
<div class="form-group font-size-sm">
<label for="vat" class="text-gray">VAT</label>
<input type="text" id="vat" name="vat" class="form-control" value="">
</div>
In the RegistrationController I have in a method this to return the $countries to the view to the select menu:
$countries = Countries::all();
But it appears:
Non-static method DvK\Laravel\Vat\Countries::all() should not be called statically
Do you know why?
In your specific case (laravel & facades), it's because you have imported the wrong class in your controller.
You need to replace
use DvK\Laravel\Vat\Countries;
with
use DvK\Laravel\Vat\Facades\Countries;
like shown in the readme # https://github.com/dannyvankooten/laravel-vat
The facade is what provides the static accessor e.g. Countries::all()
all is not a static method in the Countries class. You should first create an instance of Countries and then call its all method:
$countries = new Countries();
$allCountries = $countries->all();
return view('congress.registration', ['countries' => $allCountries]);

thymeleaf how to pass many objects?

how to pass many objects in one form? becouse like that not working.... help me please
<form class="form-control" action="#" th:action="#{'/'}" method="post">
<select>
<option th:each="city :${cities}" th:value="${city.getId()}" th:text="${city.getName()}"/>
</select>
<select>
<option th:each="category :${categories}" th:value="${category.getId()}" th:text="${category.getDescirption()}">
</option>
</select>
//this line isnt correct:
<a class="btn btn btn-primary btn-sm" href="#"
th:href="#{'/todo/done?id=' + ${city.id} + '&name=' + ${category.name}}">done</a>
</form>
You add each object as named model attribute. Example
#RequestMapping(value = "message", method = RequestMethod.GET)
public String messages(Model model) {
model.addAttribute("cities", citiesRepository.getAll());
model.addAttribute("categories", citiesRepository.getAll());
return "message/list";
}
Personally I find it more readable to have single object as model attribute. That object has fields for each actual attribute.
See official documentation for more details https://www.thymeleaf.org/doc/articles/springmvcaccessdata.html
In your example you are not using th:each correctly.
You should have th:each as select level (not at option level) then refer to individual items in nested select elements.
like
<select th:each="city :${cities}">
<option th:value="${city.getId()}" th:text="${city.getName()}"/>
</select>
In your last example you are refering to ${city.id} and ${category.name} but city and category are not defined (probably thymleaf error message tells you that).
What exactly you want to achieve? Do you want to link with selected city and category? If so, you need separate model attributes like
selectedCity and selectedCatetory.

Thymeleaf exception Neither BindingResult nor plain target object for bean name

Edited with #Crafalo suggestion
<form action="#" th:action="#{/admin/dict/adder}" th:object="${dictionary}" method="post">
<table>
<tr>
<td>Typ slownika:</td>
<td>
<select class="form-control" th:field="*{dict}" id="dropType">
<option value="0" th:text="select operator" ></option>
<option th:each="dict : ${dictList}" th:value="${dict.id}"
th:text="${dict.description}">Cos</option>
</select>
</td>
</tr>
Controller
List<Dictionary> dictList = dictService.findAllDictionaries();
model.addAttribute("dictionary", new Dictionary());
model.addAttribute("dictList", dictList);
Neither BindingResult nor plain target object for bean name 'dict' available as request attribute
In select/option i want have a parnet Dictionary in this form i need create a child Dictionary
I guess your problem is in your th:field
<select class="form-control" th:field="${dictionary.description}" id="dropType">
Should be
<select class="form-control" th:field="*{id}" id="dropType">
And in some place have the form
<form th:object="${dictionary}">
UPDATE:
You also need to send to the view the "dictionary" object in the model
model.addAttribute("dictionary", new Dictionary());
Another mistake is in your first option tag
th:text="select operator"
When you use the th: prefix is because you want to read some value from the controller, but if in this case you just want to write some fixed text, use a normal option tag, change it for:
<option value="0">select operator</option>

Resources