Adding new item to database using ASP.NET Core MVC - asp.net-core-mvc

I'm building a Pet Shop website using ASP.NET Core MVC (the latest version).
I have database with instructions for primary key and identity(1,1) (auto increment).
In my website,in order to check and see if my 'Create' method is working, I've created a page (a controller and view) of Create new animal and a page for the list of all the animals that I've got (Index controller). After clicking Submit on the create page, it's redirected to Index - where I should see the animal that I've added (this line wrote on SQL):
The problem is that I don't see anything added to my list (the photo above). After a few tries, I've tried to add animal directly in my SQL and I saw that it's got the number ID 22 - meaning that maybe I did succeeded to add new animal and I just don't see it?
I really don't know where my problem is and I would be happy to get help.
Controller:
public async Task<IActionResult> Index()
{
var petShopDataContext = _context.Animals.Include(a => a.Category);
return View(await petShopDataContext.ToListAsync());
}
public async Task<IActionResult> CreateAnimal()
{
var categories = await _categoryService.GetAnimalCategory();
ViewBag.Categories = categories.Select(c => new SelectListItem(c.Name, c.CategoryId.ToString())).ToList();
return View();
}
public async Task<IActionResult> CreateAnimal([FromForm] CreateAnimalViewModel vm)
{
vm.Animal.Category = await _categoryService.GetAsync(vm.Animal.CategoryId);
_animalService.AddAnimalAsync(vm.Animal, vm.Photo);
return RedirectToAction("Index");
}
CreateAnimalViewModel:
public class CreateAnimalViewModel
{
public Animal Animal { get; set; }
public IFormFile Photo { get; set; }
}
Create Animal View:
#model PetShop.Client.Models.CreateAnimalViewModel
#{
ViewBag.Title = "CreateAnimal";
}
<h4>Create New Animal</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="CreateAnimal" enctype="multipart/form-data" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Animal.Name" class="control-label"></label>
<input asp-for="Animal.Name" class="form-control" />
<span asp-validation-for="Animal.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Animal.BirthDate" class="control-label"></label>
<input asp-for="Animal.BirthDate" class="form-control" />
<span asp-validation-for="Animal.BirthDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Animal.Description" class="control-label"></label>
<input asp-for="Animal.Description" class="form-control" />
<span asp-validation-for="Animal.Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Animal.Category">Category</label>
<select asp-for="Animal.CategoryId" asp-items="ViewBag.Categories" class ="form-control" id="category"></select>
<span asp-validation-for="Animal.CategoryId" />
<a asp-controller="Admin" asp-action="CreateCategory">
<input type="button" value="Add new category"/>
</a>
</div>
<div class="form-group">
<label asp-for="Photo" class="control-label"></label>
<input type="file" asp-for="Photo" accept="image/*" class="form-control-file"/>
<span asp-validation-for="Photo" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
Index View:
#model IEnumerable<PetShop.Data.Models.Animal>
#{
ViewBag.Title = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="CreateAnimal">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.BirthDate)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.PhotoUrl)
</th>
<th>
#Html.DisplayNameFor(model => model.Category)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.BirthDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.PhotoUrl)
</td>
<td>
#Html.DisplayFor(modelItem => item.Category.Name)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.AnimalId">Edit</a> |
<a asp-action="Details" asp-route-id="#item.AnimalId">Details</a> |
<a asp-action="Delete" asp-route-id="#item.AnimalId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Animal Service:
public async Task<Animal> AddAnimalAsync(Animal animal, IFormFile image)
{
var entity = _animalRepository.Add(animal);
var path = await _imageService.UploadImage(image, animal);
if (path != String.Empty)
{
return _animalRepository.Update(entity);
}
return entity;
}
Animal Repository:
public Animal Add(Animal entity)
{
_context.Animals.Add(entity);
_context.SaveChanges();
return entity;
}

Related

how to list dropdown from VIewBag with one to many relation on a partial page?

this is my model.
This is a partial page:
#model FinalForm.Models.Employee
<div class="container">
#using (Html.BeginForm("SaveMarks", "Reg", FormMethod.Post))
{
<div class="form-group">
<button type="button" id="Submit" class="btn btn-info col-md-2" onclick="SubmitM()">Add Marks</button>
<div>
<label class="form-label col-md-1">Qualification</label>
#Html.DropDownList("Quallist", null, "Select", htmlAttributes: new { #class = "form-control search-select offerItem Item border border-dark", id = "Item", #Name = "QualificationList.Q_Name" })
#Html.ValidationMessageFor(model => model.EMP_QUALIFICATION, "", new { #class = "text-danger" })
</div>
<div>
<label class="form-label col-md-1">Marks</label>
<input type="text" id="Marks" name="Marks" class="form-control col-md-1" placeholder="" />
</div>
</div>
}
<div class="panel-body">
<table id="tbl_qlist" class="table table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Q_id</th>
<th>Q_Name</th>
<th>Marks</th>
<th>Del</th>
</tr>
</thead>
</table>
</div>
</div>
this is contoller method:
[ChildActionOnly]
public ActionResult Equalify()
{
ViewBag.Quallist = new SelectList(new List<QualificationList>(), "Q_id", "Q_Name");
return PartialView("Equalify");
}
```
System.InvalidOperationException: 'There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'Quallist'.'

laravel, get data by id using foreach

how do I fetch the data based on the insurance_id on the companion db? the insurance_id is dependent on another table called "insurances" if that helps. the db is this:
and the view looks like this:
here's the view:
<table class="table" id="companions_table">
<thead>
<tr>
<th>Name</th>
<th>Date of Birth</th>
<th>IC No</th>
<th>Relationship</th>
</tr>
</thead>
<tbody>
#foreach (old('companions', $companions->count() ? $companions : ['']) as $companion)
<tr id="companion{{ $loop->index }}">
<td>
<input type="text" name="companion_name[]" id="companion_name[]" class="form-control" value="{{ old('companion_name', $companion->companion_name) }}" />
</td>
<td>
<div class="input-group date" data-provide="datepicker" data-date-format="dd-mm-yyyy" data-date-today-highlight="true" data-date-end-date="0d">
<input class="form-control" type="text" name="dob[]" id="dob[]" value="{{ old('dob', $companion->dob) }}">
<div class="input-group-addon">
<span class="fa fa-calendar"></span>
</div>
</div>
</td>
<td>
<input type="text" name="ic[]" id="ic[]" class="form-control" value="{{ old('ic', $companion->ic) }}" />
</td>
<td>
<input type="text" name="relationship[]" id="relationship[]" class="form-control" value="{{ old('relationship', $companion->relationship) }}" />
</td>
</tr>
#endforeach
<tr id="companion{{ count(old('companions', $companions->count() ? $companions : [''])) }}"></tr>
/tbody>
</table>
<div class="row">
<div class="col-md-12">
<button id="add_row" class="btn btn-default pull-left">+ Add Row</button>
<button id='delete_row' class="pull-right btn btn-danger">- Delete Row</button>
</div>
my controller:
public function edit(Insurance $insurance)
{
abort_if(Gate::denies('insurance_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$customers = CustomerProfile::all()->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');
$products = Product::all()->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');
$sales_2s = User::all()->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');
$companions = Companion::all();
$insurance->load('customer', 'product', 'sales_2', 'team', 'companions');
$approvers = Role::findOrFail(3)->users()->get();
return view('admin.insurances.edit', compact('customers', 'products', 'sales_2s', 'insurance', 'approvers', 'companions'));
}
it keeps fetching all the data on the table, basically disregarding the insurance_id. how do I fix this?
All of the companions are being fetched, regardless of the insurance_id, because of the following line:
$companions = Companion::all();
If you only want companions with the current insurance_id, the quickest way would be to replace the previously mentioned line with:
$companions = Companion::where('insurance_id', $insurance->id)->get();
This should work, however the conventional way to handle this relationship in Laravel would be by adding the following function to your Insurance model:
use App\Models\Companion; // or wherever your model happens to be located
public function companions()
{
return $this->hasMany(Companion::class);
}
And replacing the line mentioned at the beginning with:
$companions = $insurance->companions;

Repopulate Textbox in PartialView When Page Fails Validation

I have a View that besides being bound to a model, has 3 partial views (a people picker) of a reuseable component. I perform a validation to check for duplicates of the data in the model at submit. If the record is a dup, it redirects back to the page, where the model can repopulate the model fields. However, I'd like the People Picker values to be retained as well, but since it is not part of the model, I don't know how to do that.
This is the controller
public ActionResult Create(IFormCollection collection)
{
try
{
Dept_COEModel Dept = new DeptModel();
Dept.DeptName = collection["DeptName"];
Dept.DeptAcronym = collection["DeptAcronym"];
Dept.DeptCeNtId = collection["UserIdHidden_20"];
Dept.DeptCeUserName = collection["UserNameHidden_20"];
Dept.DeptCeEmail = collection["UserEmailHidden_20"];
Dept.delegate1PocNtId = collection["UserIdHidden_30"];
Dept.delegate1PocName = collection["UserNameHidden_30"];
Dept.delegate1PocEmail = collection["UserEmailHidden_30"];
Dept.delegate2PocNtId = collection["UserIdHidden_40"];
Dept.delegate2PocName = collection["UserNameHidden_40"];
Dept.delegate2PocEmail = collection["UserEmailHidden_40"];
int result = _adoSqlService.CheckDept(collection["DeptName"]);
if (result == 0)
{
_adoSqlService.InsertDept(dept);
return RedirectToAction(nameof(Index));
}
else
{
ModelState.AddModelError("DeptName", "This Department already exists");
ViewData["UserResultTextbox_20"] = Dept.DeptCeUserName;
return View(Dept);
}
}
catch
{
return View(Dept);
}
}
Here is the View
#model EDAD.Models.LOB_COEModel
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>LOB_COE</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
#*<div class="form-group">
<label asp-for="lobCoeId" class="control-label"></label>
<input asp-for="lobCoeId" class="form-control" />
<span asp-validation-for="lobCoeId" class="text-danger"></span>
</div>*#
<div class="form-group">
<label asp-for="lobCoeName" class="control-label"></label>
<input asp-for="lobCoeName" class="form-control" />
<span asp-validation-for="lobCoeName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="lobCoeAcronym" class="control-label"></label>
<input asp-for="lobCoeAcronym" class="form-control" />
<span asp-validation-for="lobCoeAcronym" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Select Chief Engineer</label>
<div class="form-group form-field-div">
<table>
<tr style="white-space:nowrap;">
<td>
#Html.Action("PeoplePicker", "PeoplePicker", new EDAD.Models.PeoplePickerViewModel { PickerId = 20 })
</td>
<td></td>
</tr>
</table>
</div>
#*<span asp-validation-for="lobCoeCeNtId" class="text-danger"></span>*#
</div>
<div class="form-group">
<label class="control-label">Select Delegate 1</label>
<div class="form-group form-field-div">
<table>
<tr style="white-space:nowrap;">
<td>
#Html.Action("PeoplePicker", "PeoplePicker", new EDAD.Models.PeoplePickerViewModel { PickerId = 30 })
</td>
<td></td>
</tr>
</table>
</div>
#*<span asp-validation-for="lobCoeCeNtId" class="text-danger"></span>*#
</div>
<div class="form-group">
<label class="control-label">Select Delegate 2</label>
<div class="form-group form-field-div">
<table>
<tr style="white-space:nowrap;">
<td>
#Html.Action("PeoplePicker", "PeoplePicker", new EDAD.Models.PeoplePickerViewModel { PickerId = 40 })
</td>
<td></td>
</tr>
</table>
</div>
#*<span asp-validation-for="lobCoeCeNtId" class="text-danger"></span>*#
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Here is the cshmtl for the People Picker (note that this is reusable so I don't want to modify any code in this)
#model ABC.Models.PeoplePickerViewModel
<script src="~/lib/jquery/jquery.js"></script>
<script src="~/js/site.js"></script>
<script>
$(function () {
setUpGlyphicons(#Model.PickerId, '#Url.Action("SearchForUsers", "PeoplePicker")');
});
</script>
<div class="people-picker">
#Html.TextBox("UserResultTextbox_" + Model.PickerId, Model.User.userName, new { #onkeypress = "userSearchKeyPress(event);", #class = "form-control input-smaller", style = "display: inline", placeholder = "Last Name, First Name", autocomplete = "off" })
#Html.Hidden("UserIdHidden_" + Model.PickerId, Model.User.NTId)
#Html.Hidden("StoredUserNameHidden_" + Model.PickerId, Model.User.userName)
#Html.Hidden("UserNameHidden_" + Model.PickerId, Model.User.userName)
#Html.Hidden("UserEmailHidden_" + Model.PickerId, Model.User.userEmail)
<span id="UserEditButton_#Model.PickerId" class="fa fa-pencil icon-inline"></span>
<span id="UserCancelButton_#Model.PickerId" class="fas fa-ban hide icon-inline"></span>
<span id="UserSearchButton_#Model.PickerId" class="fa fa-search hide icon-inline"></span>
#*<span id="InjectButtonPlaceholder_#Model.PickerId" class="hide"></span>*#
<img id="PeoplePickerLoading_#Model.PickerId" class="hide" alt="Loading..." src="~/Images/loading.gif" /><br />
<span id="PeoplePickerError_#Model.PickerId" class="error-label">*</span>
<div id="UserSearchContent_#Model.PickerId" class="list-group user-results"
onmouseout="$('.disable-scroll-container').removeClass('disable-scroll');"
onmouseover="$('.disable-scroll-container').addClass('disable-scroll');">
</div>
</div>
How can I update the fields that start with the word "User" when the view fails validation
I'm going to close this question. I discovered that the issue lies in a different direction and I'm going to post a new question.

asp.net mvc table does not update after filtering with checkboxes

I am doing the ticket application and I am making filtration of items with checkboxes. First the page loads every item in database and view displays it in the table. Then a user can click on the checkbox and view displays just the selected categories. It is supposed to be updated on the checkbox click.
Controller Action:
public ActionResult Display(int[] checkId)
{
if (checkId == null)
{
DispDisplayVM viewModel = new DispDisplayVM
{
Jidlos = db.Jidlos.ToList(),
//Jidlos = (from Jidlo jidlo in db.Jidlos where checkId.Contains(jidlo.CategoryID) select jidlo).ToList(),
Categories = db.Categories.ToList()
};
return View(viewModel);
}
else
{
DispDisplayVM viewModel = new DispDisplayVM
{
//Jidlos = db.Jidlos.ToList(),
Jidlos = (from Jidlo jidlo in db.Jidlos where checkId.Contains(jidlo.CategoryID) select jidlo).ToList(),
Categories = db.Categories.ToList()
};
return View(viewModel);
}
}
Data into controller are passed by ajax. It can be one value or an array. Then there is a LINQ query to filter database.
View:
#using jidloApp.Classes
#using jidloApp.Models
#model DispDisplayVM
#{
ViewBag.Title = "Display";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Display</h2>
<div class="container">
Pridat novy recept
</div>
<div class="btn-group" data-toggle="buttons">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="1" name="checkId">
Kuřecí
</label>
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="2" name="checkId">
Vepřové
</label>
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="3" name="checkId">
Hovězí
</label>
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="4" name="checkId">
Krůtí
</label>
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="5" name="checkId">
Vegetariánské
</label>
</div>
<table class="table">
<thead>
<tr>
<th>Nazev Jidla</th>
<th>Kategorie</th>
<th>Akce</th>
</tr>
</thead>
<tbody>
#foreach (Jidlo jidlo in Model.Jidlos)
{
<tr>
<td>
#Html.DisplayFor(modelItem => jidlo.name)
</td>
<td>
#Html.DisplayFor(modelItem => jidlo.Category.popis)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = jidlo.JidloID }) |
#Html.ActionLink("Details", "Details", new { id = jidlo.JidloID }) |
#Html.ActionLink("Delete", "Delete", new { id = jidlo.JidloID })
</td>
</tr>
}
</tbody>
</table>
<script>
$(document).ready(function () {
$('input[name="checkId"]').click(function () {
getSelectedCheckBoxes();
});
var getSelectedCheckBoxes = function () {
var idArray = [];
$('input[name="checkId"]:checked').each(function () {
idArray.push($(this).attr("value"));
});
$.ajax({
url: '#Url.Action("Display", "Disp")',
type: "POST",
data: { checkId: idArray },
dataType: "json",
traditional: true,
success: function () {
alert("ajax request to server succeed");
}
});
};
});
</script>
Data filtering is working fine and requested data are passed into the view correctly.
What is not working is when I click on the checkbox, the table stays the same as before and does not update. I really can not find what is wrong here. Can you please give some advice what to do?
Btw the table updates when I create new item in database or I delete it...
I think you need a View and a PartialView.
Controller:
public ActionResult Index()
{
return View();
}
public PartialViewResult Display(int[] checkId)
{
DispDisplayVM viewModel = null;
[youre code]
return PartialView(viewModel)
}
Index View:
#{
ViewBag.Title = "Display";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Display</h2>
<div class="container">
Pridat novy recept
</div>
<div class="btn-group" data-toggle="buttons">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="1" name="checkId">
Kuřecí
</label>
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="2" name="checkId">
Vepřové
</label>
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="3" name="checkId">
Hovězí
</label>
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="4" name="checkId">
Krůtí
</label>
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="5" name="checkId">
Vegetariánské
</label>
</div>
<div id="data-container"></div>
<script>
$('input[name="checkId"]').on("click",function () {
var idArray = [];
$("input[name="checkId"]:checked").each(function () {
idArray.push($(this).attr("value"));
});
$("#data-container").load("#Url.Action("Display", "Disp")",{ checkId: idArray });
});
</script>
Display View:
#using jidloApp.Classes
#using jidloApp.Models
#model DispDisplayVM
<table class="table">
<thead>
<tr>
<th>Nazev Jidla</th>
<th>Kategorie</th>
<th>Akce</th>
</tr>
</thead>
<tbody>
#foreach (Jidlo jidlo in Model.Jidlos)
{
<tr>
<td>
#Html.DisplayFor(modelItem => jidlo.name)
</td>
<td>
#Html.DisplayFor(modelItem => jidlo.Category.popis)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = jidlo.JidloID }) |
#Html.ActionLink("Details", "Details", new { id = jidlo.JidloID }) |
#Html.ActionLink("Delete", "Delete", new { id = jidlo.JidloID })
</td>
</tr>
}
</tbody>
</table>
Code written "on fly"

How to perform arithmetic operations of two different data types in thymeleaf?

I have a piece of HTML where I need to multiply (or perform arithmetic operations) two values using thymeleaf.
Let's say my price is double and quantity is an integer.
Here's my sample code:
<fieldset class="form-inline" disabled >
<label for= "prodAmount">AMOUNT: </label>
<input type="number" class="form-control" th:text="${#aggregates.sum(product.![price * qty])}">
</fieldset>
Here's the error I'm getting:
Exception evaluating SpringEL expression: "#aggregates.sum(product.![price * qty])"
Also , I would also like to ask how to perform this when there's two or more values.
Here's my html form
<div class="container">
<div class="row">
<div class="col-lg-4 col-sm-12 col-xs-12">
<form th:action="#{/product/product-list}" method="post" th:object="${productEntity}">
<input type="hidden" th:field="*{pid}" th:value="${pid}" >
<fieldset class="form-group">
<label for="product_name">Product Name</label>
<input type="text" class="form-control" th:field="*{pName}" th:value="${pName}">
</fieldset>
<fieldset class="form-group">
<label for="price">Price</label>
<input type="number" class="form-control" th:field="*{price}" th:value="${price}" placeholder="0">
</fieldset>
<fieldset class="form-group">
<label for="pQty">Quantity</label>
<input type="number" class="form-control" th:field="*{qty}" th:value="${qty}" placeholder = "0">
</fieldset>
<fieldset class="form-group">
<label for="status">Status</label>
<select class="form-control" id="select_status" th:field="*{status}" th:value="${status}">
<option value="0">AVAILABLE</option>
<option value ="1">NOT AVAILABLE</option>
</select>
</fieldset>
<fieldset class="form-group">
<label for="image">Image</label>
<input id="input-b2" name="input-b2" type="file" class="file"
data-show-preview="false" th:field="*{image}" th:value="${image}">
</fieldset>
</form>
</div>
<div class="col-lg-8 col-sm-12 col-xs-12">
<table class="table table-inverse table-striped table-hover">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Status</th>
<th>Image</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr th:each="product : ${productTable} ">
<td th:text="${product.pid}"></td>
<td th:text="${product.pName}"></td>
<td th:text="${product.price}"></td>
<td th:text="${product.qty}"></td>
<td th:text="${product.status == '0'} ? 'Available' : 'Not Available'"></td>
<td th:text="${product.image}"></td>
<td>
<a th:href="#{/productlist/{id}(id = ${product.pid})}" class="btn btn-primary">Update</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row float-right">
<div class="col-xd-12">
<div>
<fieldset class="form-inline" disabled >
<label for= "prodAmount">AMOUNT: </label>
<input type="number" class="form-control" th:text="${#aggregates.sum(product.{price * qty})}">
</fieldset>
<button type="button" class="btn btn-primary">Checkout</button>
</div>
</div>
</div>
</div>
Product Controller:
#RequestMapping(value="/product-list")
public ModelAndView shopView() {
ModelAndView mav = new ModelAndView();
mav.addObject("productTable", pRepo.findAll());
mav.addObject("productEntity",new ProductEntity());
mav.setViewName("/productlist");
return mav;
}
#RequestMapping(value = "/{id}",method = RequestMethod.GET)
public ModelAndView getProduct(#ModelAttribute ProductEntity productEntity, #PathVariable int id) {
ModelAndView mav = new ModelAndView();
mav.addObject("productTable",pRepo.findAll());
mav.addObject("productEntity", pRepo.findOne(id));
mav.setViewName("/productlist");
return mav;
}

Resources