I have two controllers, both are having view.
control#1->view#1
control#2->view#2
on controller#1->view#1 I have data displayed in tabular format. in that data table, one column is hyperlink, when i click on that I want to pop up Bootstrap modal dialog. My retirement is Modal dialog should call action method of control#2 and display view#2 in modal dialog.
view#1:
#model xxx
<table id="myTable" class="table table-bordered">
<thead>
....
</thead>
<tbody>
#foreach (xx item in Model.xxx)
{
....
<td>#Html.ActionLink(item.Value.ToString(), "Display", "Controller#2", new { para1 = item.val1, para2 = item.val2}, null)</td>
}
#Html.ActionLink() is working fine it invokes Display() method of Controller#2 and eventually displays view#2. But now the requirement is view#2 should be popup modal dialog box.
FYI: both the views are using common _Layout.cshtml file.
Please help me doing this.
I've created a complete solution for you using #Ajax.ActionLink().To use Ajax.ActionLink it's very important that you add a reference to jquery.unobtrusive-ajax.min.js.In total you should have the following references in this order:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.ajax.unobtrusive/3.2.4/jquery.unobtrusive-ajax.min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var p1 = new Product { ID = 1, Description = "Product 1" };
var p2 = new Product { ID = 2, Description = "Product 2" };
return View(new List<Product> { p1, p2 });
}
public PartialViewResult GetDetails(string description)
{
return PartialView("_GetDetails", description);
}
}
_GetDetails.cshtml partial view:
<div id="myModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Modal Header</h4>
</div>
<div class="modal-body">
<h3>#Model</h3>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Main view:
#model IEnumerable<MVC_Master_Pages.Models.Product>
#{
ViewBag.Title = "Home";
Layout = null;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.ajax.unobtrusive/3.2.4/jquery.unobtrusive-ajax.min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script type="text/javascript">
function Done() {
$('#myModal').modal('show');
}
</script>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Description</th>
<th>Details</th>
</tr>
</thead>
<tbody>
#foreach (var product in Model)
{
<tr>
<td>#product.ID</td>
<td>#product.Description</td>
<td>
#Ajax.ActionLink("Details",
"GetDetails",
new { description = product.Description },
new AjaxOptions
{
UpdateTargetId = "details",
InsertionMode = InsertionMode.Replace,
OnSuccess = "Done()"
})
</td>
</tr>
}
</tbody>
</table>
<div id="details">
</div>
Output:
The second view can't be a complete view with layout. It should be a partial view and called by ajax. Check this answer to learn how to implement it.
Related
I have a search bar in my website, but if the searched word is not valid than I do an if statement to redirect user to home page:
if (jsonResponse is null)
{
return RedirectToAction("Index", "Home");
}
I would like that my site redirect to home page after this check on my controller and than show a pop-up in home page saying "You searched for an invalid word"
You could try this way,
Search Page Controller
public IActionResult SearchPage()
{
var data = TempData["serachResultFromDb"];
if (data != null)
{
ViewData["serachResultFromDb"] = JsonConvert.DeserializeObject<List<PrinterJob>>(TempData["serachResultFromDb"].ToString());
}
return View();
}
Search Page Chtml
#using Newtonsoft.Json.Linq
#using msPartnerSupport.Models
#{
ViewData["Title"] = "Search Page";
}
<h2>#ViewData["Title"]</h2>
#using (Html.BeginForm("SearchKey", "Home", FormMethod.Post))
{
<div>
<table class="table-bordered ">
<tr>
<td><strong>Search</strong></td>
<td>
<input type="text" name="searchkey" placeholder="Enter Search Key" />
</td>
<td>
<input type="submit" value="Search" />
</td>
<td></td>
</tr>
</table>
</div>
<br />
}
<table class="table-bordered ">
<tr>
<th>Printer Name </th>
<th>Total</th>
</tr>
#{
var searkeyResult = (List<PrinterJob>)ViewData["serachResultFromDb"];
if (searkeyResult != null)
{
foreach (var item in searkeyResult)
{
<tr>
<td><strong> #item.PrinterName</strong></td>
<td><strong> #item.TotalPrint</strong></td>
</tr>
}
}
}
</table>
Output should be like :
SearchKey Controller
[HttpPost]
public IActionResult SearchKey(string searchkey)
{
//Searching From Database
List<PrinterJob> serachingFromDb = _context.PrinterJobs.Where(skey => skey.PrinterName == searchkey).ToList();
//If no search Result then redirecting to new page
if (serachingFromDb.Count == 0)
{
return RedirectToAction("About");
}
//On successful search result
TempData["serachResultFromDb"] = JsonConvert.SerializeObject(serachingFromDb);
return RedirectToAction("Index");
}
Note: I am testing on Home controller so directly redirecting to Index action. This controller has no view page.
Index Controller
public IActionResult Index()
{
ViewData["Message"] = "You searched for an invalid word";
return View();
}
Note: It will be redirected when there will be no search result.
Index Chtml
#{
ViewData["Title"] = "Index";
}
<div class="container">
<div class="modal fade" id="samplePopup" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"> </h4>
</div>
<div class="modal-body">
#ViewData["Message"]
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$(function () {
$('#samplePopup').modal('show');
});
});
</script>
Pop Up When No Search Results:
Hope it will help you. Let me know if you have any more concern.
I have a list of table for survey form and each one of them have a button/asp-action to view the answers of at least 3 competitors. but I need to select the competitors of a survey form using a modal. inside that modal, I should populate the body with a checkbox of competitors who answered that survey form. How can I push through to direct the data-toggle modal to the controller?
Here is my View:
#for (int i = 0; i < Model.SurveyNames.Count; i++)
{
<tr>
<td>
#Model.SurveyNames[i].SurveyName
</td>
<td>
#Model.SurveyNames[i].SurveyFor
</td>
<td>
#Model.SurveyNames[i].Description
</td>
<td>
#Model.SurveyNames[i].CreatedBy
</td>
<td>
#Model.SurveyNames[i].Status
</td>
<td>
<!-- Button trigger modal -->
<a asp-action="ViewCompetitors" asp-route-id="#Model.SurveyNames[i].Id" data-toggle="modal" data-target="#ChooseCompetitors">View Competitors</a>
</td>
</tr>
}
And this is my Controller, it should return the values to index modal:
public IActionResult Index(int? id)
{
var model = new CompetitorAnswerViewModel();
var SurveyList = _context.MainSurvey.ToList();
foreach (var zsurvey in SurveyList)
{
model.SurveyNames.Add(new survey { Id = zsurvey.Id, SurveyName = zsurvey.SurveyName, SurveyFor = zsurvey.SurveyFor,Description = zsurvey.Description,CreatedBy = zsurvey.CreatedBy,Status = zsurvey.Status}) ;
}
var competitorList = _context.SurveyCompetitor.ToList().Where(x => x.MainSurveyId == id);
foreach (var competitors in competitorList)
{
model.CompetitorNames.Add(new Competitor { CompetitorName = competitors.CompetitorName});
}
return View(model);
}
I should populate the body with a checkbox of competitors who answered that survey form. But it doesn't forward to the controller whenever I click "View Competitors".
I want the table data id to pass it to the contoller to filter the survey competitors and then return the filtered data to the modal in the same index
You could put the Competitors view in a partial view and render it to Index view using ajax.
1.Create the partial view in Shared folder /Views/Shared/_CompetitorsPartialView.cshtml
#model YourViewModel
<div class="col-md-12">
Your View
</div>
2. Return the filtered data to this partail view
public IActionResult ViewCompetitors(int id)
{
// filter logic
return PartialView("_CompetitorsPartialView",YourViewModel);
}
3.Use ajax in Index view.
Modify <a> to <button>:
<button id = "ViewCompetitors" onclick="viewCompetitor(#item.CustomerId)">View Competitors</button>
Modal and ajax:
<div class="modal fade" id="ChooseCompetitors" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Modal Header</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<div id="showresults"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
#section Scripts{
<script>
function viewCompetitor(id) {
$.ajax({
type: 'Get',
url: '/Home/ViewCompetitors/' + id,//your url
success: function (result) {
$("#ChooseCompetitors").modal();//open modal
$('#showresults').html(result);//populate view to modal
}
})
}
</script>
}
Hi Everyone, I try to used the modal to avoid having multiple pages. but I got a problem, first, I click the view button and it will display to modal the right information; but when I click other view button instead the next data, it display the previous data.
second, after I select the view button and try to select the new shoes button (expectation must be display the new module in modal) it display the data of the previous item I select in view button:
Controller:
public ActionResult Index() //main page
{
var result = _Context.Shoeses.Include(x => x.Supply).ToList();
return View(result);
}
public ActionResult New() //create new product
{
var SupplierCategory = _Context.Suppliers.ToList();
var listOfSupplier = new ShoesViewModel
{
Supply = SupplierCategory
};
return PartialView(listOfSupplier);
}
public ActionResult Details(int id) //view selected data
{
Shoes productItem = new Shoes();
productItem = _Context.Shoeses.Find(id);
return PartialView("_Details", productItem);
}
View: Index
#model IEnumerable<ShoeInformation.Models.Shoes>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br />
<br />
<h2>Tindahan sa Bahay ni Tatang Benjamin</h2>
<br />
<br />
//my modal
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3 class="modal-title">Details</h3>
</div>
<div class="modal-body" id="modalBody">
Testing Only
</div>
</div>
</div>
</div>
//my modal
<p>#Html.ActionLink("New Shoes", "New", "Shoes", new { id="btn_Modal"}, new { #class = "btn btn-primary btn-lg",#data_toggle="modal" ,#data_target="#myModal"})</p>
<table class="table table-striped table-hover ">
<tr>
<th>Product ID
</th>
<th>Product Code
</th>
<th>Product Name
</th>
<th>Item Size
</th>
<th>Supplier
</th>
<th>Available Quantity
</th>
<th>Unit Price (Php)
</th>
<th>Action
</th>
</tr>
#foreach (var shoes in Model)
{
<tr class="success">
<td>
#shoes.Id
</td>
<td>
#shoes.ProductCode
</td>
<td>
#Html.ActionLink(#shoes.ProductName, "Edit", "Shoes", new { id=shoes.Id})
</td>
<td>
#shoes.ItemSize
</td>
<td>
<input type="hidden" value="#shoes.Id" id="hiddenval" />
#Html.HiddenFor(x => shoes.Id)
#Html.DisplayFor(x => shoes.Supply.SupplierName)
</td>
<td>
#shoes.ItemQty
</td>
<td>
#shoes.ItemUnitPrice
</td>
<td>
#Html.ActionLink("View", "Details", "Shoes", new { id=shoes.Id}, new { #class = "view-Modal",#data_toggle="modal" ,#data_target="#myModal"})
</td>
</tr>
}
</table>
#*Open Modal Testing*#
#section scripts
{
<script src="~/Scripts/jquery.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
$('#myModal').hide();
$("#btn_Modal").click(function () {
$('#myModal').modal('show');
});
$(".view-Modal").click(function () {
var productId =
$(this).closest('tr').find('#hiddenval').val();
$.ajax({
type: 'POST',
url: '/Shoes/Details',
data: { id: productId },
success: function (response)
{
$('#modalBody').html(response);
$('#myModal').modal('show');
}
});
})
$(".close").click(function ()
{
console.log("Clear All");
});
});
</script>
}
partial view: _details
#model ShoeInformation.Models.Shoes
<div>
<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">Details</h4>
</div>
<div class="modal-body">
<table class="tablemodel">
<tr>
<tr>
#Html.DisplayFor(x=>x.Id)
</tr>
<tr>
#Html.DisplayFor(x=>x.ProductName)
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
I try to breakpoint to see the problem but everything is working properly, however in the modal it display the same value
can someone please help me regarding to this matter
thanks in advance
I'm going round in circles now so if anyone can identify the issue here I would greatly appreciate it.
I have a partial I'm using to list out items and that works fine.
The post back to the controller works if the items passed back is just set as an ienumerable of the items but I need to pass back a model as it contains more information than just the list.
On doing this the list is empty each time and I cannot see why.
The partial:
#model RequestModel
#section Scripts {
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
<style>
.btn span.glyphicon {
opacity: 0;
}
.btn.active span.glyphicon {
opacity: 1;
}
</style>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>
}
#for (var i = 0; i < Model.Requests.Count(); i++)
{
<div #(Model.Requests.Count == 3 ? "class=col-md-4" : Model.Requests.Count() == 2 ? "class=col-md-6" : "class=col-md-12")>
#Html.HiddenFor(m => Model.Requests[i].RequestID)
<table class="table table-responsive img-rounded">
<thead>
<tr class="alert-cascade">
<th colspan="2">
<div class="btn-group btn-group-sm pull-right" role="group" data-toggle="buttons">
<button class="btn btn-success" data-toggle="tooltip" title="Accept" id="acceptradio">
#Html.RadioButtonFor(m => Model.Requests[i].AcceptChecked, Model.Requests[i].AcceptChecked, new { #id = Model.Requests[i].RequestID, #style = "display:none" })
<span>Accept </span>
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
</button>
<button class="btn btn-warning" data-toggle="tooltip" title="Reject" id="rejectradio">
#Html.RadioButtonFor(m => Model.Requests[i].RejectChecked, Model.Requests[i].RejectChecked, new { #id = Model.Requests[i].RequestID, #style = "display:none" })
<span>Reject </span>
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
</button>
</div>
#Model.Requests[i].EmployeeDescription
</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Request Type</strong></td>
<td class="text-right">#Model.Requests[i].RequestType</td>
</tr>
<tr>
<td><strong>Duration</strong></td>
<td class="text-right">#Model.Requests[i].DurationDescription</td>
</tr>
<tr>
<td><strong>Dates</strong></td>
<td class="text-right">#Model.Requests[i].DatesDescription</td>
</tr>
</tbody>
</table>
</div>
}
The view:
#model RequestPageModel
#{
ViewData["Title"] = "Requests";
ViewData["SubTitle"] = "Welcome to Cascade Mobile";
}
#{Layout = "~/Views/Shared/_MainLayout.cshtml";}
#section Scripts {
<script type="text/javascript">
//Submit count setter
$(document).ready(function () {
var accepted = 0;
var rejected = 0;
$("#acceptradio").click(function () {
console.log("ready 2!");
$("#acceptCount").text("4");
});
});
</script>
}
<div class="container">
<h3>#ViewBag.Warning</h3>
#*Existing requests*#
<h4><strong>Requests</strong> <span class="badge alert-cascade">#Model.Pager.TotalRecords</span></h4><br />
#using (Html.BeginForm("Index", "Request", new { #id = "requestsform" }))
{
<div class="row">
#Html.Partial("_MultiSelectPartial", Model.RequestModel)
</div>
<div>
<textarea class="span6" rows="3" placeholder="Comments.." required></textarea>
</div>
<input type="submit" value="submit"/>
}
<button id="submitbtn" class="btn btn-primary pull-right" type="button">
Accept
<span class="badge" id="acceptCount">0</span>
Reject
<span class="badge" id="rejectCount">0</span>
</button>
#Html.Partial("_Pager", Model.Pager)
</div>
The controller action:
[HttpPost]
public IActionResult Index(RequestModel requests)
{
ViewBag.Warning = "We have: ";
foreach (var request in requests.Requests)
{
ViewBag.Warning += request.RequestID + " : ** : ";
}
var requestModel = GetRequestPageModel(3,1);
//requestModel.Requests[0].AcceptChecked = true;
return View("~/Views/User/Requests.cshtml", requestModel);
}
The model:
using System;
using System.Collections.Generic;
namespace Mobile.Models
{
/// <summary>
/// Request data model for the requests page
/// </summary>
public class RequestModel
{
public List<Request> Requests;
public RequestModel(List<Request> requests)
{
Requests = requests;
}
public RequestModel()
{
Requests = new List<Request>();
}
}
}
Again, if the post method takes just a list of request items its fine, but I will need to pass more information and cannot get it to post the list as part of the model. Can anyone see whats wrong here?
The model in your partial is RequestModel and your loop is generating controls with
name="Requests[0].RequestID"
name="Requests[1].RequestID"
etc, but the model in your POST method should be RequestPageModel so the correct name attributes would need to be
name="RequestModel.Requests[0].RequestID"
name="RequestModel.Requests[1].RequestID"
which will post back to
[HttpPost]
public IActionResult Index(RequestPageModel model)
You need to change the model in the partial to #model RequestPageModel (and adjust the HtmlHelper methods accordingly) and in the main view, use #Html.Partial("_MultiSelectPartial", Model).
In addition, change the name of the parameter to (say) RequestModel model so there is no conflict with the equivalent property name (refer this answer for an explanation).
I would however recommend that you use custom EditorTemplate's for your types rather than a partial, so that you controls are correctly named (refer the 2nd part of this answer for an example)
Side notes:
Your radio buttons do not makes sense, since they have different
names so you can select both (and once selected, you cannot
un-select them)
Your have a <textarea> without a name attribute so it will not
submit a value.
I've looked around, but can't find anything solving my problem with this (common?) issue.
My problem is that the whole site is refreshed instead of just the div tag. It have worked once, but after an update, not anymore...
AddMember.cshtml
#using DBSUSite.ViewModels
#model CommitteeAddMemberModel
<script src='#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")' type="text/javascript"></script>
<h1>
Tilføj medlem</h1>
<p>
Her kan du søge efter brugere og tilføje dem til bestyrelsen eller udvalget.</p>
#using (Ajax.BeginForm("SearchMembers", new AjaxOptions { UpdateTargetId = "searchUsersList", HttpMethod = "POST" }))
{
#Html.HiddenFor(model => model.CommitteeId)
<label for="str">
Søg efter:
</label>
<input id="str" name="str" value="" />
<input type="submit" value="Søg" />
}
<div id="searchUsersList">
#{ Html.RenderPartial("_SearchUserPartial", Model); }
</div>
Action
[Authorize]
[HttpPost]
public ActionResult SearchMembers(int committeeId, string str)
{
//TODO: Put into User model!
var db = new DBEntities();
// Removed lots of code.
var model = new CommitteeAddMemberModel { CommitteeId = committeeId, Users = users.Values.AsEnumerable() };
return PartialView("_SearchUserPartial", model);
}
Partial View
#using DBSUSite.Models
#using DBSUSite.ViewModels
#model CommitteeAddMemberModel
<table>
<thead>
<tr>
<th>
Navn
</th>
<th>Tilføj</th>
</tr>
</thead>
<tbody>
#foreach (User user in Model.Users)
{
<tr>
<td>
#Html.DisplayFor(q => user.FirstName) #Html.DisplayFor(q => user.Surname)
</td>
<td>
#Html.ActionLink("Tilføj", "SaveMember", "Committee", new { committeeId = Model.CommitteeId, userId = user.UserID }, null)
</td>
</tr>
}
</tbody>
</table>
Thanks in advance!
You need to make sure that you included all these libraries:
<script src="#Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>