how to turn this spring boot thyme-leaf code into Ajax - ajax

I Have a comment and post system and I want To turn it into ajax without using thymeleaf fragmentation. How to do it i cannot figure out I do not want to refresh the page each time i make a post or comment .
Controller :
#Controller
public class DashboardController {
private Post post;
private User user;
#Autowired
private PostRepository postRepository;
#Autowired
private UserRepository userRepository;
#Autowired
CommentRepository commentRepository;
#RequestMapping(value = "/dashboard", method = RequestMethod.GET)
public String returnPosts(Model model) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName(); //holding login user details
model.addAttribute("firstName", userRepository.findByEmail(currentPrincipalName).getFirstName());
model.addAttribute("newPost", new Post());
model.addAttribute("newComment", new Comment());
model.addAttribute("posts", postRepository.findAllByOrderByDateDesc());
model.addAttribute("comments", commentRepository.findAll());
return "main";
}
#RequestMapping(value = "/dashboard/posts", method = RequestMethod.POST)
public String addPost(Model model, #ModelAttribute Post post, #ModelAttribute User user) {
model.addAttribute("newPost", post);
creatPost(post);
System.out.println(post.getId());
return "redirect:/dashboard";
}
#RequestMapping(value = "/dashboard/comments", method = RequestMethod.POST)
public String addComment( Model model, #ModelAttribute Comment comment,
#ModelAttribute User user) {
model.addAttribute("newComment", comment);
// model.addAttribute("posts", post);
creatComment(comment.getPostId(), comment);
System.out.println(comment.toString());
//System.out.println(post.getId());
// System.out.println(comment.getPostId());
return "redirect:/dashboard";
}
private Comment creatComment(String id, Comment comment) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();
comment.setDate(new Date());
comment.setAuthor(userRepository.findByEmail(currentPrincipalName).getFirstName()
+ " " + userRepository.findByEmail(currentPrincipalName).getLastName());
comment.setPostId(id);
return commentRepository.save(comment);
}
private Post creatPost(Post post) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName(); //holding login user details
post.setAuthor(userRepository.findByEmail(currentPrincipalName).getFirstName()
+ " " + userRepository.findByEmail(currentPrincipalName).getLastName());
post.setDate(new Date());
return postRepository.save(post);
}
}
Thymeleaf forms :
<div id="content" class="yellow col-xs-12">
<form class="col-xs-12" role="form" action="/dashboard/posts"
th:action="#{/dashboard/posts}" th:object="${newPost}" method="post">
<div class="form-group col-xs-12">
<textarea class="form col-xs-6" rows="2" id="full" placeholder="share anything....."
th:field="*{content}" style="font-size: 20px;" required="required"></textarea>
<div class="menu1 col-xs-12">
<hr/>
<ul class="text-center col-xs-12">
<a href="#">
<li>
<button type="submit" class="sendpost btn btn-success">Send</button>
</li>
<li class="xs-12 "><i class="fa fa-flash fa-lg"></i>Tasks</li>
<li class="xs-12"><i class="fa fa-paperclip fa-lg"></i>files</li>
<li class="xs-12"><i class="fa fa-calendar fa-lg"></i> calendar</li>
<li class="xs-12"><i class="fa fa-search fa-lg"></i>stying</li>
</a>
</ul>
</div>
</div>
</form>
<div>
<div th:each="post : ${posts}" style="border:2px solid #CCCCCC ; margin-bottom: 50px" id="post-div"
class="post-group col-xs-12">
<div class="imag col-xs-2">
<!--<input type="hidden" th:field="*{post.id}" disabled="disabled"/>-->
<img style="width: 50px;" src="images/1.png" class="img-circle img-responsive" alt=""/>
</div>
<div class=" col-xs-10">
<h4 style="line-height: .4;"><p class="name" th:text="*{post.author}">
</p>
<small style="color: #337ab7" th:text="*{post.date}"></small>
</h4>
<br/>
<p style="font-size: 20px" id="post-p" class="desc" th:text="*{post.content}"></p><br/>
<div class="footer ignore-zoom">
<a class="comment" onclick="showDiv1()"><i class="aa fa fa-comment"></i>
<span class="lin">0</span></a>
<a onclick="showDiv2()" href="#">
<i id="like" class="aa fa fa-heart active"></i>
<span style="display:none;" id="like-1" class="lin">1</span></a>
<a class="aa dropdown-toggle" data-toggle="dropdown" href="#" aria-expanded="false"><i
class="fa fa-pencil"></i> </a>
</div>
<div th:each="comment : ${comments}" id="my-comment">
<div th:if="${post.id == comment.postId}">
<hr/>
<br/>
<img class="img-circle img-responsive" src="images/1.png"
style="margin-right:5%; width: 50px; display: inline-flex; color:#080602;"/>
<div style="line-height:.8">
<label th:text="*{comment.author}"> </label><br/>
<small th:text="*{comment.date}" style=" color: #337ab7 ; margin-left:16%;">time of
comment
</small>
</div>
<br/>
<p style="font-size: 16px;" id="-comment" th:text="*{comment.comment}"></p>
<div class="footer footer1 ignore-zoom">
<a onclick="showDiv4()" href="#">
<i id="like1" class="aa fa fa-heart active"></i>
<span style="display:none;" id="like-2" class="lin">1</span></a>
<a class="aa dropdown-toggle" data-toggle="dropdown" href="#" aria-expanded="false"><i
class="fa fa-pencil"></i> </a>
</div>
</div>
</div>
<form role="form" action="/dashboard/comments"
th:action="#{/dashboard/comments}" th:object="${newComment}" method="post">
<input type="hidden" name="postId" th:value="${post.id}"/>
<div id="comment-div" class="form-group col-xs-12">
<textarea th:field="*{comment}" class="form col-xs-6" rows="2" id="full2"
placeholder="Your Comment....." required="required"></textarea>
<div class="menu1 col-xs-12">
<hr/>
<ul class="text-center col-xs-12">
<a href="#">
<li onclick="showDiv()">
<button type="submit" class="btn btn-info">Send</button>
</li>
<li class="xs-12 "><i class="fa fa-flash fa-lg"></i></li>
<li class="xs-12"><i class="fa fa-paperclip fa-lg"></i></li>
<li class="xs-12"><i class="fa fa-calendar fa-lg"></i></li>
<li class="xs-12"><i class="fa fa-search fa-lg"></i></li>
</a>
</ul>
</div>
</div>
</form>
</div>
</div>
</div>
</div>

You can have a look at the tutorial http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#ajax-fragments
And the content is as below:
Ajax fragments
WebFlow allows the specification of fragments to be rendered via AJAX with tags, like this:
<view-state id="detail" view="bookingDetail">
<transition on="updateData">
<render fragments="hoteldata"/>
</transition>
</view-state>
These fragments (hoteldata, in this case) can be a comma-separated list of fragments specified at the markup with th:fragment :
<div id="data" th:fragment="hoteldata">
This is a content to be changed
</div>
Always remember that the specified fragments must have an id attribute, so that the Spring JavaScript libraries running on the browser are capable of substituting the markup.
tags can also be specified using DOM selectors:
<view-state id="detail" view="bookingDetail">
<transition on="updateData">
<render fragments="[//div[#id='data']]"/>
</transition>
</view-state>
...and this will mean no th:fragment is needed:
<div id="data">
This is a content to be changed
</div>
As for the code that triggers the updateData transition, it looks like:
<script type="text/javascript" th:src="#{/resources/dojo/dojo.js}"></script>
<script type="text/javascript" th:src="#{/resources/spring/Spring.js}"></script>
<script type="text/javascript" th:src="#{/resources/spring/Spring-Dojo.js}"></script>
...
<form id="triggerform" method="post" action="">
<input type="submit" id="doUpdate" name="_eventId_updateData" value="Update now!" />
</form>
<script type="text/javascript">
Spring.addDecoration(
new Spring.AjaxEventDecoration({formId:'triggerform',elementId:'doUpdate',event:'onclick'}));
</script>

Related

pass object from HTML template back to the controller

I have the following HTML block. I want to pass the object "jobDTO" back to the contoller "/deleteJob" method. Whatever I do I am getting null object.
<th:block th:if="${jobDTO != null}" th:each="jobDTO: ${allJobDTOs.get(jobGroup)}">
<div id="accordion2" style="margin-bottom: 3px;">
<div class="card" id="headingOne">
<div class="card-header" style="padding: 0">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" th:attr="data-target='#accordion2_'+${jobDTO.identity.name}"
aria-expanded="true" aria-controls="collapseChild" >
<p class="font-weight-bold custom-p identity-black" > Job Identity </p>
<p class="custom-p" style="padding-left: 52px;" th:text="${jobDTO.identity.group} +' , ' + ${jobDTO.identity.name}"></p>
</button>
</h5>
</div>
<div th:id="'accordion2_'+${jobDTO.identity.name}" class="collapse" aria-labelledby="headingOne" data-parent="#accordion2">
<div class="card-body">
<dl class="row">
<dt class="col-lg-3">Trigger List</dt>
<dd class="col-sm-9">
<th:block th:each="trigger: ${jobDTO.triggers}">
<p><b>nextFireTime</b> <span th:text="${trigger.nextFireTime}"> </span></p>
<hr>
</th:block>
</dd>
</dl>
<!-- important part.. how to pass the jobDTO object back to the controller -->
<form id="form2" action="#" th:action="#{/deleteJob}" th:object="${jobDTO}" th:method="post">
<input type="text" th:value="*{identity.name}" th:field="*{identity.name}" hidden/>
<button type="submit" value="Submit" class="btn btn-danger btn-sm" >Delete Job</button>
</form>
</div>
</div>
</div>
</div>
</th:block>
my controller relevant parts are:
#GetMapping(value = "/deleteJob")
public String deleteJobPage(Model model) {
model.addAttribute("jobDTO", new ScheduleJobDTO());
//Returns the Home page with the prepared model attributes
return "Home";
}
// =================
#PostMapping("/deleteJob")
public String deleteJob(#ModelAttribute final ScheduleJobDTO jobDTOReturn, BindingResult bindingResult, Model model) {
// I want to receive the jobDTO object here
schedulerService.deleteJobFromGroup(jobDTOReturn.getIdentity().getGroup(),
jobDTOReturn.getIdentity().getName());
return "redirect:/";
}
what I am missing here?
I think there is an error in your input tag, try this :
<input type="text" th:value="${jobDTO.identity.name}" th:field="*{identity.name}" hidden/>

How can i resolve my update record query in same page?

In My list view I have all the details of department. But when I click on details It will display me a Pop-up. In Pop up box it has to fetch and give me all the details of particular field but instead of that it always give me details of last inserted record
Here is my code of blade file
#extends('layouts.master')
#section('content')
<section>
<div class="page-wrapper">
<div class="container-fluid">
<div class="row page-titles">
<div class="col-md-5 align-self-center">
<h4 class="text-themecolor">{{__('Department')}}</h4>
</div>
</div>
<div class="card">
<div class="card-body">
<div>
+ Add Department
</div>
<div id="myModal" class="modal fade in" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Add Department </h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<form id="myform" class="form-horizontal" method="POST" action="{{route('store_department')}}">
#csrf
<div class="form-group">
#if(Session::has('key'))
<?php $createdBy = Session::get('key')['username']; ?>
#endif
<div class="col-md-12">
<input type="hidden" name="createdBy" value="<?php echo $createdBy ?>">
<input type="text" class="form-control" name="nameOfDepartment" placeholder="Add New Department">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-info waves-effect" data-dismiss="modal">Save</button>
<button type="button" class="btn btn-default waves-effect" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<div class="table-responsive m-t-40">
<table class="table table-bordered table-striped ">
<thead>
<tr>
<th>Department Name</th>
<th>Created By</th>
<th>Created On</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#if($listOfDepartment != null)
#foreach($listOfDepartment as $departmentList)
<tr>
<td>{{$departmentList->nameOfDepartment}}</td>
<td>{{$departmentList->createdBy}}</td>
<td>{{$departmentList->created_at}}</td>
<td>
<i class="fa fa-edit fa-lg" style="color:#0066ff" aria-hidden="true"></i>
<i class="fa fa-trash fa-lg" style="color:red" aria-hidden="true"></i>
</td>
</tr>
#endforeach
#endif
</tbody>
</table>
</div>
</div>
<div id="myEditModal" class="modal fade in" tabindex="-1" role="dialog" aria-labelledby="myModalLabelEdit" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabelEdit">Edit Department</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<form class="form-horizontal" method="POST" action="{{ route('update_department', $departmentList->id) }}">
#csrf
#method('PUT')
<div class="form-group">
<div class="col-md-12">
<input type="text" name="nameOfDepartment" class="form-control" placeholder="Edit Department" value="{{$departmentList->nameOfDepartment}}">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-info waves-effect" data-dismiss="modal">Update</button>
<button type="button" class="btn btn-default waves-effect" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
#endsection
here is my code of department controller
<?php
namespace App\Http\Controllers;
use App\Department;
use Illuminate\Http\Request;
class DepartmentController extends Controller
{
public function createDepartment()
{
return view('pages.department');
}
public function storeDepartment(Request $request)
{
$department = new Department();
$department->createdBy = $request->get('createdBy');
$department->nameOfDepartment = $request->get('nameOfDepartment');
$department->save();
return redirect('list-department')->with('Success', 'Department Added Successfully!');
}
public function listDepartment()
{
$listOfDepartment = Department::all();
return view('pages.department', compact('listOfDepartment'));
}
public function editDepartment($id)
{
$departments = Department::find($id);
return view('pages.department', compact('departments', 'id'));
}
public function updateDepartment(Request $request, $id)
{
$department = Department::find($id);
$department->createdby = $request->get('createdBy');
$department->nameOfDepartment = $request->get('nameOfDepartment');
$department->save();
return redirect('list-department')->with('Success', 'Department Updated Successfully!');
}
public function deleteDepartment($id)
{
$department = Department::find($id);
$department->delete();
return redirect('list-department')->with('Success', 'Department Deleted SuccessFully!');
}
}
And Here Are My Routes
Route::get('add-department', 'DepartmentController#createDepartment')->name('create_department');
Route::post('store-department', 'DepartmentController#storeDepartment')->name('store_department');
Route::get('list-department', 'DepartmentController#listDepartment')->name('list_department');
Route::get('edit-department/{id}', 'DepartmentController#editDepartment')->name('edit_department');
Route::put('update-department/{id}', 'DepartmentController#updateDepartment')->name('update_department');
Route::get('delete-department/{id}', 'DepartmentController#deleteDepartment')->name('delete_department');
Your modal is always created with the last $departmentList
You are using this to create some kind of list
#foreach($listOfDepartment as $departmentList)
<tr>
<td>{{$departmentList->nameOfDepartment}}</td>
<td>{{$departmentList->createdBy}}</td>
<td>{{$departmentList->created_at}}</td>
<td>
<a href="{{route('edit_department', $departmentList->id)}}" data-toggle="modal" data-target="#myEditModal">
<i class="fa fa-edit fa-lg" style="color:#0066ff" aria-hidden="true"></i>
</a>
<a href="{{route('delete_department', $departmentList->id)}}">
<i class="fa fa-trash fa-lg" style="color:red" aria-hidden="true"></i>
</a>
</td>
</tr>
#endforeach
You end the loop here so $departmentList is the last one from the loop
Later you add some html again that uses $departmentList
<form class="form-horizontal" method="POST" action="{{ route('update_department', $departmentList->id) }}">
This variable still contains the last department from your loop before.
You can probably utilize some javascript that opens the modal and put the correct post url in place.

Failed to load resource: the server responded with a status of 500 (Internal Server Error) dynamic api

downloaded latest(3.0) boilerplate with zero.
Followed up the task creator application implementation on codeproject.com
I have added simple entity (Clients) instead of tasks.
The displaying of tasks work fine. However, when I try to add a new client the it seems that the dynamic api is not available and I get the following error:
ClientsController:
`[AbpMvcAuthorize]
public class ClientsController : MyAppControllerBase
{
private readonly IClientAppService _clientService;
public ClientsController(IClientAppService clientService)
{
_clientService = clientService;
}
public async Task<ViewResult> Index(GetAllClientsInput input)
{
var output = await _clientService.GetAll(input);
var model = new Web.Models.Clients.IndexViewModel(output.Items);
return View("Index", model);
}
public async Task Create(CreateClientInput input)
{
await _clientService.Create(input);
}
public async Task Delete(CreateClientInput input)
{
await _clientService.Create(input);
}
}`
Index.js:
(function() {
$(function() {
var _clientService = abp.services.app.client;
var _$modal = $('#ClientCreateModal');
var _$form = _$modal.find('form');
_$form.validate();
_$form.find('button[type="submit"]').click(function (e) {
e.preventDefault();
if (!_$form.valid()) {
return;
}
var client = _$form.serializeFormToObject(); //serializeFormToObject is defined in main.js
abp.ui.setBusy(_$modal);
_clientService.create(client).done(function () {
_$modal.modal('hide');
location.reload(true); //reload page to see new user!
}).always(function () {
abp.ui.clearBusy(_$modal);
});
});
_$modal.on('shown.bs.modal', function () {
_$modal.find('input:not([type=hidden]):first').focus();
});
});
})();
Index.cshtml
#section scripts
{
<environment names="Development">
<script src="~/js/views/clients/Index.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="~/js/views/clients/Index.min.js" asp-append-version="true"></script>
</environment>
}
<div class="row clearfix">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="card">
<div class="header">
<h2>
#L("Clients")
</h2>
<ul class="header-dropdown m-r--5">
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">more_vert</i>
</a>
<ul class="dropdown-menu pull-right">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
</ul>
</li>
</ul>
</div>
<div class="body table-responsive">
<table class="table">
<thead>
<tr>
<th>#L("UserName")</th>
<th>#L("FullName")</th>
<th>#L("EmailAddress")</th>
<th>#L("IsActive")</th>
</tr>
</thead>
<tbody>
#foreach (var user in Model.Clients)
{
<tr>
<td>#user.FirstName</td>
<td>#user.LastName</td>
<td>#user.Email</td>
<td>#user.Mobile</td>
</tr>
}
</tbody>
</table>
<button type="button" class="btn btn-primary btn-circle waves-effect waves-circle waves-float pull-right" data-toggle="modal" data-target="#ClientCreateModal">
<i class="material-icons">add</i>
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="ClientCreateModal" tabindex="-1" role="dialog" aria-labelledby="ClientCreateModalLabel" data-backdrop="static">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form name="userCreateForm" role="form" novalidate class="form-validation">
<div class="modal-header">
<h4 class="modal-title">
<span>#L("CreateNewClient")</span>
</h4>
</div>
<div class="modal-body">
<div class="form-group form-float">
<div class="form-line">
<input class="form-control" type="text" name="FirstName" required maxlength="#AbpUserBase.MaxUserNameLength" minlength="2">
<label class="form-label">#L("FirstName")</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" name="LastName" class="form-control" required maxlength="#AbpUserBase.MaxNameLength">
<label class="form-label">#L("LastName")</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" name="Mobile" class="form-control" required maxlength="#AbpUserBase.MaxSurnameLength">
<label class="form-label">#L("Mobile")</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="email" name="Email" class="form-control" required maxlength="#AbpUserBase.MaxEmailAddressLength">
<label class="form-label">#L("Email")</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default waves-effect" data-dismiss="modal">#L("Cancel")</button>
<button type="submit" class="btn btn-primary waves-effect">#L("Save")</button>
</div>
</form>
</div>
</div>
</div>
client service :
[AbpAuthorize(PermissionNames.Pages_Tenants)]
public class ClientAppService : ApplicationService, IClientAppService
{
private readonly IRepository<Client> _clientRepository;
public ClientAppService(IRepository<Client> clientRepository)
{
_clientRepository = clientRepository;
}
public async Task<ListResultDto<ClientListDto>> GetAll(GetAllClientsInput input)
{
var clients = await _clientRepository
.GetAll().ToListAsync<Client>();
return new ListResultDto<ClientListDto>(
ObjectMapper.Map<List<ClientListDto>>(clients));
}
public async Task Create(CreateClientInput input)
{
var task = ObjectMapper.Map<Client>(input);
await _clientRepository.InsertAsync(task);
}
}
the server does not get hit at all on the create action.
any idea what I am missing?
I think there's a misunderstanding with IMustHaveTenant interface. When you derive an entity from IMustHaveTenant you cannot use that entity in host environment. The host has no tenant id. As far as i understand clients are belonging to tenants. So what you have to do is, remove the Clients page from host menu. Whenever you want to see clients of tenants, just use impersonation.
To show/hide specific menu items you can use requiredPermissionName. A permission can be configured to use just for tenants/host/both. So create a new permission which is configured to be used for tenants. Set that permission while you create new MenuItemDefinition for clients page. That's it!
Read => https://aspnetboilerplate.com/Pages/Documents/Navigation?searchKey=navigation#registering-navigation-provider

MVC.NET Core Bootstrap-Modal forms with multi-parameters don't reach Post controller

I have a web app using modal forms to confirm some of the actions my users (or admin) might be allowed to do. The modal form setup is taken from Microsoft's IdentitySampleApplication project and been incorporated for my project in mostly the same way with this one difference. I am using the generic modal forms. I am trying to allow a user to have multiple user roles on an application (while their sample presumes the user will only have one role.)
I am now working out the deletion of roles for this type multi-role scenario for maintenance. I should point out that all instances of code involving only one id work fine, it is this one instance with 2 ids that fails to pass through either of the ids I need at the controller.
The deletion of a user role requires the key of the user and the role.
My controller has a bit of code like the following to accept the ids and present a modal form, which works quite nicely.
[HttpGet]
public IActionResult DeleteUserRole( string userid, string roleid ){...}
The HttpPost portion looks something like this
[HttpPost]
public IActionResult DeleteUserRole( string userid, string roleid, IFormCollection form ){...}
however, this second action never gets the ids that were passed to the modal forms get method.
In all methods that only have a single routing id, I have no issues. It is only this one method that vexes me. I call it from this link. Note the two asp-route variables and I suspect this is at the heart of my issue, but the get call is fine with this, it is the post that has no values:
<a id="deleteRoleModal" asp-action="DeleteUserRole"
asp-route-userid="#item.userId" asp-route-roleid="#item.roleId"
data-toggle="modal" data-target="#modal-action-role"
class="btn btn-sm btn-danger">
where at the base of the form I have a modal form implementation it uses looking like this:
#await Html.Partial( "_Modal", new BootstrapModel { ID = "modal-action-role", AreaLabeledId = "modal-action-role-label", Size = ModalSize.Medium } )
My modal form looks much like the samples used in the IdentitySampleProject and is shown here, it was not altered in any meaningful way yet works fine with single parameter call backs:
#model string
#using MyModels
<form asp-action="DeleteUserRole" role="form">
#Html.AntiForgeryToken()
#await Html.Partial( "_ModalHeader", new ModalHeader { Heading = "Delete User Role" } )
<div class="modal-body form-horizontal">
Are you sure you want to delete user role #Model?
</div>
#await Html.Partial( "_ModalFooter", new ModalFooter { SubmitButtonText = "Delete" } )
</form>
I am looking for a direction to go to solve the issue. I am hoping that indeed the double route ids are my issue, but I can not seem to find anyone else doing something like this in samples.
The generated management page looks mostly like this:
<!DOCTYPE html>
<html>
<head>
<title>my company</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/lib/bootswatch/spacelab/bootstrap.min.css" />
<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css" />
<link rel="stylesheet" href="/css/site.css" />
<link rel="stylesheet" href="/css/navTabs.css" />
<link rel="stylesheet" href="/css/partner.css" />
</head>
<body>
<div id="header">
<div class="slideContainer">
<div class="slide"><img src="/image/Firm-small2.jpg" alt="Offices" class="headerImage" /></div>
<div class="slide"><img src="/image/InLibrary225.jpg" alt="Library" class="headerImage"></div>
<div class="slide"><img src="/image/DSC_9999editSM.JPG" alt="Offices" class="headerImage" /></div>
<div class="slide"><img src="/image/DSC_9925edit2SM.JPG" alt="Computer Room" class="headerImage" /></div>
</div>
<nav class="navbar navbar-inverse">
<ul class="nav navbar-nav navbar-right ">
<li class="navtext">
<label>-- Welcome: Webmaster </label>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="navtext">
<label>Your Proven Partner in Cartoon Drawing</label>
</li>
</ul>
</nav>
</div>
<div id="sidebar">
<div><img src="/image/headerLogo.gif" alt="my company Logo" class="logoImage" /></div>
<nav id="menu">
<ul class="nav navbar-inverse">
<li>Home</li>
<li>
<div id="menuGroupItem">
Partners
<a data-toggle="collapse" data-target="#partnerMenu"><i class="fa fa-chevron-down"></i></a>
</div>
<ul id="partnerMenu" class="nav collapse" role="menu" aria-labelledby="partnerMenu">
<li><i class="fa fa-caret-right"></i> Eddy A Fish</li>
<li><i class="fa fa-caret-right"></i> Tom A Hawk</li>
</ul>
</li>
<li>Services</li>
<li>News</li>
<li>Events</li>
<li>Publications</li>
<li>Firm History</li>
<li>Contact</li>
<li class="divider"></li>
<li>Manage Website</li>
<li>Logout</li>
</ul>
</nav>
<div class="affiliation">
<table>
<tr>
<td>
<img src="/image/WBE_color_rgb_UP25.jpg" alt="" class="affiliationImage" />
</td>
</tr>
</table>
</div>
<div>
<ul class="rightAlign">
<li> </li>
<li>my company</li>
<li>16 main street</li>
<li>anytown, pa 00000</li>
<li> </li>
<li>610.111.1111</li>
</ul>
</div>
</div>
<div id="wrapper">
<div id="main" class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="/Users/UserRole/a2c77901-4a74-49aa-9354-1fadc943c8c4" method="post"><input id="UserId" name="UserId" type="hidden" value="a2c77901-4a74-49aa-9354-1fadc943c8c4" /><input id="UserName" name="UserName" type="hidden" value="BioEditor" /> <h3>Add roles for user: <span class="text-success">BioEditor</span></h3>
<div>
<div class="form-group">
<table class="table table-responsive">
<thead>
<th>Role</th>
<th>Action</th>
</thead>
<tbody>
<tr>
<td><i class="fa fa-check text-success"> </i>BioEditor</td>
<td>
<a id="deleteRoleModal" data-toggle="modal" data-target="#modal-action-role" class="btn btn-sm btn-danger" href="/Users/DeleteUserRole?userid=a2c77901-4a74-49aa-9354-1fadc943c8c4&roleid=8b12b24d-5836-46eb-a7aa-0be1818a67f5">
<i class="fa fa-trash"></i> Delete
</a>
</td>
</tr>
<tr>
<td><i class="fa fa-check text-success"> </i>PowerEditor</td>
<td>
<a id="deleteRoleModal" data-toggle="modal" data-target="#modal-action-role" class="btn btn-sm btn-danger" href="/Users/DeleteUserRole?userid=a2c77901-4a74-49aa-9354-1fadc943c8c4&roleid=c4f3bdf8-b880-423c-8de3-1e51329da104">
<i class="fa fa-trash"></i> Delete
</a>
</td>
</tr>
<tr>
<td><i class="fa fa-check text-success"> </i>Administrator</td>
<td>
<a id="deleteRoleModal" data-toggle="modal" data-target="#modal-action-role" class="btn btn-sm btn-danger" href="/Users/DeleteUserRole?userid=a2c77901-4a74-49aa-9354-1fadc943c8c4&roleid=f1aafc1e-0527-4542-8f0e-fb1afeccac46">
<i class="fa fa-trash"></i> Delete
</a>
</td>
</tr>
</tbody>
</table>
</div>
<div class="form-group">
<div class="input-group">
<select class="input-group form-control" data-val="true" data-val-required="The ApplicationRoleId field is required." id="ApplicationRoleId" name="ApplicationRoleId">
<option>Please select</option>
<option value="8b12b24d-5836-46eb-a7aa-0be1818a67f5">BioEditor</option>
<option value="c4f3bdf8-b880-423c-8de3-1e51329da104">PowerEditor</option>
<option value="f1aafc1e-0527-4542-8f0e-fb1afeccac46">Administrator</option>
<option value="fe77274d-4b16-46a6-8177-a84faf198c9b">EventEditor</option>
</select>
<span class="input-group-btn">
<button type="submit" class="btn btn-sm btn-success"><i class="fa fa-user"> </i> Add Selected Role </button>
</span>
<span class="field-validation-valid" data-valmsg-for="ApplicationRoleId" data-valmsg-replace="true"></span>
</div>
</div>
</div>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8KeASaIZMdBDjnZy_1CdaouczJ-zwxPaQp-N5OQ5bGWfYzVfpDz7_iC0VlJb_cRDkqucT-8ENFhsNPe9Rng1Mqrm9VQbYQoSQwerxj953ql4v7dABrW6pioEySOJN7qFXaalGYePyjHoB0QiKxfuvkvh938tJG4gVnh5D1JvLyNBBKlR4d25PcoJOJZTdN_Bxg" /></form> </div>
</div>
<div aria-hidden="true" aria-labelledby="modal-action-role-label" role="dialog" tabindex="-1" id="modal-action-role" class="modal fade">
<div class="modal-dialog ">
<div class="modal-content">
</div>
</div>
</div>
</div>
</div>
<div id="footer" class="container-fluid">
<div class="navbar navbar-fixed-bottom navbar-inverse ">
<ul>
<li class="navbar-link">© my company</li>
<li class="navbar-link text-muted"><a id="disclaimerLink" href="#">Disclaimer</a></li>
</ul>
</div>
</div>
<script type="text/javascript" src="/lib/jquery/dist/jquery.js"></script>
<script type="text/javascript" src="/lib/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript" src="/js/site.js"></script>
</body>
</html>
Thanks for any direction you might be able to provide, Kent
That was exactly a nudge in the right direction to finding the issue, thanks Ahmar. What is going on, due to the 2 ids being passed back to the controller is that the data is wrapped up in a query string rather than as a real route {controller}{action}{id}.
The modal won't pass along the query string to the final so I changed the model and wrapped up the values in the modal form for the final deletion and it all worked. Thanks for asking the right the question to get this answered.

Submitting a POST object

I spent the whole weekend searching the net on my problem. It seems like I am missing something really silly, but I failed to pick it up.
Here's the problem. I sent an object to a JSP and on the JSP I could see its content. I them I submitted the form. Back in the controller, it shows the object is overwritten/recreated. I can't seem to understand. I checked the logs on my Tomcat but I do not see any error...
On my Controller:
#RequestMapping(value = {"/", "/home"}, method = RequestMethod.GET)
public String homePage(ModelMap model) {
model.addAttribute("user", getPrincipal());
Catalog catalog = catalogService.getCatalogByCategory(Catalog.CatalogCategory.ALL);
model.addAttribute("catalog", catalog);
model.addAttribute("numberOfItemsAdded", "500");
return "welcome";
}`
and in my JSP I have the following:
<form:form method="POST" modelAttribute="catalog">
<form:hidden path="id"/>
<div id="products" class="row list-group">
<c:forEach var="orderItem" items="${catalog.orderItems}">
<div class="item col-xs-4 col-lg-4">
<div class="thumbnail">
<img class="group list-group-image" src="http://placehold.it/400x250/000/fff" alt=""/>
<div class="caption">
<h4 class="group inner list-group-item-heading">
${orderItem.name}</h4>
<p class="group inner list-group-item-text">
${orderItem.description}
</p>
<div class="row">
<div class="col-xs-12 col-md-6">
<p class="lead">
R ${orderItem.price}</p>
</div>
<div class="col-xs-12 col-md-6">
<label for="${orderItem.id}" class="btn btn-primary">Add to Cart <input
type="checkbox" id="${orderItem.id}" name="orderItem.addedToCart"
class="badgebox"><span class="badge">&check;</span></label>
</div>
</div>
</div>
</div>
</div>
</c:forEach>
</div>
<div class="row">
<div class="form-group">
<div class="col-sm-12 pull-right">
</div>
<div class="col-sm-2 pull-right">
<input type="submit"
class="btn btn-default btn-block btn-primary"
value="Next" name="action" formmethod="POST"
formaction="confirmList"/>
</div>
</div>
</div>
</form:form>`
After pressing "Next", which submits the form data to a controller:
#RequestMapping(value = "/confirmList", method = RequestMethod.POST)
public String confirmList(#ModelAttribute Catalog catalog, #ModelAttribute String numberOfItemsAdded) {
System.out.println("\n\n------>catalog = " + catalog);
System.out.println("\n\n------>numberOfItemsAdded = " + numberOfItemsAdded);
List<OrderItem> selectedItems = new ArrayList<OrderItem>();
for (OrderItem orderItem : catalog.getOrderItems()) {
if (orderItem.isAddedToCart()) {
selectedItems.add(orderItem);
}
}
//model.addAttribute("numberOfItemsAdded", selectedItems.size());
return "welcome";
}
`
The System.out.println(...) output the following:
------>catalog = Catalog{id=1, name='null', category='null', orderItems=null}
------>numberOfItemsAdded =
Those are empty outputs.... :'(
I have no idea what I am doing wrong here.....
This was answered in a comment line by George. All I had to do is hide/bind those null fields.
It is very concerning that we use the term 'hidden' to also mean 'ignore' or 'leave as is'. But anyway, the solution above did exactly what I was looking for.
Thanks to the Community

Resources