Spring MVC Controller not receiving atribute from Template with Thymeleaf - spring

I have a template which represents a list of notes that are retrieved from a database
<tr th:unless="${#lists.isEmpty(allNotes)}"
th:each="note : ${allNotes}">
<td>
<form action="#" method="POST" th:action="#{/home/editNote}"
th:object="${note}">
<input type="hidden" id="noteId" name="noteId" th:value="*{noteId}">
<button type="button" class="btn btn-success"
onclick="editNoteModal('updateNote', this.getAttribute('data-noteId'),
this.getAttribute('data-noteTitle'),
this.getAttribute('data-noteDescription'))">Edit
</button>
</form>
<form action="#" method="POST" th:action="#{/home/deleteNote}">
<input type="hidden" name="noteId" th:value="*{note.noteId}">
<a class="btn btn-danger">Delete</a>
</form>
</td>
<th scope="row" th:text="${note.noteTitle}">Example Note Title</th>
<td th:text="${note.noteDescription}">Example Note Description</td>
</form>
</tr>
</tbody>
In the GUI It looks like this
This is my modal code which should open after I click on the edit button:
<div class="modal fade" id="editNoteModal" tabindex="-1" role="dialog" aria-labelledby="noteModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editnoteModalLabel">Note</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="note-title" class="col-form-label">Title</label>
<input type="text" name="noteTitle" class="form-control" id="editNoteTitle"
maxlength="20" required>
</div>
<div class="form-group">
<label for="note-description" class="col-form-label">Description</label>
<textarea class="form-control" name="noteDescription" id="editNoteDescription"
rows="5" maxlength="1000" required></textarea>
</div>
<button id="editNoteSubmit" type="submit" class="d-none"></button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="$('#editNoteModal').click();">
Save
changes
</button>
</div>
</div>
</div>
</div>
</div>
In the GUI it looks like this:
I want to be able to edit given note and then send the edited id to the controller so I can update this change within the database. I have correct database logic for the update, I just don't know the way how to send the given notes id and changed information to my controller.
#PostMapping("/editNote")
public String editNote(#ModelAttribute(value = "note") Note note,
#ModelAttribute(value = "noteId") NoteIdModel noteIdModel, Model model,
Authentication authentication) {
System.out.println("noteid " + note.getNoteId());
System.out.println("noteidHidden " + noteIdModel.getNoteIdHidden());
System.out.println("notedesc" + note.getNoteDescription());
noteService.editNote(note, authentication);
return "result";
}
However, the incoming noteId is null. I have checked the database and the note with correct id is indeed in the database and is also retrieved from the database. It's just not sent to the controller.

Try this one:
HTML fragment
<tr th:unless="${#lists.isEmpty(allNotes)}"
th:each="note : ${allNotes}">
<td>
<button type="button" class="btn btn-success"
th:data-noteId="${note.noteId}"
th:data-noteTitle="${note.noteTitle}"
th:data-noteDescription="${note.noteDescription}"
onclick="editNoteModal('updateNote', this.getAttribute('data-noteId'),this.getAttribute('data-noteTitle'),this.getAttribute('data-noteDescription'))">Edit
</button><br/>
<a class="btn btn-danger">Delete</a>
</td>
<td scope="row" th:text="${note.noteTitle}"></td>
<td th:text="${note.noteDescription}"></td>
</tr>
JS fragment
/**
* Fill edit modal with current information
*/
function editNoteModal(modal, noteId, noteTitle, noteDescription) {
$('#editnoteModalLabel').text("Note " + noteId);
$('#editNoteId').val(noteId);
$('#editNoteTitle').val(noteTitle);
$('#editNoteDescription').val(noteDescription);
$('#editNoteModal').modal("show");
}
/**
* Save to backend edit information
*/
function save() {
var noteId = $('#editNoteId').val();
var noteTitle = $('#editNoteTitle').val();
var noteDescription = $('#editNoteDescription').val();
$.ajax({
url : "./editNote",
method : "POST",
headers : {
'Content-Type' : 'application/json'
},
data : JSON.stringify({
noteId : noteId,
noteTitle : noteTitle,
noteDescription : noteDescription
}),
success : function(result) {
$('#editNoteModal').modal("hide");
alert(result);
}
})
}
Backend
#PostMapping(path = "/editNote", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> editNote(#RequestBody Note note) {
System.out.println("noteid " + note.getNoteId());
System.out.println("noteidTitle " + note.getNoteTitle());
System.out.println("notedesc" + note.getNoteDescription());
//Save in database
return ResponseEntity.ok("OK");
}

This is how I did while I was trying to pass the id to open a modal by finding details using that id:
<a href="#" class="btn btn-sm btn-primary"
th:data-parameter1="${user.useruuid}"
onclick="openUserModal(this.getAttribute('data-parameter1'));">Details</a>
And then somewhere in your JavaScript, you can something (similar) like this:
<script type="text/javascript" th:fragment="includeModalScript">
function openUserModal(id) {
$.ajax({
url: "/findOnebyId?id="+ id,
success: function(data){
alert(id);
.......
</script>
And my controller looked like this:
#GetMapping("/findOnebyId")
#ResponseBody
public AppUser findOneByUUID(String id) {
....
}
You can take a look here, here and here for a working demo similar to your issue/requirement.

Related

How to update a table row by passing data from a Bootstrap modal form

I'm fresh in web development and I'm facing some problems
I have an html page that displays a table. Each row contains data and an "edit" button.
What I want is the following:
I already could invoke the modal form and make it pop up with data corresponding to the row's data (through the button "edit") before I add this code to my form tag th:action="#{/countries/update/{id} (id =${countryToUpdate.id})}" and hence I get this following error:
org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'id' cannot be found on null
I know that the passed model attribute countryToUpdateis null
I'm asking if it's possible to pass a model attribute to a the bootstrap modal form
That's my html table:
<table class="table">
<tr>
<th>Id</th>
<th>Description</th>
<th>Capital</th>
<th>Code</th>
<th>Actions</th>
</tr>
<tr th:each="country:${countries}">
<td th:text="${country.id}"></td>
<td th:text="${country.description}"></td>
<td th:text="${country.capital}"></td>
<td th:text="${country.code}"></td>
<td>
<!--Edit button to invoke the bootstrap form-->
<div class="btn-group">
<a th:href="#{/countries/findById/{id} (id=${country.id})}" class="btn btn-primary editModalBtn" data-toggle="modal" data-target="#editModal">Edit</a>
</div>
</td>
</tr>
</table>
The bootstrap form:
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">New message</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!--the action attribute of the from indicates to where the form is gonna be submitted-->
<form th:action="#{/countries/update/{id} (id =${countryToUpdate.id})}" method="post" th:object="${countryToUpdate}">
<div class="form-group">
<label for="descriptionEdit" class="col-form-label">Description</label>
<!--name should correspond to the fields in the modal class-->
<input
type="text"
class="form-control"
id="descriptionEdit"
name="description"
>
</div>
<div class="form-group">
<label for="capitalEdit" class="col-form-label">Capital</label>
<input type="text"
class="form-control"
id="capitalEdit"
name="capital"
>
</div>
<div class="form-group">
<label for="codeEdit" class="col-form-label">Code</label>
<input type="text"
class="form-control"
id="codeEdit"
name="code"
>
</div>
<div class="form-group">
<label for="continentEdit" class="col-form-label">Continent</label>
<input type="text"
class="form-control"
id="continentEdit"
name="continent"
>
</div>
<div class="form-group">
<label for="nationalityEdit" class="col-form-label">Nationality</label>
<input type="text"
class="form-control"
id="nationalityEdit"
name="nationality"
>
</div>
<div class="modal-footer">
<!--submit type button should be within the form to execute the query-->
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
</div>
</div>
</div>
</div>
My controller:
#GetMapping("countries")
public String findAll(Model model){
List<Country> listOfCountries = countryService.findAll();
model.addAttribute("countries", listOfCountries);
return "country";
}
#GetMapping("countries/findById/{id}")
#ResponseBody
public Country findById(#PathVariable int id, Model mod)
{
Country country = countryService.findById(id).get();
//I want to create a countryToUpdate attribute to use it in the modal form
mod.addAttribute("countryToUpdate", country);
return country;
}
#GetMapping("countries")
public String findAll(Model model){
List<Country> listOfCountries = countryService.findAll();
model.addAttribute("countries", listOfCountries);
return "country";
}
#PostMapping(value="countries/update/{id}")
public String update(#ModelAttribute("countryToUpdate") Country country, #PathVariable int id) {
//Get the country object from database through the passed id
Optional<Country> c = countryService.findById(id);
c.get().setDescription(country.getDescription());
c.get().setContinent(country.getContinent());
c.get().setCode(country.getCode());
c.get().setCapital(country.getCapital());
c.get().setNationality(country.getNationality());
System.out.println("this country description is " + country.getDescription());
countryService.save(c.get());
return "redirect:/countries";
}
Any help would be appreciated.

DataTables warning: table id=category_table - Invalid JSON response. datatable ajax laravel

i am using delete method to destroy an item of the category table but when i reload the datatable function ajax it gives me an error DataTables warning: table id=category_table - Invalid JSON response. i don't know why it returns this error please help i want to refresh the table without refreshing the website
note:the delete method works fine
my table
<h1>all categories</h1>
<table class="table" id="category_table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">name</th>
<th scope="col">edit</th>
<th scope="col">delete</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
my ajax code
<script>
$(document).ready(function(){
$('body').on('click','#delete',function(){
var id = $(this).val();
$('#deleteexampleModal').modal('show');
$("#deleteid").val(id);
});
});
$('#deleteform').submit(function(e){
e.preventDefault();
var id = $("#deleteid").val();
// console.log(id);
$.ajax({
url: 'categories/'+id,
type: "DELETE",
dataType: 'json',
success:function(response){
console.log(response);
$("#deleteexampleModal").modal('hide');
// window.location.reload();
$('#category_table').DataTable().ajax.reload();
}
});
});
and my modal when clicking the delete button
<!-- delete Modal -->
<div class="modal fade" id="deleteexampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add new Product</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form method="POST" id="deleteform" name="form">
#csrf
#method('DELETE')
<div class="form-group">
are you sure you want to delte this item?
<input type="text" id="deleteid" name="deleteid">
</div>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
my delete method
public function deleteCategory($id){
$category = Category::find($id)->delete();
return response()->json([
'status' => 200,
'message' => 'deleted succfully'
]);
}

I try to update image with ajax in laravel but only details are update image is not update. How can i solve this?

Hi every one, I am using laravel 8, and i want to update data using model, now i am facing little problem. The Problem is only details are update but file or image did not updated, i give every thing in bellow,
Blade Code: THis is my datatable
<table class="table display" width="100%" id="example">
<thead>
<tr>
<th>No</th>
<th>Title</th>
<th>Image</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#php
$i=0;
#endphp
#foreach ($banner as $item )
<tr id="banner-{{ $item->id }}">
<td>{{ ++$i }}</td>
<td>{{ $item->title }}</td>
<td><img src="{{ asset('/assets/image/banner/'.$item->image) }}" alt="" style="width: 100px; height:100px"></td>
<td><input type="checkbox" name="status" class="status" id="status" data-toggle="toggle" data-on="Active" data-off="Deactive" data-onstyle="success" data-offstyle="danger" data-id="{{ $item->id }}" {{ $item->status == 'Active' ? 'checked' : '' }}></td>
<td>
<a class="btn btn-outline-warning btn-sm" href="javascript:void(0);" onclick="editbanner({{ $item->id }})"><i class="fas fa-pencil-alt"></i></a>
<i class="mdi mdi-trash-can"></i>
</td>
</tr>
#endforeach
</tbody>
</table>
Update Model here is data update model, that i create for update data.
<div class="modal fade" id="BannerEditModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<div class="text-center">
<h3 class="modal-title" id="exampleModalLabel">Insert Position & Salary</h3>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul id="BannerForm_errorlist"></ul>
<form class="forms-sample" id="bannereditform" method="post">
#csrf
<input type="hidden" name="id" id="id">
<div class="form-group">
<label>Title<small class="text-danger">*</small></label>
<input type="text" id="title1" name="title1" class="form-control" />
</div>
<div class="form-group">
<label>Banner Image<small class="text-danger">*</small></label>
<input type="file" id="image1" name="image1" class="form-control" />
</div>
<div class="text-center pb-2">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<input type="submit" class="btn btn-success submit" name="submit" id="submit" value="Update" />
</div>
</form>
</div>
</div>
</div>
Ajax Part This is Ajax code for data fetching and data uploading
function editbanner(id) {
$.get("/banner/edit/" + id, function(banner) {
$('#id').val(banner.id);
$('#title1').val(banner.title);
$('#BannerEditModal').modal("toggle");
});
}
$('#bannereditform').submit(function(e) {
e.preventDefault();
let id = $('#id').val();
var title1 = $('#title1').val();
var image1 = $('#image1').val();
let _token = $('input[name=_token]').val();
console.log(image1);
$.ajax({
type: "PUT"
, url: "/banner/update"
, data: {
id: id
, title1: title1
, image1: image1
, _token: _token
, }
, dataType: "json"
, success: function(response) {
// console.log(response);
$('#banner' + response.id + 'td:nth-child(1)').text(response.title1);
$('#banner' + response.id + 'td:nth-child(2)').val(response.image1);
$('#BannerEditModal').modal("toggle");
// location.reload();
$('#bannereditform')[0].reset();
}
});
});
Controller
public function update(Request $request)
{
$banner = Banner::find($request->id);
$banner->title = $request->input('title1');
if($request->hasFile('image1')){
$destination = public_path().'/assets/image/banner/'.$banner->image;
if(File::exists($destination)){
File::delete($destination);
}
$image = $request->file('image1');
$image_name = time().'.'.$image->getClientOriginalExtension();
$image->move(public_path().'/assets/image/banner/',$image_name);
$banner->image = $image_name;
}
$banner->save();
return response()->json($banner);
}
Route Here is my data fatching and data updating route
Route::get('/banner/edit/{id}', "App\Http\Controllers\BannerController#edit")->name('banner.edit');
Route::put('/banner/update', "App\Http\Controllers\BannerController#update")->name('banner.update');
you need to change the way you getting value from #image from
var image1 = $('#image1').val();
to
var image1 = $('#image1').prop('files')[0]
You are missing enctype in your modal form:
The enctype attribute specifies how the form-data should be encoded when submitting it to the server.
Note: The enctype attribute can be used only if method="post".
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<div class="text-center">
<h3 class="modal-title" id="exampleModalLabel">Insert Position & Salary</h3>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul id="BannerForm_errorlist"></ul>
<form class="forms-sample" id="bannereditform" method="post" enctype="multipart/form-data">
#csrf
<input type="hidden" name="id" id="id">
<div class="form-group">
<label>Title<small class="text-danger">*</small></label>
<input type="text" id="title1" name="title1" class="form-control" />
</div>
<div class="form-group">
<label>Banner Image<small class="text-danger">*</small></label>
<input type="file" id="image1" name="image1" class="form-control" />
</div>
<div class="text-center pb-2">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<input type="submit" class="btn btn-success submit" name="submit" id="submit" value="Update" />
</div>
</form>
</div>
</div>
Ajax : to send form files and data to Back-end we are using Form Data objects:
$('#bannereditform').submit(function(e) {
e.preventDefault();
let formData = new FormData($('#bannereditform')[0]);
$.ajax({
type: "PUT"
, url: "/banner/update"
, data:formData,
, dataType: "json",
processData: false
, success: function(response) {
// console.log(response);
$('#banner' + response.id + 'td:nth-child(1)').text(response.title1);
$('#banner' + response.id + 'td:nth-child(2)').val(response.image1);
$('#BannerEditModal').modal("toggle");
// location.reload();
$('#bannereditform')[0].reset();
}
});})

Core MVC 2 and Ajax wrong data type

I apologize for the subject topic too general, I have difficulties with Ajax work at all, I'm not able to sent/get up any response. The topic is probably duplicated, but I do not see the error in my code. All tutorials I found say the same thing but it still dont work for me, please take a look.
View
#model ValueTypeEditViewModel
#{
ViewBag.Title = "Dodaj Wartość";
Layout = "_AdminLayout";
}
<div class="col">
<form asp-action="EditValue" method="post">
<input type="hidden" asp-for="ValueType.ValueId" />
<input type="hidden" asp-for="ValueType.TypeId" />
<div class="form-group">
<label asp-for="ValueType.Value" class="m-1"></label>
<div><span asp-validation-for="ValueType.Value" class="text-danger"></span></div>
<input asp-for="ValueType.Value" class="form-control" />
</div>
#if (Model.IsSysParam)
{
<div class="form-group">
<label asp-for="ValueType.Controller" class="m-1"></label>
<div><span asp-validation-for="ValueType.Controller" class="text-danger"></span></div>
<input asp-for="ValueType.Controller" class="form-control" />
</div>
<div class="form-group">
<label asp-for="ValueType.Code" class="m-1"></label>
<div><span asp-validation-for="ValueType.Code" class="text-danger"></span></div>
<input asp-for="ValueType.Code" class="form-control" />
</div>
<div class="form-group">
<label asp-for="ValueType.Description" class="m-1"></label>
<div><span asp-validation-for="ValueType.Description" class="text-danger"></span></div>
<textarea asp-for="ValueType.Description" class="form-control"></textarea>
</div>
<div class="form-group">
<label asp-for="ValueType.IsSysParam" class="m-1"></label>
<div><span asp-validation-for="ValueType.IsSysParam" class="text-danger"></span></div>
<input type="checkbox" asp-for="ValueType.IsSysParam" class="form-control" />
</div>
}
#if (Model.ValueType.ValueId != 0)
{
<div class="form-group">
<label asp-for="ValueType.CreateDate" class="m-1"></label>
<label class="m-1">#Model.ValueType.CreateDate</label>
</div>
<div class="form-group">
<label asp-for="ValueType.EditDate" class="m-1"></label>
<label class="m-1">#Model.ValueType.EditDate</label>
</div>
}
#*#if (!Model.IsSysParam)
{
<div class="row">
<div class="col-5">
<select id="lbProducts" class="form-control" asp-items="Model.Products" size="#Model.ListBoxSize" multiple></select>
<label class="m-1">Lista Przedmiotów</label>
</div>
<div class="col-1 align-self-center">
<div class="d-flex justify-content-center">
<button id="addItems" class="btn btn-light mt-1" type="button"><i class="fa fa-long-arrow-right" aria-hidden="true"></i></button>
</div>
</div>
<div class="col-5">
<select id="lbAddedProducts" class="form-control" size="#Model.ListBoxSize" multiple></select>
#*<form method="post">
<button asp-page-handler="saveValueItems" id="saveValueItems" class="btn btn-primary mt-1" type="button"><i class="fa fa-floppy-o" aria-hidden="true"></i></button>
</form>
<button id="removeItems" class="btn btn-primary mt-1" type="button"><i class="fa fa-trash-o" aria-hidden="true"></i></button>
</div>
</div>
}*#
<div class="text-left">
<button class="btn btn-primary mt-1" type="submit">Zapisz</button>
</div>
</form>
<form asp-route="#(Model.IsSysParam ? RouteUrl.Name.SystemList : RouteUrl.Name.CategoryList)" method="post">
<div class="text-left">
<input type="hidden" name="isSysParamCategory" value="#Model.IsSysParam.ToString()" />
<button class="btn btn-secondary btn mt-1">Anuluj</button>
</div>
</form>
<form method="post">
#if (!Model.IsSysParam)
{
<div class="row">
<div class="col-5">
<select id="lbProducts" class="form-control" asp-items="Model.Products" size="#Model.ListBoxSize" multiple></select>
<label class="m-1">Lista Przedmiotów</label>
</div>
<div class="col-1 align-self-center">
<div class="d-flex justify-content-center">
<button id="addItems" class="btn btn-light mt-1" type="button"><i class="fa fa-long-arrow-right" aria-hidden="true"></i></button>
</div>
</div>
<div class="col-5">
<select id="lbAddedProducts" class="form-control" size="#Model.ListBoxSize" multiple></select>
<button asp-page-handler="saveValueItems" id="saveValueItems" class="btn btn-primary mt-1" type="button"><i class="fa fa-floppy-o" aria-hidden="true"></i></button>
<button id="removeItems" class="btn btn-primary mt-1" type="button"><i class="fa fa-trash-o" aria-hidden="true"></i></button>
</div>
</div>
}
</form>
</div>
At View you can see comented code started with - '#if (!Model.IsSysParam)'. Firstly I tried to fire Ajax from 'main' from with asp-page-handler="saveValueItems" at button. Then I added nested form in form with post (there is commented too), in the end I tried to created separeted form in the bottom of example. (by the way, I'm a beginner with mvc and don't really know if I can nesting form in form)
All the time I get the same error
Ajax
$(saveValueItems).click(function () {
var data = [];
var addedItems = $(addedItemList).find('option');
for (var i = 0; i < addedItems.length; i++) {
var item = addedItems[i];
data.push($(item).val());
}
$.ajax({
type: "POST",
url: "/admin/category/editvalue/96/35?handler=saveValueItems",
data: JSON.stringify(data),
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
console.log('spoko');
},
failure: function (response) {
alert(response);
}
});
})
I hardcoded url to be sure I send request to good action. I have this in mind to test only with this one item/values.
Controller
[ValidateAntiForgeryToken]
[Route(RouteUrl.Admin + RouteUrl.Slash + RouteUrl.Category + RouteUrl.Slash + "editvalue/{typeId?}/{valueId?}", Name = RouteUrl.Name.CategoryEditValueAjax)]
public ActionResult OnPostSaveValueItems([FromBody] int[] arrValueItems)
{
string test = "Hello Response Back";
return new JsonResult(test);
}
Startup.cs
I added to Startup.cs ValidateAntiForgeryToken before AddMvc() too
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
services.AddMvc();
Question:
I do not understand why I am sending the wrong data type. I want to send an int table and I receive a message that I'm sending ValueType and the view is expecting ValueTypeEditViewModel.
I do not know where to look for the cause of the error
1 Edit:
All actions for edit page
[HttpPost]
[Route(RouteUrl.Admin + RouteUrl.Slash + RouteUrl.System + RouteUrl.Slash + "[action]/{typeId?}", Name = RouteUrl.Name.SystemCreateValue)]
[Route(RouteUrl.Admin + RouteUrl.Slash + RouteUrl.Category + RouteUrl.Slash + "[action]/{typeId?}", Name = RouteUrl.Name.CategoryCreateValue)]
public ViewResult CreateValue(int typeId, bool isSysParamCategory)
{
return View(RouteUrl.Edit + RouteUrl.Value, new ValueTypeEditViewModel(typeId, isSysParamCategory, repositoryProduct.Products, Convert.ToInt32(repository.GetSysParamByCode(SysParams.ProductListBoxSize))));
}
[HttpGet]
[Route(RouteUrl.Admin + RouteUrl.Slash + RouteUrl.System + RouteUrl.Slash + "[action]/{typeId?}/{valueId?}", Name = RouteUrl.Name.SystemEditValue)]
[Route(RouteUrl.Admin + RouteUrl.Slash + RouteUrl.Category + RouteUrl.Slash + "[action]/{typeId?}/{valueId?}", Name = RouteUrl.Name.CategoryEditValue)]
public ViewResult EditValue(int typeId, int valueId)
{
bool isSysParamCategory = repository.GetCategoryByTypeId(typeId).IsSysParam;
return View(RouteUrl.Edit + RouteUrl.Value, new ValueTypeEditViewModel(repository.GetValue(typeId, valueId), isSysParamCategory, repositoryProduct.Products, Convert.ToInt32(repository.GetSysParamByCode(SysParams.ProductListBoxSize))));
}
[HttpPost]
[Route(RouteUrl.Admin + RouteUrl.Slash + RouteUrl.System + RouteUrl.Slash + "[action]/{typeId?}/{valueId?}", Name = RouteUrl.Name.SystemEditValue)]
[Route(RouteUrl.Admin + RouteUrl.Slash + RouteUrl.Category + RouteUrl.Slash + "[action]/{typeId?}/{valueId?}", Name = RouteUrl.Name.CategoryEditValue)]
public IActionResult EditValue(AureliaCMS.Models.ValueType valueType)
{
if (ModelState.IsValid)
{
repository.SaveValueType(valueType);
return View(RouteUrl.Save, new SaveCategoryType(repository.GetCategoryByTypeId(valueType.TypeId).IsSysParam, valueType.Value, false));
}
else
{
return View(valueType);
}
}

Form submit with a file in Spring mvc + bootstrap

Its a two part question.
I am trying to submit a pop up form with a file and textarea. I am not able to receive file in my controller code.
Part 1 - How do I receive the file at the controller.
Part 2 - Once I submit the form, how do I close the popup and remain on the same page so that URL does not change.
Popup code-
<form name="eperform">
<div class="modal fade" id="export" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
<span class="glyphicon glyphicon-remove" aria-hidden="true" style="padding-top: 10px;"></span>
</button>
<h4 class="modal-title custom_align" id="Heading">Provide ID's here:</h4>
</div>
<div class="form-group">
<div>
<fieldset style="margin-left: 10px;">
<legend style="font-size: medium;">File Upload</legend>
<input id="fileUpload" name="fileUpload" type="file" style="margin-left: 20px"/>
</fieldset>
</div>
<br/>
<div>
<fieldset style="margin-left: 10px;">
<legend style="font-size: medium;">Ids</legend>
<label for="envIds"></label>
<textarea class="form-control noresize" rows="4" style="width:98% " name="ids" id="ids" value="">
</textarea>
<input type="hidden" id="server" name="server" value="${server}">
<input type="hidden" id="port" name="port" value="${port}">
<input type="hidden" id="queuename1" name='queuename1' value="">
<input type="hidden" id="environment" name="environment" value="${environment}">
</fieldset>
</div>
</div>
<div class="modal-footer ">
<button type="button" class="btn btn-success" id="eid"
onclick="exportObjects(document.getElementById('ids').value,document.getElementById('queuename1').value,'${port}','${server}','${environment}',document.getElementById('fileUpload').value)">
<span class="glyphicon glyphicon-ok-sign"></span>Export
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
<span class="glyphicon glyphicon-remove"></span> Cancel
</button>
</div>
</div>
</div>
</div>
</form>
Javascript code-
function exportObjects(ids, queueName, port, server, environment, fileUpload) {
var strHREF = "/exportObjects?ids=" + ids
+ "&queueName=" + queueName + "&port=" + port + "&server="
+ server + "&environment=" + environment +"&fileUpload=" + fileUpload;
document.eperform.action = strHREF;
document.eperform.submit();
}
Controller code-
#RequestMapping(value="/exportObjects", method = RequestMethod.GET)
public ModelAndView exportObjects(HttpServletRequest request) throws Exception{
String server =request.getParameter("server");
String port =request.getParameter("port");
String environment = request.getParameter("environment");
String type =request.getParameter("queueName");
String ids = request.getParameter("ids");
CommonsMultipartFile file = (CommonsMultipartFile) request.getAttribute("fileUpload");
if(file != null && file.getSize() != 0){
String path=request.getServletContext().getRealPath("/");
String filename=file.getOriginalFilename();
System.out.println(path+" "+filename);
try{
InputStream in = file.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
System.out.println(out.toString());
}catch(Exception e){System.out.println(e);}
}
// Perform action on ids and file data
ModelAndView model = new ModelAndView();
// I do not know what to do here.
return model;
}
It seems that you are not familiar with web developement,I recommend you take some time to review the java web development knowledge.
Below are the answer for your two questions:
If you want to upload a file to the server,you must add enctype="multipart/form-data" to your form
<form name="eperform" enctype="multipart/form-data">
<div>
<fieldset style="margin-left: 10px;">
<legend style="font-size: medium;">File Upload</legend>
<input id="fileUpload" name="fileUpload" type="file" style="margin-left: 20px"/>
</fieldset>
</div>
</form>
If you want to stay on the same page,you should using an asynchronous method to submit your action,and Ajax is your best choice.You need to submit your request and in the success callback method close the popup dialog.
$.ajax({
url:"exportObjects",
type:"post",
data:{
queueName:queueName,
port:port,
server:server,
environment:environment
},
success:function(data){
//if the request submit success,invoke 'close' method to close the dialog
$("#dialog_div").dialog("close");
}
});
In your springmvc code,you should not use ModelAndView because it will forward to a new page,you need to return an original string,like the code listed below,after that you can use MultipartFile to get your upload file:
#RequestMapping(value="eperform",method=RequestMethod.POST)
#ResponseBody
public String updateNodeRelation(#RequestParam(value="fileUpload")
MultipartFile file,HttpServletRequest request) {
System.out.println(file.getOriginalFilename());
return "success";
}
UPDATED
If you want to submit a file and then stay on the same page,then you need to use iframe and not use Ajax,as below:
<!-- using iframe to stay on the same page-->
<form id="eperform"name="eperform" action="exportObjects" enctype="multipart/form-data"
target="hidden_frame">
<div>
<fieldset style="margin-left: 10px;">
<legend style="font-size: medium;">File Upload</legend>
<input id="fileUpload" name="fileUpload" type="file"
style="margin-left: 20px"/>
</fieldset>
</div>
<iframe id="hidden_frame" name="hidden_frame"
style="display:none"/>
<button type="button" onclick="submitFile()">Submit</button>
</form>
And using the below Javascript code to submit the form and close popup dialog**
function submitFile(){
$("#eperform").submit();
$("#dialog_div").dialog("close");
}

Resources