Springboot uploading files Required request part 'file' is not present - html

I'm trying to upload a image as a string field in an advert,but when adding a file to the body i got this error: "exception": "org.springframework.web.multipart.support.MissingServletRequestPartException", "message": "Required request part 'file' is not present".
I looked here for answers on this problem, but nothing helped me. I will be glad of any help.
My controller:
#Controller
#RequestMapping("/adverts")
public class AdvertController {
private AdvertService advertService;
private FileUploadService fileUploadService;
public AdvertController(AdvertService advertService, FileUploadService fileUploadService) {
this.advertService = advertService;
this.fileUploadService = fileUploadService;
}
#GetMapping("/showFormForAdd")
public String showFormForAdd(MultipartFile file, Model theModel) throws IOException {
Advert theAdvert = new Advert();
theModel.addAttribute("advert", theAdvert);
return "adverts/advert-form";
}
#PostMapping("/save")
public String saveAdvert(#RequestParam("file") MultipartFile file,
#AuthenticationPrincipal Account user,
#Valid #ModelAttribute("advert") Advert theAdvert,
BindingResult bindingResult) throws IOException {
if (bindingResult.hasErrors()) {
return "adverts/advert-form";
} else {
String filepath = fileUploadService.upload(file);
theAdvert.setFilename(filepath);
advertService.save(user, theAdvert);
}
return "redirect:/adverts/list";
}
}
My service:
#Service
public class FileUploadServiceImpl implements FileUploadService {
private String UPLOADED_FOLDER = "/images/";
#Override
public String upload(MultipartFile file) {
System.out.println(file);
if(file.isEmpty())
return null;
String fileName = null;
try {
fileName = generateFileName(Objects.requireNonNull(file.getOriginalFilename()));
byte[]bytes = file.getBytes();
Path path = Paths.get(UPLOADED_FOLDER + fileName);
Files.write(path, bytes);
} catch (IOException e) {
e.printStackTrace();
}
return "/resources/" + fileName;
}
private String generateFileName(String file){
String ext = file.substring(file.lastIndexOf("."));
return System.currentTimeMillis() + ext;
}
}
My html form for input:
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h3>Объявления о продаже недвижимости</h3>
<hr>
<p class="h4 mb-4">Добавить новое объявление в систему</p>
<form action="#" th:action="#{/adverts/save}"
th:object="${advert}" method="POST" enctype="multipart/form-data">
<!-- Add hidden form field to handle update -->
<input type="hidden" th:field="*{id}" />
<input type="text" th:field="*{title}"
class="form-control mb-4 col-4" placeholder="Название"/>
<p th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="alert alert-danger col-4" >Title Error</p>
<input type="file" name="file_upload"
class="form-control mb-4 col-4" placeholder="Изображение">
<!-- <input type="file" name="file"/>-->
<!-- <input type="hidden" class="form-control" th:field="*{photo}" placeholder="Enter Image"/>-->
<input type="text" th:field="*{price}"
class="form-control mb-4 col-4" placeholder="Цена">
<p th:if="${#fields.hasErrors('price')}" th:errors="*{price}" class="alert alert-danger col-4" >Price Error</p>
<input type="text" th:field="*{description}"
class="form-control mb-4 col-4" placeholder="Описание">
<p th:if="${#fields.hasErrors('description')}" th:errors="*{description}" class="alert alert-danger col-4" >Description Error</p>
<button type="submit" class="btn btn-info col-2">Добавить</button>
</form>
<a th:href="#{/adverts/list}">Назад к списку объявлений</a>
</div>
</body>
</html>

Change
<input type="file" name="file_upload" class="form-control mb-4 col-4" placeholder="Изображение">
To
<input type="file" name="file" class="form-control mb-4 col-4" placeholder="Изображение">
Your controller expects a param file, but from html you are sending file_upload. Thats why spring shows error message "Required request part 'file' is not present"

Related

Cant post the data using Modal with Ajax in Razor Pages

This is the index file code:
public IList<Employee> Employee { get; set; }
public async Task OnGetAsync()
{
Employee = await _context.Employee.ToListAsync();
}
public JsonResult EmployeeList()
{
var data = _context.Employee.ToList();
return new JsonResult(data);
}
[HttpPost]
public JsonResult AddEmployee(Employee e)
{
var emp = new Employee()
{
Name = e.Name,
Age = e.Age,
Email = e.Email
};
_context.Employee.Add(emp);
_context.SaveChanges();
return new JsonResult("Success!!!");
}
Button to open Modal:
<button class="btn btn-info mb-3" id="btn1">Add Employee</button>
The Modal:
<!-- The Modal -->
<div class="modal Add-Emp">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Add Employee</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<!-- Modal body -->
<div class="modal-body">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label>Name</label>
<input type="text" placeholder="Enter Name" class="form-control" id="Name" autocomplete="off"/>
</div>
<div class="form-group">
<label>Age</label>
<input type="text" placeholder="Enter Age" class="form-control" id="Age" autocomplete="off"/>
</div>
<div class="form-group">
<label>Email</label>
<input type="text" placeholder="Enter Email" class="form-control" id="Email" autocomplete="off"/>
</div>
</form>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button class="btn btn-primary" onclick="AddEmployee();">Save</button> I
<button class="btn btn-danger btn-default" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
The Js Code:
$("#btn1").click(function () {
$(".Add-Emp").modal("show")
})
function AddEmployee() { debugger
var objData = { Name: $("#Name").val(), Age: $("#Age").val(), Email: $("#Email").val() }
$.ajax({
url: "Pages/Employees/Index/AddEmployee",
type: "Post",
data: objData,
contentType: "application/xxx-www-form-url-encoded; charset=utf-8",
dataType: "json",
success: function () { alert("Data Saved"); },
error: function () { alert("Error!!!"); }
})
}
Modal opens on click But data does not get posted on clicking the save button it displays alert "Error!!!" defined in failure of ajax requestㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
1.You maybe not familiar with Razor Pages, Razor pages uses OnGet and OnPost to deal with the Http Get and Post request. If you need another Get or Post method in current PageModel, you need define the method name like: OnGetHandlerName or OnPostHandlerName.
2.If your .cshtml.cs file located like: Pages/Employees/Index.cshtml.cs, the request url should be:/Employees/Index. If you set the handler in your PageModel, the request url should be:/Employees/Index?handler=xxx.
3.For how to use Ajax in Razor Pages, Razor Pages enable anti-forgery token validation by default, so you need add this token to header in ajax.
If you use form in Razor Pages, it will default generate an input with token. If not, you need add #Html.AntiForgeryToken() manually.
A whole working demo you could follow:
Page(Pages/Employees/Index.cshtml):
#page
#model IndexModel
<button class="btn btn-info mb-3" id="btn1">Add Employee</button>
<div class="modal Add-Emp">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Add Employee</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<!-- Modal body -->
<div class="modal-body">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label>Name</label>
<input type="text" placeholder="Enter Name" class="form-control" id="Name" autocomplete="off" />
</div>
<div class="form-group">
<label>Age</label>
<input type="text" placeholder="Enter Age" class="form-control" id="Age" autocomplete="off" />
</div>
<div class="form-group">
<label>Email</label>
<input type="text" placeholder="Enter Email" class="form-control" id="Email" autocomplete="off" />
</div>
</form>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button class="btn btn-primary" onclick="AddEmployee();">Save</button> I
<button class="btn btn-danger btn-default" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
#section Scripts
{
<script>
$("#btn1").click(function () {
$(".Add-Emp").modal("show")
})
function AddEmployee() {
debugger
var objData = { Name: $("#Name").val(), Age: $("#Age").val(), Email: $("#Email").val() }
$.ajax({
url: "/Employees/Index?handler=AddEmployee",
type: "Post",
data: JSON.stringify(objData), //change here...
contentType: "application/json; charset=utf-8", //change here...
headers: {
RequestVerificationToken:
$('input:hidden[name="__RequestVerificationToken"]').val()
}, //add this....
dataType: "json",
success: function () { alert("Data Saved"); },
error: function () { alert("Error!!!"); }
})
}
</script>
}
Pages/Employees/Index.cshtml.cs:
public class IndexModel : PageModel
{
//...
public IList<Employee> Employee { get; set; }
public async Task OnGetAsync()
{
Employee = await _context.Employee.ToListAsync();
}
public JsonResult OnGetEmployeeList()
{
var data = _context.Employee.ToList();
return new JsonResult(data);
}
public JsonResult OnPostAddEmployee([FromBody]Employee e)
{
var emp = new Employee()
{
Name = e.Name,
Age = e.Age,
Email = e.Email
};
return new JsonResult("Success!!!");
}
}

not-null property references a null or transient value ERROR

i'M HAVING A TROUBLE WITH AN PROJECT, AN EXCEPTIONS IS RETURNED TO ME, I tried editing the model by trying to remove the nullable = true constraint, but the porblem persists
org.hibernate.PropertyValueException: not-null property references a null or transient
value
nested exception is org.hibernate.PropertyValueException: not-null property references
a null or transient value
org.springframework.dao.DataIntegrityViolationException: not-null property references a
null or transient value :
I attach below the structure of my project
Controller
#Controller
public class TemperatureController {
#Autowired
private TemperatureService temperatureService;
#RequestMapping(value="/", method= RequestMethod.GET) // inserisco il controllo per la
chiamata alla pagina principale
public ModelAndView homePage() { // creo un modelandview
ModelAndView mv = new ModelAndView(); // creo un'istanza del modelandView
mv.setViewName("home"); // setto il nome dell'istanza
List<InfoMeteo> listaIndicatoriMeteo = temperatureService.getAll();
mv.addObject("listaIndicatoriMeteo",listaIndicatoriMeteo);
mv.addObject("indicatoreMeteo", new InfoMeteo()); // creo la lista
return mv; // ritorno l'istanza
}
#RequestMapping(value="/", method= RequestMethod.POST)
public ModelAndView saveIndicatoriMeteo(InfoMeteo indicatoreMeteo) {
temperatureService.saveIndicatoriMeteo(indicatoreMeteo);
return new ModelAndView("redirect:/");
}
}
Model
#Entity
#Table(name="gestioneindicatorimeteo")
public class InfoMeteo implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO) // uso l'autoincrement
private long id;
#Column(name="Data")
private Date Data;
#Column(name="TemperaturaMax", nullable= false)
private byte TemperaturaGiornalieraMax;
#Column(name="TemperaturaMin", nullable= false)
private byte TemperaturaGiornalieraMin;
#Column(name="precipitazioni")
private String precipitazioni;
#Column(name="Quantità", nullable= false)
private byte quantitaprec;
#Column(name="Tempo", nullable= false)
private String tempo;
#Column(name="URMax", nullable= false)
private byte umiditaMax;
#Column(name="URMin", nullable= false)
private byte umiditaMin;
#Column(name="WSPDMax", nullable= false)
private short velocitaVentoMax;
#Column(name="WSPDMin", nullable= false)
private short velocitaVentoMin;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Date getData() {
return Data;
}
public void setData(Date data) {
Data = data;
}
public byte getTemperaturaGiornalieraMax() {
return TemperaturaGiornalieraMax;
}
public void setTemperaturaGiornalieraMax(byte temperaturaGiornalieraMax) {
TemperaturaGiornalieraMax = temperaturaGiornalieraMax;
}
public byte getTemperaturaGiornalieraMin() {
return TemperaturaGiornalieraMin;
}
public void setTemperaturaGiornalieraMin(byte temperaturaGiornalieraMin) {
TemperaturaGiornalieraMin = temperaturaGiornalieraMin;
}
public String getPrecipitazioni() {
return precipitazioni;
}
public void setPrecipitazioni(String precipitazioni) {
this.precipitazioni = precipitazioni;
}
public byte getQuantitaprec() {
return quantitaprec;
}
public void setQuantitaprec(byte quantitaprec) {
this.quantitaprec = quantitaprec;
}
public String getTempo() {
return tempo;
}
public void setTempo(String tempo) {
this.tempo = tempo;
}
public byte getUmiditaMax() {
return umiditaMax;
}
public void setUmiditaMax(byte umiditaMax) {
this.umiditaMax = umiditaMax;
}
public byte getUmiditaMin() {
return umiditaMin;
}
public void setUmiditaMin(byte umiditaMin) {
this.umiditaMin = umiditaMin;
}
public short getVelocitaVentoMax() {
return velocitaVentoMax;
}
public void setVelocitaVentoMax(short velocitaVentoMax) {
this.velocitaVentoMax = velocitaVentoMax;
}
public short getVelocitaVentoMin() {
return velocitaVentoMin;
}
public void setVelocitaVentoMin(short velocitaVentoMin) {
this.velocitaVentoMin = velocitaVentoMin;
}
}
Repository
#Repository("TemperatureRepository")
public interface TemperatureRepository extends JpaRepository<InfoMeteo, Long> {
}
Service
public interface TemperatureService {
void saveIndicatoriMeteo(InfoMeteo indicatoreMeteo);
List<InfoMeteo> getAll();
}
Service implementation
#Service("TemperatureService")
public class TemperatureServiceImpl implements TemperatureService {
#Autowired
private TemperatureRepository temperatureRepository; // inietto per dipendenza il
service del repository
#Override
public void saveIndicatoriMeteo(InfoMeteo indicatoreMeteo) {
temperatureRepository.save(indicatoreMeteo);
}
#Override
public List<InfoMeteo> getAll() {
return temperatureRepository.findAll();
}
}
Home.html
<!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Home Page</title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.bundle.min.js">
</head>
<body>
<div class="container">
<div class="pb-3 mt-4 mb-2">
<div class = "btn btn-primary" >
</div>
<h2>Gestione Meteo - <small>Lista Indicatori Meteo</small></h2>
</div>
</div>
<div class="col-md-5" style="margin-top:50px;margin-bottom:50px;">
<form method="post" th:action="#{/}" th:object = "${indicatoreMeteo}">
<div class="form-group">
<label for= "data">Data</label>
<input type="text" " field="*{Data}" id="data>
class="form-control" required>
</div>
<div class="form-group">
<label for= "TemperaturaMax">Temperatura Max</label>
<input type="text" field="*{TemperaturaGiornalieraMax}" id="TemperaturaMax"
class="form-control" required>
</div>
<div class="form-group">
<label for= "TemperaturaMin">Temperatura Min</label>
<input type="text" id="TemperaturaMin"
field="*{TemperaturaGiornalieraMin}"
class="form-control" required>
</div>
<div class="form-group">
<label for= "precipitazioni">Precipitazioni (prp)</label>
<input type="text" id="precipitazioni"
field="*{precipitazioni}"
class="form-control" required>
</div>
<div class="form-group">
<label for= "Quantità">Quantità precipitazioni</label>
<input type="text" id="Quantità"
field="*{quantitaprec}"
class="form-control" required>
</div>
<div class="form-group">
<label for= "Tempo">Condizioni meteo</label>
<input type="text" id="Tempo"
field="*{tempo}"
class="form-control" required>
</div>
<div class="form-group">
<label for= "URMax">Ur max (Umidità)</label>
<input type="text" id="URMax"
field="*{umiditaMax}"
class="form-control" required>
</div>
<div class="form-group">
<label for= "URMin">Ur Min (Umidità)</label>
<input type="text" id="URMin"
field="*{umiditaMin}"
class="form-control" required>
</div>
<div class="form-group">
<label for= "WSPDMax">Velocità vento Min (Wv)</label>
<input type="text" id="WSPDMax"
field="*{velocitaVentoMax}"
class="form-control" required>
</div>
<div class="form-group">
<label for= "WSPDMin">Velocità vento Max(Wv)</label>
<input type="text" id="WSPDMin"
field="*{velocitaVentoMin}"
class="form-control" required>
</div>
<button style="margin-top:50px;" type="submit"
class="btn btn-dark"> Salva indicatori Meteo</button>
</form>
</div>
<table class="table table-striped">
<div table= "pb-2 mt-4 mb-3">
<thead>
<tr>
<th scope="col">Data</th>
<th scope="col">Temperatura Max giornaliera</th>
<th scope="col">Temperatura Min giornaliera</th>
<th scope="col">precipitazioni</th>
<th scope="col">Tipo di precipitazioni</th>
<th scope="col">Quantita prec </th>
<th scope="col">Condizioni meteo</th>
<th scope="col">Umidita Max</th>
<th scope="col">Umidita Min</th>
<th scope="col">Velocita Vento Max</th>
<th scope="col">Velocita Vento Min</th>
</tr>
<tbody>
<tr th:each="indicatoreMeteo: ${listaIndicatoriMeteo}">
<td th:text= "${indicatoreMeteo.Data}"></td>
<td th:text= "${indicatoreMeteo.TemperaturaGiornalieraMax}"></td>
<td th:text= "${indicatoreMeteo.TemperaturaGiornalieraMin}"></td>
<td th:text= "${indicatoreMeteo.precipitazioni}"></td>
<td th:text= "${indicatoreMeteo.quantitaprec}"></td>
<td th:text= "${indicatoreMeteo.tempo}"></td>
<td th:text= "${indicatoreMeteo.umiditaMax}"></td>
<td th:text= "${indicatoreMeteo.umiditaMin}"></td>
<td th:text= "${indicatoreMeteo.velocitaVentoMax}"></td>
<td th:text= "${indicatoreMeteo.velocitaVentoMin}"></td>
</tbody>
</table>
I have tried different solutions but it keeps giving me this kind of exception all the time, I don't know what to do

convert asynchronous onSuccess into a promise and do await

I have html page with inputs
<!doctype html>
<html lang="en">
<head>
<title>CLR: PACKING</title>
<meta charset = "UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<?!= include("index-css"); ?>
</head>
<body>
<div class="conteiner">
<form novalidate>
<h6 class="title">PACKING</h6>
<div class="dws-input">
<div class="col-md-3"></div>
<div>
<div>
<button id="del" type="button"><RESET</button>
</div>
<div class="form-floating mb-3 mt-3">
<input type="text" class="form-control" novalidate id="tLogin" name= "username" placeholder= "Логин:" autofocus >
<label for="tLogin">Login:</label>
</div>
<div class="form-floating mb-3 mt-3">
<input type="text" class="form-control" novalidate id="tTable" name= "text" placeholder= "Номер стола:" >
<label for="tTable">Table:</label>
</div>
</div>
<div class="form-floating mb-3 mt-3">
<input type="text" novalidate class="form-control" id="tOrder" name= "text" placeholder= "Заказ:" >
<label for="tOrder">Order:</label>
</div>
</div>
</form>
</div>
<?!= include("index-js"); ?>
</body>
</html>f
In include(index-js.html) I wrote this
<script>
var curInpID;
var findData;
function keyPressFunction(ev) {
var inputData = ev.target.value;
if (ev.code !== 'Enter') return;
curInpID = ev.target.id;
google.script.run.withSuccessHandler(onSuccess).searchData(inputData);
console.log(findData); //result onSuccess here
for (const i of formControl) {
if (i.value === '') {
i.nextElementSibling.focus();
break;
}
}
}
function onSuccess(_findData) {
findData = _findData;
}
</script>
onSuccess goes to apps script, check value at input there and return true/false in findData
function searchData(data){
for (let i = 0; i < arrLogins.length; i++){
if(arrLogins[i].indexOf(login)!==-1){
firstValid = true;
return firstValid;
}
}
firstValid = false;
return firstValid;
}
Because of onSuccess is asynchronous, this way works slowly and sometimes returns wrong value to the findData. In the previous topic, a colleague suggested to me to convert it into a promise and do await.
I found some examples with async, await and promise on this site, but I can't understand, what I need to transform here. Please, help me! Thank you!

Trying to send data from html to google spreadsheet by fetch and post

I'm trying to go like author in youtube here
https://www.youtube.com/watch?v=yiPnkBEHqf0&list=PLRmEk9smitaVGAAhgU0Pdc2sEs7yxDrEk&index=2
the task to send data to google spreadsheet from html to spreadsheet
this script I wrote from js with fetch:
const url = "https://script.google.com/macros/s/AKfycbzPNAtqRkYrkbJ8SuDu5mLrtn8A3syzkU7CwzXHUEHXTxJbSLKn/exec";
var loginText = document.getElementById("tLogin");
var tableText = document.getElementById("tTable");
var orderText = document.getElementById("tOrder");
function testGS(){
var userInfo = {
login: loginText.value,
table: tableText.value,
order: orderText.value,
tdate: new Date().toLocaleDateString(),
//komm: kommText.value,
};
fetch(url, {
method: 'POST',
body: JSON.stringify(userInfo)
})
.then((res) => res.text())
.then((res) => console.log(res));
}
document.getElementById("del").addEventListener("click", testGS);
This I wrote in Apps script:
<!-- begin snippet: js hide: false console: true babel: false -->
The html-page is here.
<!doctype html>
<html lang="en">
<head>
<title>CLR: PACKING</title>
<meta charset = "UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="CSS/main_page_style.css">
<link rel="icon" href="Image/favicon.png" type="png">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
</head>
<body>
<div class="conteiner">
<form novalidate>
<h6 class="title">PACKING</h6>
<img src="Image/mainImg.jpg" class="img-fluid" alt="...">
<div class="dws-input">
<div class="col-md-3"></div>
<div>
<div>
<button id="del" type="button"><======СБРОС</button>
</div>
<div class="form-floating mb-3 mt-3">
<input type="text" class="form-control" novalidate id="tLogin" name= "username" placeholder= "Логин:" autofocus >
<label for="tLogin">Логин:</label>
</div>
<div class="form-floating mb-3 mt-3">
<input type="text" class="form-control" novalidate id="tTable" name= "text" placeholder= "Номер стола:" >
<label for="tTable">Номер стола:</label>
</div>
</div>
<div class="form-floating mb-3 mt-3">
<input type="text" novalidate class="form-control" id="tOrder" name= "text" placeholder= "Заказ:" >
<label for="type3">Заказ:</label>
</div>
</div>
</form>
</div>
<script src="JS/fetchNew.js"></script>
</body>
</html>
Js-script with fetch must be start by clicking button "del" and data must go to spreadsheet. But I take some errors. I have broke my brain, I tryed to reinstall node.js, clasp, tried to login again, prn init, republished my project, but mistake is the same
Can you help me what I forgot? Thank you for help!
The path with spreadsheet is here https://drive.google.com/drive/folders/1JwWgndNrcM2hgxyE3CBF0SKOxZarwCCf?usp=sharing

Dropdown validation for default value

I need help on how to validate the default value on a select dropdown list. What I have now doesn't show the validation on the view because I have '--Select--' as the first value. What can I do to get the validation to work. It works for Order, Title, URL but not for the select dropdown. I added a value = "0" and added Range attribute in view model.
Edit: I have to change this so it uses validation summary instead of using the tags for each field but I still can't get the validation messages to show.
<form id="form-create-link" method="post" asp-controller="Link"
asp-action="CreateLink">
<div class="form-group col-md-8">
**<div asp-validation-summary="ModelOnly" id="validation-error" hidden
class="text-danger custom-validation-summary"></div>
</div>**
<input id="link-id" asp-for="#Model.LinkId" type="hidden" />
<input name="FetchCategories" type="hidden"/>
<div class="form-group col-md-8 col-lg-4">
<div class="form-group">
#{
var authorizedCommitteeTypes = await Model.CommitteeType
.ToSelectListAsync(AuthorizationService, User,
AuthRequirements.AdminCommitteeType);
if (authorizedCommitteeTypes.Count == 1)
{
<input id="committeeType" name="committeeType" type="hidden"
value="#authorizedCommitteeTypes.FirstOrDefault()?.Value" />
}
else
{
<label class="control-label">Committee Type</label>
<select id="add-edit-committee-type"
name="committeeType"
asp-for="#Model.CommitteeType"
asp-items="#authorizedCommitteeTypes"
class="form-control">
</select>
}
}
</div>
</div>
<div class="form-group col-md-8 col-lg-4">
<label class="control-label">Category</label>
#{
if (Model != null && Model.AvailableCategories != null)
{
var availableCategories =
new SelectList(
Model.AvailableCategories.OrderBy(c => c.Order),
dataValueField: "CategoryId",
dataTextField: "Title",
selectedValue: Model.CategoryId);
<select id="dropdown-linkCategories" required
asp-for="#Model.CategoryId"
asp-items="#availableCategories"
class="form-control">
<option>-- Select --</option>
</select>
}
else
{
<select id="dropdown-linkCategories"
class="form-control">
<option>-- Select --</option>
</select>
}
}
</div>
<div class="form-group col-md-8 col-lg-4">
<label class="control-label">Title</label>
<input id="title" asp-for="Title" name="Title" class="form-control" />
</div>
<div class="form-group col-md-8 col-lg-4">
<label class="control-label">Display Order</label>
<div>
<input id="order" asp-for="Order" name="Order" class="form-control" />
</div>
</div>
<div class="form-group col-md-8 col-lg-4">
<label class="control-label">URL</label>
<input id="url" asp-for="URL" name="URL" class="form-control" />
</div>
<div class="form-group col-md-8 col-lg-12">
<label class="control-label">Description</label>
<textarea class="rtextDescription" name="Description" id="Description"
row="1" cols="60"
data-val-maxlength-max="200" asp-for="Description"
data-val-maxlength="Max length for Description is 200"></textarea>
</div>
<div class="form-group col-md-8 col-lg-12">
<label class="check " >
Add Another
<input type="checkbox" name="AddAnother">
<span class="checkmark"></span>
</label>
</div>
#{
if (Model.LinkId == 0)
{
<div class="form-group col-md-12">
<input type="submit" id="link-submit"
class="btn btn-forum col-sm-12 col-md-4 col-lg-4"
value="Add & Return to Links" />
<a asp-area="Admin"
asp-controller="Link"
asp-action="Index"
class="btn btn-forum col-sm-12 col-md-2 col-lg-2">Back to
Links</a>
</div>
}
else
{
<div class="form-group col-md-8 col-lg-12">
<input type="submit" value="Save" id="edit-submit"
class="btn btn-forum col-sm-12 col-md-2 col-lg-2" />
<a asp-area="Admin"
asp-controller="Link"
asp-action="Index"
class="btn btn-forum col-sm-12 col-md-2 col-lg-2">Back to
Links</a>
</div>
}
}
</form>
According to your code, it seems that the View Model contains the selected properties (such as: CommitteeType, CategoryId), after selecting item from the DropDownlist, we could get the selected value from these properties. So, to validate the DropDownList, we could add the validate attribute to these selected properties.
You could refer the following sample, it will create a custom validation attribute to check whether the selected value is valid or not:
Models:
public class Categories
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
}
public class Order
{
[Required]
public int OrderId { get; set; }
[Required]
public string Title { get; set; }
[CheckSelctedValue(ErrorMessage ="Please select a valid category")]
public string CategoryId { get; set; } //DropDownList selected value
public List<Categories> AvailableCategories { get; set; } //DropDownList select items.
}
Here, create a custom validation attribute to check whether the selected value is valid or not.
public class CheckSelctedValue : ValidationAttribute
{
public override bool IsValid(object value)
{
int number;
//get the selected value and according to the condition to check whether the value is valid or not.
//try to convert the selected value to int.
bool success = int.TryParse(value.ToString(), out number);
//if the number is 0, it means user select the first item.
if (success && number !=0)
{
return true;
}
else
{
return false;
}
}
}
Controller:
public IActionResult CreateOrder()
{
Order o = new Order();
o.OrderId = 1001;
o.Title = "AA";
o.AvailableCategories = new List<Categories>()
{
new Categories(){ CategoryID=101, CategoryName="Meat"},
new Categories(){ CategoryID=102, CategoryName="Fruit"},
new Categories(){ CategoryID=102, CategoryName="Vegetables"}
};
o.CategoryId = "101";
return View(o);
}
[HttpPost]
public IActionResult CreateOrder(Order order)
{
//used to set the select items for the dropdownlist.
order.AvailableCategories = new List<Categories>()
{
new Categories(){ CategoryID=101, CategoryName="Meat"},
new Categories(){ CategoryID=102, CategoryName="Fruit"},
new Categories(){ CategoryID=102, CategoryName="Vegetables"}
};
if (ModelState.IsValid)
{
}
return View(order);
}
Code in the View Page (add value="0" to the dropdownlist first option):
#model netcore5.Models.Order
<div class="row">
<div class="col-md-4">
<form asp-action="CreateOrder">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="OrderId" class="control-label"></label>
<input asp-for="OrderId" class="form-control" />
<span asp-validation-for="OrderId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CategoryId" class="control-label"></label>
<select id="dropdown-linkCategories" required
asp-for="CategoryId"
asp-items="#(new SelectList(Model.AvailableCategories, "CategoryID","CategoryName", Model.CategoryId))"
class="form-control">
<option value="0">-- Select --</option>
</select>
<span asp-validation-for="CategoryId" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
The output as below:
Edit
I updated my code. I have to use the validation summary that is at the
top of the form but I can't get the validation messages to show.
<div asp-validation-summary="ModelOnly" id="validation-error" hidden class="text-danger custom-validation-summary"></div>
The issue is related to the above code.
First, if we want to show the validation message summary, we should set the asp-validation-summary attribute to All, instead of ModelOnly. More detail information, see The Validation Summary Tag Helper.
Second, since you are using hidden attribute, it will hide the validation message, so, try to remove the hidden attribute.
After updated, the code should be as below:
<div asp-validation-summary="All" id="validation-error"
class="text-danger custom-validation-summary"></div>