Using MVC .NetCore, I populate a "partial" view and a Table. Within that table, a list of records.
Each row have a button to edit or delete. To delete a record, I need to have 4 IDs since the PK is made of those 4 keys.
I was able to make it work with a javascript, however, I do not like the "confirm" display being produce. I would like to have a more elegant way and use a modal form for this. But how do I retrieve the 4 values when clicking a button in of the row?
Here is a Row being populated from my Model:
<td>
<div>
<a onclick="showInPopup('#Url.Action("Match_StatsCreateOrEdit","Match_Stats",new {comp_id=item.Match_Stats.Comp_Id, team_id=item.Match_Stats.Team_Id,match_id=item.Match_Stats.Match_Id, match_Stat_Id=item.Match_Stats.Match_Stat_Id},Context.Request.Scheme)','Update A Stat')" class="btn btn-primary btn-xs"><i class="fas fa-pencil-alt"></i> Edit</a>
<form asp-action="Match_StatsDelete" asp-route-comp_Id="#item.Match_Stats.Comp_Id" asp-route-team_Id="#item.Match_Stats.Team_Id" asp-route-Match_Id="#item.Match_Stats.Match_Id"
asp-route-Match_Stat_Id="#item.Match_Stats.Match_Stat_Id" onsubmit="return jQueryAjaxDelete(this)" class="d-inline">
<button type="submit" class="btn btn-warning btn-xs"><i class="fas fa-trash"></i> Delete</button>
</form>
</div>
</td>
Here is the Javascript currently used:
jQueryAjaxDelete = form => {
if (confirm('Are you sure want to delete this record ?')) {
try {
$.ajax({
type: 'POST',
url: form.action,
data: new FormData(form),
contentType: false,
processData: false,
success: function (res) {
$('#view-all').html(res.html);
$.notify('Deleted Successfully !', {
globalPostion: 'Top Center',
className: 'success'
});
},
error: function (err) {
console.log(err)
}
})
} catch (ex) {
console.log(ex)
}
}
//prevent default form submit event
return false;
}
Here is the Model I would like to use. How do I get the 4 ID into this?
<!-- /.modal -->
<div class="modal fade" id="modal-removeplayers">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Confirmation needed</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Do you really want to delete this record ?</p>
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<!-- CODE HERE TO RETRIEVE All 4 IDs and Call the "delete" on the Controller -->>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
One way is that put the modal inside the loop:
Model:
public class Test
{
public Match_Stats Match_Stats { get; set; }
//other properties....
}
public class Match_Stats
{
public int Comp_Id { get; set; }
public int Team_Id { get; set; }
public int Match_Id { get; set; }
public int Match_Stat_Id { get; set; }
//other properties.....
}
View(Index.cshtml):
#model IEnumerable<Test>
#{
int i = 0;
}
#foreach (var item in Model)
{
//other code.....
<a onclick="showInPopup('#Url.Action("Match_StatsCreateOrEdit","Match_Stats",new {comp_id=item.Match_Stats.Comp_Id, team_id=item.Match_Stats.Team_Id,match_id=item.Match_Stats.Match_Id, match_Stat_Id=item.Match_Stats.Match_Stat_Id},Context.Request.Scheme)','Update A Stat')" class="btn btn-primary btn-xs"><i class="fas fa-pencil-alt"></i> Edit</a>
//add the button to launch the modal
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-removeplayers_#i"><i class="fas fa-trash"></i> Delete</button>
<div class="modal fade" id="modal-removeplayers_#i">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Confirmation needed</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Do you really want to delete this record ?</p>
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
//move the form to here.....
<form asp-action="Match_StatsDelete" asp-route-comp_Id="#item.Match_Stats.Comp_Id" asp-route-team_Id="#item.Match_Stats.Team_Id" asp-route-Match_Id="#item.Match_Stats.Match_Id"
asp-route-Match_Stat_Id="#item.Match_Stats.Match_Stat_Id" class="d-inline">
<button type="submit" class="btn btn-warning btn-xs"><i class="fas fa-trash"></i> Delete</button>
</form>
</div>
</div>
</div>
</div>
i++; //add this...
}
Controller:
public IActionResult Index()
{
//hard-coded the data just for easy testing!!!
var model = new List<Test>()
{
new Test(){Match_Stats=new Match_Stats(){Comp_Id=1,Match_Id=11,Match_Stat_Id=12,Team_Id=13}},
new Test(){Match_Stats=new Match_Stats(){Comp_Id=2,Match_Id=21,Match_Stat_Id=22,Team_Id=23}},
new Test(){Match_Stats=new Match_Stats(){Comp_Id=3,Match_Id=31,Match_Stat_Id=32,Team_Id=33}}
};
return View(model);
}
[HttpPost]
public IActionResult Match_StatsDelete(int Comp_Id,int Match_Id, int Match_Stat_Id,int Team_Id)
{
//do your stuff.......
}
The second way, you can use partial view to reuse the modal and use ajax to invoke the partial view.
Model:
public class Test
{
public Match_Stats Match_Stats { get; set; }
//other properties....
}
public class Match_Stats
{
public int Comp_Id { get; set; }
public int Team_Id { get; set; }
public int Match_Id { get; set; }
public int Match_Stat_Id { get; set; }
//other properties.....
}
View(Index.cshtml):
#model IEnumerable<Test>
#foreach (var item in Model)
{
<a onclick="showInPopup('#Url.Action("Match_StatsCreateOrEdit","Match_Stats",new {comp_id=item.Match_Stats.Comp_Id, team_id=item.Match_Stats.Team_Id,match_id=item.Match_Stats.Match_Id, match_Stat_Id=item.Match_Stats.Match_Stat_Id},Context.Request.Scheme)','Update A Stat')" class="btn btn-primary btn-xs"><i class="fas fa-pencil-alt"></i> Edit</a>
<button type="button" class="btn btn-primary" onclick="toggleModal('#item.Match_Stats.Comp_Id','#item.Match_Stats.Team_Id','#item.Match_Stats.Match_Id','#item.Match_Stats.Match_Stat_Id')"><i class="fas fa-trash"></i> Delete</button>
}
<div id="loadModal">
<!--load the modal-->
</div>
#section Scripts
{
<script>
function toggleModal(comp_id,team_id,match_id,match_Stat_Id) {
var model = {
comp_id : comp_id,
team_id:team_id,
match_id:match_id,
match_Stat_Id:match_Stat_Id
};
$.ajax({
type: "Post",
url: "/Home/LoadPartial",
data:model,
success: function (data) {
$("#loadModal").html(data);
$('#modal-removeplayers').modal('show')
}
})
}
</script>
}
Partial View in /Views/Shared folder(Partial.cshtml):
#model Match_Stats
<div class="modal fade" id="modal-removeplayers">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Confirmation needed</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Do you really want to delete this record ?</p>
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<form asp-action="Match_StatsDelete" asp-route-comp_Id="#Model.Comp_Id" asp-route-team_Id="#Model.Team_Id" asp-route-Match_Id="#Model.Match_Id"
asp-route-Match_Stat_Id="#Model.Match_Stat_Id" class="d-inline">
<button type="submit" class="btn btn-warning btn-xs"><i class="fas fa-trash"></i> Delete</button>
</form>
</div>
</div>
</div>
</div>
Controller:
public IActionResult Index()
{
//hard-coded the data just for easy testing!!!
var model = new List<Test>()
{
new Test(){Match_Stats=new Match_Stats(){Comp_Id=1,Match_Id=11,Match_Stat_Id=12,Team_Id=13}},
new Test(){Match_Stats=new Match_Stats(){Comp_Id=2,Match_Id=21,Match_Stat_Id=22,Team_Id=23}},
new Test(){Match_Stats=new Match_Stats(){Comp_Id=3,Match_Id=31,Match_Stat_Id=32,Team_Id=33}}
};
return View(model);
}
[HttpPost]
public IActionResult Match_StatsDelete(int Comp_Id,int Match_Id, int Match_Stat_Id,int Team_Id)
{
//do your stuff.......
}
[HttpPost]
public IActionResult LoadPartial(Match_Stats model)
{
//hard-coded the data just for easy testing!!!
var list = new List<Match_Stats>()
{
new Match_Stats(){Comp_Id=1,Match_Id=11,Match_Stat_Id=12,Team_Id=13},
new Match_Stats(){Comp_Id=2,Match_Id=21,Match_Stat_Id=22,Team_Id=23},
new Match_Stats(){Comp_Id=3,Match_Id=31,Match_Stat_Id=32,Team_Id=33}
};
var data = list.Where(a => a.Comp_Id == model.Comp_Id & a.Match_Id == model.Match_Id & a.Team_Id == model.Team_Id & a.Match_Stat_Id == model.Match_Stat_Id).FirstOrDefault();
return PartialView("Partial", data);
}
Result:
Related
This is follow up question on this (Bootstrap Modal Confirmation using ASP.Net MVC and a table)
Using MVC .NetCore, I populate a "partial" view and a Table (called _Match_StatsViewAll.cshtml under a directory of the same name of my controller Match_Stats).
It's being called from an Indexview:
public async Task<ViewResult> Match_StatsIndex(string message, string comp_id, string match_id, string team_id)//ACTION METHOD/View Results
Within that table (code below) , a list of records. Each row have a button to edit or delete. To delete a record, I need to have 4 IDs since the PK is made of those 4 keys. I was able to make it work with a javascript, however, I did not like the "confirm" display being produced. Thanks to this post, I was able to add a modal for each rows in the table and delete the record. However now, If I use the original json call to refresh the partial model (that only refresh the table), I have this screen:
Here is a Row being populated from my Model:
<td>
<div>
#{i++; }
<a onclick="showInPopup('#Url.Action("Match_StatsCreateOrEdit","Match_Stats",new {comp_id=item.Match_Stats.Comp_Id, team_id=item.Match_Stats.Team_Id,match_id=item.Match_Stats.Match_Id, match_Stat_Id=item.Match_Stats.Match_Stat_Id},Context.Request.Scheme)','Update A Stat')" class="btn btn-primary btn-xs"><i class="fas fa-pencil-alt"></i> Edit</a>
<form asp-action="Match_StatsDelete" asp-route-comp_Id="#item.Match_Stats.Comp_Id" asp-route-team_Id="#item.Match_Stats.Team_Id" asp-route-Match_Id="#item.Match_Stats.Match_Id"
asp-route-Match_Stat_Id="#item.Match_Stats.Match_Stat_Id" onsubmit="return jQueryAjaxDelete(this)" class="d-inline">
<button type="submit" class="btn btn-warning btn-xs"><i class="fas fa-trash"></i> Delete</button>
</form>
#*//add the button to launch the modal*#
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-removeplayers_#i"><i class="fas fa-trash"></i> Delete modal</button>
<div class="modal fade" id="modal-removeplayers_#i">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Confirmation needed</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Do you really want to delete this record ?</p>
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<form asp-action="Match_StatsDelete" asp-route-comp_Id="#item.Match_Stats.Comp_Id" asp-route-team_Id="#item.Match_Stats.Team_Id" asp-route-Match_Id="#item.Match_Stats.Match_Id"
asp-route-Match_Stat_Id="#item.Match_Stats.Match_Stat_Id" onsubmit="return jQueryAjaxDeleteDirect(this)" class="d-inline">
<button type="submit" class="btn btn-warning btn-xs"><i class="fas fa-trash"></i> Delete Json</button>
</form>
</div>
</div>
</div>
</div>
</div>
</td>
In my controller - calling the delete :
public async Task<IActionResult> Match_StatsDelete(string comp_id, string team_id, string match_id, string match_stat_id)
{
// Wrap the code in a try/catch block
try
{
var deleteok = _match_statsRepository.Delete(entity);
if (deleteok != null)
{
//Code Here to populate my table only since this is a partial view inside a page
return Json(new { isValid = true, html = JavaScriptConvert.RenderRazorViewToString(this, "_Match_StatsViewAll", myPartialmodelpopulated) });
}
else
{
ModelState.AddModelError("", "Could not Delete Match");
return RedirectToAction("MatchIndex", new { message = "Success", comp_id });
}
}
catch (Exception ex)
{
// Log the exception to a file.We discussed logging to a file
//......More code here for the log has been removed //
return View("Error");
}
}
Here is the Javascript:
jQueryAjaxDeleteDirect = form => {
try {
$.ajax({
type: 'POST',
url: form.action,
data: new FormData(form),
contentType: false,
processData: false,
success: function (res) {
$('#view-all').html(res.html);
$.notify('Deleted Successfully !', {
globalPostion: 'Top Center',
className: 'success'
});
},
error: function (err) {
console.log(err)
}
})
} catch (ex) {
console.log(ex)
}
//prevent default form submit event
return false;
}
The " return Json" call works fine if I use the original code (so no MODAL form - just the javascript "confirm") .
Thank you for the help!
I need to call a delete method in my index.cshtml.cs from JavaScript. The reason for that is I want to use a modal or a sweet alert confirmation before deleting. Using my present code, I can get the "Id" of the record I want to delete but I am stuck on how to call my delete method in index.cshtml.cs and pass the Id to it. I don't like to use the API controller.
Here is my code.
index.cshtml
<td>
<button
data-id="#item.Id"
data-body-message="Are you sure?"
class="btn btn-danger btn-sm delete">
Delete
</button>
<a asp-page="Upsert" asp-route-id="#item.Id" class="btn btn-success btn-sm text-white">Edit</a>
</td>
</tr>
index.cshtml.cs
public async Task<IActionResult> OnPostDeleteAsync(int id)
{
var customer = await context.Customers.FirstOrDefaultAsync(x => x.Id == id);
if (customer == null)
{
return NotFound();
}
context.Customers.Remove(customer);
await context.SaveChangesAsync();
return RedirectToPage("Index");
}
customer.js
$((function () {
var url;
var redirectUrl;
var target;
var id;
$('body').append(`
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Warning</h4>
</div>
<div class="modal-body delete-modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" id="cancel-delete">Cancel</button>
<button type="button" class="btn btn-danger" id="confirm-delete">Delete</button>
</div>
</div>
</div>
</div>`);
//Delete Action
$(".delete").on('click', (e) => {
e.preventDefault();
target = e.target;
var Id = $(target).data('id');
id = Id;
var bodyMessage = $(target).data('body-message');
$(".delete-modal-body").text(bodyMessage);
$("#deleteModal").modal('show');
});
$("#confirm-delete").on('click', () => {
debugger;
$.ajax({
type: 'POST',
url: '?handler=Delete()',
success: function (data) {
alert(data);
},
error: function (error) {
alert("Error: " + error);
}
})
});
}()));
I am very new to ASP.net Core MVC.
im trying to post to mvc.core controller textarea value & id value & im getting js error "result is not defined "
and the only data the controller getting the id value .
Razor:
<div class="well">
<div class="row">
<form asp-action="AddToSellList" method="post" class="form-horizontal shadow" style="padding: 10px;">
#foreach (var item in Model)
{
<div class="well well-sm" style="background-color: white;">
<div class=" row">
<div class="col-sm-10 pull-right text-right">
#* Prop *#
#foreach (var qestion in item.QAViewModel)
{
<div id="#item.Id" class="collapse" style="background-color: gray">
<p>Qestion</p>
#* Prop *#
#foreach (var ansewr in qestion.Answers)
{
#* Prop *#
}
</div>
}
</div>
<div class="col-sm-2">
<button class="btnShowModal btn btn-primary btnWhiteSpace" id="#item.Id" type="button" value="#item.Id">
#item.Id
<i class="fas fa-info-circle" aria-hidden="true"></i>
</button>
<button type="button" class="btn btn-info" data-toggle="collapse" data-target="##item.Id"> <i class="fas fa-question-circle" aria-hidden="true"></i>Bla bla </button>
</div>
</div>
</div>
//Check box for selecting items for Action AddToSellList
<input type="checkbox" name="Hiden" value="#item.Id"/>
}
<button type="submit" id="btt"> submit to Action AddToSellList</button>
</form>
</div>
</div>
<div class="modal fade" tabindex="-1" id="loginModal"
data-keyboard="false" data-backdrop="static">
<div class="modal-dialog modal-sm ">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<i class="fas fa-window-close"></i>
</button>
<h4 class="modal-title">moder for posting for _AskQ </h4>
</div>
<div class="modal-body ">
<form asp-action="_AskQ" class="form-horizontal" style="padding: 10px; " method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" name="id" asp-for="#Model.First().SiteUserId" />
<div class="form-group">
<textarea name="Question" type="text" class="abc form-control text-right"id="a" required=""> </textarea>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary button button4">Ask</button>
</div>
</form>
</div>
</div>
</div>
</div>
Js:`
<script type="text/javascript">
$(document).ready(function() {
$('.collapse').on('shown.bs.collapse',
function() {
$(".collapse").addClass('glyphicon-chevron-up').removeClass('glyphicon-chevron-down');
});
});
</script>
<script type="text/javascript">
$(document).ready(function() {
$(".btnShowModal").click(function() {
$("#loginModal").modal('show');
var id = $(this).attr("id");
//$(".button4").click(function(e) {
// e.preventDefault();
$(".button4").click(function() {
url = '#Url.Action("_AskQ", "Bid")';
const value = $.trim($("textarea").val());
if (value === "") {
alert(value);
}
var data = {
Id: id,
value: value
};
console.log(id);
console.log(value);
$.ajax({
url: url,
data: data,
type: "POST"
}).done(function(result) {
$(id).html(result);
}).fail(function(x, s, e) {
alert("failed: " + s);
});
});
}
);
});
`
controller :
[HttpPost]
public IActionResult _AskQ(QAViewModel Vm)
{
if (!ModelState.IsValid)
{
return View(Vm);
}
var qustion = new QuoteQuestion
{
SiteUserId = _userManager.GetUserId(User),
QuoteId = Vm.Id,
Question = Vm.Question
};
_context.quoteQuestions.Add(qustion);
_context.SaveChanges();
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
ViewBag.q = qustion.Question;
ViewBag.Id = qustion.QuoteId;
ViewBag.SiteUId = qustion.SiteUserId;
}
return RedirectToAction("Index");
}
public class QAViewModel
{
public int QuoteQuestionId { get; set; }
public int Id { get; set; }
public string Question { get; set; }
public string SiteUserId { get; set; }
public virtual IList<Answers> Answers { get; set; }
}
In the data after ajax call, I can see the Id value & the Value value, but it keep failing to actually post to the controller (Id value only).
I'm posting from ActionResult name :index to ActionResult name _AskQ
Try the following changes in your code ,pay attention to the passed data name should be consistent with the parameter in the action
$(".button4").click(function() {
const value = $.trim($("textarea").val());
if (value === "") {
alert(value);
}
var Vm = {
Id: id,
Question: value
};
console.log(id);
console.log(value);
$.ajax({
type: "POST",
url: "/Bid/_AskQ",
contentType: "application/json",
data: "json",
data: JSON.stringify(Vm),
success: function (result) {
$(id).html(result);
},
error: function (x, s, e) {
alert("failed: " + s);
}
});
});
Add the [FromBody] attribute on the parameter when passing the json type data
[HttpPost]
public IActionResult _AskQ([FromBody]QAViewModel Vm)
Then the return value of the _AskQ method should be the html json result that you want to render the place with the specify id .Make the modification according to your needs。
In my strongly typed view I am looping over a list of objects coming from a database. Each of these objects is presented in a jumbotron, which has a button "Had role before". On click the modal opens and there I want to input some data in input boxes and save it to my database via an ajax call. One part of data that I want to input is the unique id which each object in the loop has. With the code I have so far I managed on click to get the id of the first object, but when I am clicking the buttons for the rest of the objects nothing happens.
This is the script in my view :
<script type="text/javascript">
$(document).ready(function () {
$(function () {
var idW;
$('#mdl').on('click', function () {
var parent = $(this).closest('.jumbotron');
var name = parent.find('input[name="mdlname"]').val();
var id = parent.find('input[name="mdlwrid"]').val();
var idW = id;
console.log(idW);
var titleLocation = $('#myModal').find('.modal-title');
titleLocation.text(name);
$('#myModal').modal('show');
});
});
$('#mdlSave').on('click', function () {
console.log('x');
addPastRoleAjax();
});
function addPastRoleAjax() {
$.ajax({
type: "POST",
url: '#Url.Action("addPastRole", "WorkRoles")',
dataType: "json",
data: {
wrId: idW,
dateStart: $("#wrdateStart").val(),
dateEnd: $("#wrknamedateEnd").val()
},
success: successFunc
});
function successFunc(data, status) {
if (data == false) {
$(".alert").show();
$('.btn').addClass('disabled');
//$(".btn").prop('disabled', true);
}
}
</script>
the loop :
#foreach (var item in Model)
{
<div class="jumbotron">
<input type="hidden" name="mdlwrid" value="#item.WorkRoleId" />
<input type="hidden" name="mdlname" value="#item.RoleName" />
<h1>#Html.DisplayFor(modelItem => item.RoleName)</h1>
<p class="lead">#Html.DisplayFor(modelItem => item.RoleDescription)</p>
<p> #Html.ActionLink("Focus on this one!", "addWorkRoleUser", new { id = item.WorkRoleId }, new { #class = "btn btn-primary btn-lg" })</p>
<p> <button type="button" id ="mdl" class="btn btn-default btn-lg" data-toggle="modal" data-target="#myModal">Had role in the past</button> </p>
</div>
}
The modal :
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
<input id="wrdateStart" class='date-picker' />
<input id="wrknamedateEnd" class='date-picker' />
</div>
<div class="modal-footer">
<button type="button" id="mdlSave" class="btn btn-default" data-dismiss="modal">Save</button>
</div>
</div>
</div>
Your problem is in the following piece of code:
#foreach (var item in Model)
{
<div class="jumbotron">
<input type="hidden" name="mdlwrid" value="#item.WorkRoleId" />
<input type="hidden" name="mdlname" value="#item.RoleName" />
<h1>#Html.DisplayFor(modelItem => item.RoleName)</h1>
<p class="lead">#Html.DisplayFor(modelItem => item.RoleDescription)</p>
<p> #Html.ActionLink("Focus on this one!", "addWorkRoleUser", new { id = item.WorkRoleId }, new { #class = "btn btn-primary btn-lg" })</p>
<p> <button type="button" id ="mdl" class="btn btn-default btn-lg" data-toggle="modal" data-target="#myModal">Had role in the past</button> </p>
</div>
}
You have used a foreach loop and inside it you create button elements with same id.
<button type="button" id ="mdl" class="btn btn-default btn-lg" data-toggle="modal" data-target="#myModal">Had role in the past</button>
So,foreach let you to create many buttons with same id. That's wrong and that's why you get that behavior(only first button work).The solution: Use classes instead.
I have following list view
Once I click Reject I just configured to open a modal dialog like following
So Once I submit this modal dialog I want to submit modal values to method to save that in database table.
this is relevant model classes
public class ProductViewModel
{
public AB_Product Products { get; set; }
public IEnumerable<AB_Product> LProducts { get; set; }
}
public partial class AB_Product
{
public string ProductID { get; set; }
public string ApprovalStatus { get; set; }
public string ReasonEn { get; set; }
public string ReasonAr { get; set; }
}
this is view page code
#model project_name.Models.ProductViewModel
<table class="table">
<tr>
<th>
Name
</th>
<th>
Action
</th>
</tr>
#foreach (var obj in Model.LProducts)
{
<tr>
#Html.HiddenFor(modelItem => obj.ProductID)
<td>
#Html.DisplayFor(modelItem => obj.ProductTitleEn)
</td>
<td>
<div class="btn-group btn-group-sm" id="CreateButton">
<button type="button" class="btn btn-default" onclick="location.href='#Url.Action("Create")';return false;">View Product</button>
</div>
#if (obj.ApprovalStatus == "Pending")
{
<div class="btn-group btn-group-sm" id="ApproveButton">
<button type="button" class="btn btn-success" onclick="location.href='#Url.Action("Change_Product_State","Home", new { productid = obj.ProductID, value = "Approved" },null)';return false;">Approve</button>
</div>
<div class="btn-group btn-group-sm" id="RejectButton">
<button type="button" id="modal-opener" class="btn btn-danger" return false;">Reject</button>
</div>
}
<div class="btn-group btn-group-sm" id="CreateButton">
<button type="button" class="btn btn-primary" onclick="location.href='#Url.Action("Create_ProductComments","Home", new { productid = obj.ProductID }, null)';return false;">Add Comments</button>
</div>
</td>
</tr>
}
</table>
<div id="dialog-modal" title="Basic modal dialog">
#using (Ajax.BeginForm("Change_Product_State", "Home", new { value = "Rejected" }, new AjaxOptions { UpdateTargetId = "ID", OnSuccess = "onSuccess" }))
{
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
#Html.LabelFor(m => m.Products.ReasonEn)
</div>
<div class="editor-field">
#Html.TextAreaFor(m => m.Products.ReasonEn)
#Html.ValidationMessageFor(m => m.Products.ReasonEn)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Products.ReasonAr)
</div>
<div class="editor-field">
#Html.TextAreaFor(m => m.Products.ReasonAr)
#Html.ValidationMessageFor(m => m.Products.ReasonAr)
</div>
<p>
<input type="submit" value="Submit" />
</p>
</fieldset>
</div>
}
</div>
#section Scripts
{
<script>
$(function () {
$("#dialog-modal").dialog({
autoOpen: false,
width: 400,
height: 400,
show: {
effect: "blind",
duration: 1000
},
hide: {
effect: "explode",
duration: 1000
}
});
$("#modal-opener").click(function () {
$("#dialog-modal").dialog("open");
});
});
function onSuccess() {
$("#dialog-modal").dialog("close");
}
</script>
}
how to bind list object I click which is ProductID with m.Products.ProductID
Remove the #Html.HiddenFor(modelItem => obj.ProductID) from the foreach loop and inside the Ajax.BeginForm() add
#Html.HiddenFor(m => m.Products.ProductID)
so its value can be posted. Then add the value of the ProductID as a data- attribute of the button (and change the id to class - see notes below)
<button type="button" class="modal-opener btn btn-danger" data-id="#obj.ProductID">Reject</button>
and modify the script to
$(".modal-opener").click(function () { // use class name
$('#Products_ProductID').val($(this).attr("data-id")); // set the value of the hidden input
$("#dialog-modal").dialog("open");
})
Note that you have a lot of invalid html due to duplicate id attributes generated by your foreach loop. Use class names instead. Your html should be
#foreach (var obj in Model.LProducts)
{
<tr>
<td>#Html.DisplayFor(modelItem => obj.ProductTitleEn)</td>
<td>
<div class="btn-group btn-group-sm CreateButton"> // change
<button type="button" class="btn btn-default" onclick="location.href='#Url.Action("Create")';return false;">View Product</button>
</div>
#if (obj.ApprovalStatus == "Pending")
{
<div class="btn-group btn-group-sm ApproveButton"> // change
<button type="button" class="btn btn-success" onclick="location.href='#Url.Action("Change_Product_State","Home", new { productid = obj.ProductID, value = "Approved" },null)';return false;">Approve</button>
</div>
<div class="btn-group btn-group-sm RejectButton"> // change
<button type="button" class="modal-opener btn btn-danger" data-id="#obj.ProductID">Reject</button> // as above
</div>
}
<div class="btn-group btn-group-sm CreateButton"> // change
<button type="button" class="btn btn-primary" onclick="location.href='#Url.Action("Create_ProductComments","Home", new { productid = obj.ProductID }, null)';return false;">Add Comments</button>
</div>
</td>
</tr>
}