I'm working a simple modal popup.My goal is to send dialog's information to another view.
My index view below.
<button id="modal-opener">Open</button>
<div id="dialog-modal">
#using (Ajax.BeginForm("Index",new AjaxOptions{UpdateTargetId = "ID",HttpMethod = "Post",OnSuccess = "onSuccess"}))
{
<div>
<fieldset>
<legend>Acount Information</legend>
<div id="editor-label">
#Html.LabelFor(a=>a.FirstName)
</div>
<div id="editor-field">
#Html.TextBoxFor(a=>a.FirstName)
#Html.ValidationMessageFor(a=>a.FirstName)
</div>
<div id="editor-label">
#Html.LabelFor(a=>a.LastName)
</div>
<div id="editor-field">
#Html.TextBoxFor(a=>a.LastName)
#Html.ValidationMessageFor(a=>a.LastName)
</div>
<p>
<input type="submit" value="submit"/>
</p>
</fieldset>
</div>
}
</div>
And my _Layout.cshtml is below:
<script>
$(function() {
$("#dialog-modal").dialog({
autoOpen: false,
width: 300,
height: 250,
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>
And my controller is below ,so I want to send FirstName and LastName to details view
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Person person)
{
return RedirectToAction("Details",person);
}
public ActionResult Details(Person person)
{
return View(person);
}
If you want to do full redirect rather than a partial postback, you will need to change this line:
#using (Ajax.BeginForm("Index",new AjaxOptions{UpdateTargetId = "ID",HttpMethod = "Post",OnSuccess = "onSuccess"}))
into
#using(Html.BeginForm("Index"))
If you just want to do the partial postback to the details view, then change the action on the from Index to details
#using (Ajax.BeginForm("Details",new AjaxOptions{UpdateTargetId = "ID",HttpMethod = "Post",OnSuccess = "onSuccess"}))
HTH
Related
I've got a master page/template page/whatever you wanna call it with the site navigation and header and I want to swap out the body of the page with different partial views.
In the code behind file for the master page I have:
public void OnGet(string screenSelect = "Welcome")
{
ScreenSelect = screenSelect;
}
In the cshtml file I have:
#switch (Model.ScreenSelect)
{
case "Page1":
<div>
#await Html.PartialAsync("_Page1", Model.Page1Model)
</div>
break;
case "Page2":
<div>
#await Html.PartialAsync("_Page2", Model.Page2Model)
</div>
break;
case "Page3":
<div>
#await Html.PartialAsync("_Page3", Model.Page3Model)
</div>
break;
case "Page4":
<div>
#await Html.PartialAsync("_Page4", Model.Page4Model)
</div>
break;
case "Page5":
<div>
#await Html.PartialAsync("_Page5", Model.Page5Model)
</div>
break;
}
And for javascript I have:
function navigateTo(pageName)
{
console.log('in navigateTo');
$.ajax({
type: "GET",
url: "MasterPage?screenSelect=" + pageName,
content: "application/json; charset=utf-8",
success: function (response)
{
console.log('in success');
},
error: function (xhr, textStatus, errorThrown)
{
console.log('in error');
}
});
}
I can confirm that the navigateTo function is firing and the OnGet is being hit with the correct parameter. I've set breakpoints on the #awaits and can confirm that the correct #await Html.PartialAsync is also being hit. But the page just doesn't update.
Since you are using JQuery Ajax to update the partial content, after calling the action method successful, it will return the result to the Ajax success function. So, if you want to update the partial view content in the master page, you should do that in the Ajax's Success function.
Please refer the following code:
MasterPage.cshtml.cs:
public class MasterPageModel : PageModel
{
[BindProperty]
public string ScreenSelect { get; set; }
[BindProperty]
public string Page1Model { get; set; }
[BindProperty]
public string Page2Model { get; set; }
[BindProperty]
public string Page3Model { get; set; }
public void OnGet(string screenSelect = "Welcome")
{
ScreenSelect = screenSelect;
}
//create a handler to load partial view.
public IActionResult OnGetLoadPartial(string screenSelect)
{
var returnmodel = "";
//initial data source.
Page1Model = "this is Page1 Page";
Page2Model = "This is Page2 Page";
Page3Model = "This is Page3 Page";
switch (screenSelect)
{
case "Page1":
returnmodel = Page1Model;
return Partial("_Page1", returnmodel);
case "Page2":
returnmodel = Page2Model;
return Partial("_Page1", returnmodel);
case "Page3":
returnmodel = Page3Model;
return Partial("_Page1", returnmodel);
default:
returnmodel = "<div><h2> Master Page </h2></div>";
return Content(returnmodel);
};
}
}
MasterPage.cshtml
#page
#model RazorSample.Pages.MasterPageModel
<nav class="navbar navbar-default">
<div class="container-fluid">
<ul class="nav navbar-nav">
<li class="active">Master Page</li>
<li>Page 1</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>
</div>
</nav>
<div id="container">
#switch (Model.ScreenSelect)
{
case "Page1":
<div>
#await Html.PartialAsync("_Page1", Model.Page1Model)
</div>
break;
case "Page2":
<div>
#await Html.PartialAsync("_Page2", Model.Page2Model)
</div>
break;
case "Page3":
<div>
#await Html.PartialAsync("_Page3", Model.Page3Model)
</div>
break;
default:
<div>
<h2>Master Page</h2>
</div>
break;
}
</div>
#section Scripts{
<script>
function navigateTo(pageName) {
console.log('in navigateTo');
event.preventDefault(); //prevent the default event.
$.ajax({
type: "Get",
url: "MasterPage?handler=LoadPartial&screenSelect=" + pageName,
success: function (response) {
console.log('in success');
$("#container").html("");// clear the container
$("#container").html(response); //load the partial view.
},
error: function (xhr, textStatus, errorThrown) {
console.log('in error');
}
});
}
</script>
}
Code in the partial view:
#model string
#*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*#
#{
}
<h2>#Model</h2>
Then, the result like this:
Thanks to the excellent answer by Rena in the previous question I am also asking how do I achieve the same effect of the sweet alert message box on the create controller action I tried with the code they gave in this.
Using JavaScript code behind asp.net core c#
But because the action create submits the form first it doesn't seem to like the trigger the alert.
swal({
title: "MIS",
text: "Case Created your Case Number is ",
icon: "warning",
buttons: true,
dangerMode: true,
})
just post the form with ajax after that jsut show the message you want
<form action="/your action url" method="post" id="formCreate">
...Yıur item inputs
<button type="submit"></button>
</form>
$("#formCreate").submit(function (event) {
event.preventDefault(); //prevent default action
var post_url = $(this).attr("action"); //get form action url
var request_method = $(this).attr("method"); //get form GET/POST method
var form_data = $(this).serialize(); //Encode form elements for submission
$.ajax({
url: post_url,
type: request_method,
data: form_data
}).done(function (response) { //
Swal.fire({
position: 'center',
icon: "warning",
text: "Case Created your Case Number is "+response.Id,
title: "MIS",
showConfirmButton: false,
timer: 1500,
}).then(() => {
window.location.reload(true);
})
});
});
in cotroller side you should return something like this
[HttpPost]
public IActionResult Create(Item item){
//create item
return Json(new {Id=item.id});
}
It seems you want to trigger the sweet alert when you click the submit button.
Here is a working demo:
Model:
public class Test
{
public int Id { get; set; }
public string Name { get; set; }
}
Index.cshtml:
#model IEnumerable<Test>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="#item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="#item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Create.cshtml:
#model Test
<h1>Create</h1>
<h4>Test</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="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<input type="button" onclick="Create()" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
<script>
function Create() {
swal({
title: "MIS",
text: "Case Created your Case Number is " + $("#Name").val(),
icon: "warning",
buttons: true,
dangerMode: true,
}).then((willCreate) => {
if (willCreate) {
var data = $('form').serialize();
$.ajax({
url: "/tests/create",
type: "POST",
data: data,
dataType: "html",
success: function () {
swal("Done!", "It was succesfully created!", "success")
.then((success) => {
window.location.href="/tests/index"
});
},
error: function (xhr, ajaxOptions, thrownError) {
swal("Error creating!", "Please try again", "error");
}
});
}
});
}
</script>
}
Controller:
public class TestsController : Controller
{
private readonly Mvc3_1Context _context;
public TestsController(Mvc3_1Context context)
{
_context = context;
}
// GET: Tests
public async Task<IActionResult> Index()
{
return View(await _context.Test.ToListAsync());
}
// GET: Tests/Create
public IActionResult Create()
{
return View();
}
// POST: Tests/Create
[HttpPost]
public async Task<IActionResult> Create(Test test)
{
if (ModelState.IsValid)
{
_context.Add(test);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(test);
}
}
Result:
How can I pass a dropdown selected value from my view to a controller then to different controller? I have a home page and an about page. On the home page the user selects an item from the dropdown, then they click on a button that navigates them to another page that has the same dropdown. My goal is to have the dropdown prepopulated on the about page based on what they selected on the home page.
My problem is that I am doing the navigation in my home page controller, so I am not getting the value of the selected value because it is not a post just a get. My variable "string countryDDL" in my home controller is null.
I am currently using TempData to pass the value, however, I am open to other options (viewbag, session state, etc). Thank you for your time.
Home page view:
<form method="post" asp-controller="Home" asp-action="Index" role="form">
<div class="form-group">
<label>Country Dropdown:</label>
<select name="countryDDL" asp-items="#(new SelectList(ViewBag.message, "ID", "CountryName"))"></select>
</div>
</form>
<a asp-action="AboutPage" asp-controller="Home">About Page</a>
Home Controller:
public void CountryDDL()
{
List<CountryModel> countryName = new List<CountryModel>();
countryName = (from b in _context.CountryModel select b).ToList();
countryName.Insert(0, new CountryModel { ID = 0, CountryName = "" });
ViewBag.message = countryName;
}
[HttpGet("[action]")]
public IActionResult AboutPage()
{
string countryDDL = HttpContext.Request.Form["countryDDL"];
int intCountry = Convert.ToInt32(countryDDL);
CountryModel data = new CountryModel()
{
ID = intCountry,
CountryName = "",
};
TempData["myData"] = data;
return RedirectToAction("Index", "AboutPage");
}
My Book Page Controller:
[HttpGet("[action]")]
[Route("/Index")]
public async Task<IActionResult> Index()
{
//get values from Home controller
CountryModel data = TempData["myData"] as CountryModel;
return View();
}
Firstly,your code makes a mistake that you could not pass TempData["myData"] redirect to another controller action with the following error message.That is because TempData uses Session, which itself uses IDistributedCache. IDistributedCache doesn't have the capability to accept objects or to serialize objects:
InvalidOperationException: The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer' cannot serialize an object of type
Here is the whole working demo:
Home/Index.cshtml:
<form method="post" asp-controller="Home" asp-action="Index" role="form">
<div class="form-group">
<label>Country Dropdown:</label>
<select id="sel" name="countryDDL" asp-items="#(new SelectList(ViewBag.message, "ID", "CountryName"))"></select>
</div>
</form>
<a asp-action="AboutPage" asp-controller="Home" >About Page</a>
#section Scripts{
<script>
$("a").click(function () {
var selectItem = $('#sel').find(":selected").val();
var href = $(this).attr('href');
if (href) {
href +="?countryDDL="+selectItem;
$(this).attr('href', href);
console.log(href);
}
});
</script>
}
HomeController:
public class HomeController : Controller
{
private readonly MvcProj3_1Context _context;
public HomeController(MvcProj3_1Context context)
{
_context = context;
}
public IActionResult Index()
{
CountryDDL();
return View();
}
public void CountryDDL()
{
List<CountryModel> countryName = new List<CountryModel>();
countryName = (from b in _context.CountryModel select b).ToList();
countryName.Insert(0, new CountryModel { ID = 0, CountryName = "" });
ViewBag.message = countryName;
}
[HttpGet]
public IActionResult AboutPage(string countryDDL)
{
int intCountry = Convert.ToInt32(countryDDL);
List<CountryModel> data = new List<CountryModel>()
{
new CountryModel()
{
ID = intCountry,
CountryName = "asd",
}
};
TempData["myData"] = JsonSerializer.Serialize(data);
return RedirectToAction("Index", "AboutPage");
}
}
AboutPage/Index.cshtml:
<form>
<div class="form-group">
<label>Country Dropdown:</label>
<select id="sel" name="countryDDL" asp-items="#(new SelectList(ViewBag.message, "ID", "CountryName"))"></select>
</div>
</form>
AboutPageController:
public class AboutPageController : Controller
{
[HttpGet]
public async Task<IActionResult> Index()
{
//get values from Home controller
ViewBag.message = JsonSerializer.Deserialize<List<CountryModel>>(TempData["myData"] as string);
return View();
}
}
Result:
Update
You could get the data like below:
[HttpGet]
public IActionResult AboutPage(string countryDDL)
{
int intCountry = Convert.ToInt32(countryDDL);
//change this line...
var data = _context.CountryModel.Where(c => c.ID == intCountry).ToList();
TempData["myData"] = JsonSerializer.Serialize(data);
return RedirectToAction("Index", "AboutPage");
}
1-you can use form to navigate and submit it with get to about page:
<form method="get" asp-controller="Home" asp-action="AboutPage" role="form">
<div class="form-group">
<label>Country Dropdown:</label>
<select name="countryDDL" asp-items="#(new SelectList(ViewBag.message, "ID", "CountryName"))"></select>
</div>
<button type="submit">About Page</button>
</form>
2-you can use jquery like below:
a: change a tag like this:
About Page
b: and select like below:(set "onChange" event)
<select onchange="$('#a_about').prop('href','/Home/AboutPage?countryDDL='+$(this).val())" name="countryDDL" asp-items="#(new SelectList(ViewBag.message, "ID", "CountryName"))" ></select>
i have simple form where one dropdown and one submit button. i have two index function one for get and one for form post. when i select a product from dropdown and click on submit button then my index action getting invoke but there i notice my products property getting null. see my code please and tell me where i made the mistake.
view code
#model AuthTest.Models.SampleViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>DateValTest</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Products, htmlAttributes: new { #class = "control-label col-md-2", style = "padding-top:0px;" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedProductId, new SelectList(Model.Products, "ID", "Name"), "-- Select Product--")
#Html.ValidationMessageFor(model => model.SelectedProductId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
model code
public class Product
{
public int ID { set; get; }
public string Name { set; get; }
}
public class SampleViewModel
{
[Display(Name = "Products")]
public List<Product> Products { set; get; }
[Required(ErrorMessage = "Select any one")]
public int SelectedProductId { set; get; }
}
controller code
public class TestValController : Controller
{
// GET: TestVal
public ActionResult Index()
{
var SampleVM = new SampleViewModel();
SampleVM.Products = new List<Product>
{
new Product{ ID=1, Name="IPhone" },
new Product{ ID=2, Name="MacBook Pro" },
new Product{ ID=3, Name="iPod" }
};
return View(SampleVM);
}
[HttpPost]
public ActionResult Index(SampleViewModel vm)
{
var SampleVM = new SampleViewModel();
SampleVM.Products = new List<Product>
{
new Product{ ID=1, Name="IPhone" },
new Product{ ID=2, Name="MacBook Pro" },
new Product{ ID=3, Name="iPod" }
};
if (ModelState.IsValid)
return View(vm);
else
return View(SampleVM);
}
}
when i debug second action then i saw vm products property getting null
please tell me where i made the mistake?
thanks
You are not making any mistake, You are not getting the list of products back because you are not including them in the HTML input form.
If you want to include the list of products you can add the following inside the input form
#for (int i = 0; i < Model.Products.Count(); i++)
{
<div>
#Html.HiddenFor(model => Model.Products[i].Name)
#Html.HiddenFor(model => Model.Products[i].ID)
</div>
}
#Mou,
Please modify your razor view and try this.
In Razor View nowhere you have specified the Http verb(Get,Post).
#using (Html.BeginForm("Index", "TestVal", FormMethod.Post)
I have this controller and view:
public ActionResult DynamicView()
{
return View();
}
_
#model ChatProj.Models.GroupNumber
#{
ViewBag.Title = "DynamicView";
}
<h2>DynamicView</h2>
<fieldset>
<legend>Create a room</legend>
<div class="editor-label">
#Html.LabelFor(model => model.GroupId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.GroupId)
#Html.ValidationMessageFor(model => model.GroupId)
</div>
<input type="submit" value="DynamicView" />
</fieldset>
This is what it looks like on the page.
That's fine and dandy, but I would like to pass that number to a controller, which then passes it to a view. I would like to pass it to this view:
#using PagedList.Mvc;
#using ChatProj.App_Code;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Grupprum 1";
}
<h2>Grupprum 1</h2>
<style>
ul {list-style-type:circle;}
</style>
<div class="container">
<div class="nano chat">
<div class="content">
<ul id="discussion">
</ul>
</div>
</div>
<input type="text" id="message" />
<input type="button" id="sendmessage" value="Send" disabled="disabled" />
<input type="hidden" id="displayname" />
</div>
#section scripts {
<!--Script references. -->
<!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
<!--Reference the SignalR library. -->
<script src="~/Scripts/jquery.signalR-1.1.3.js"></script>
<script src="~/Scripts/jquery.nanoscroller.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script>
<!--SignalR script to update the chat page and send messages.-->
<script>
$(function () {
// Reference the auto-generated proxy for the hub.
var chat = $.connection.chatHub;
$(".nano").nanoScroller();
// Create a function that the hub can call back to display messages.
chat.client.addNewMessageToPage = function (name, message) {
// Add the message to the page.
$('#discussion').append('<li><strong>' + htmlEncode(name)
+ '</strong>: ' + htmlEncode(message) + '</li>');
};
$(document).ready(function () {
$("#sendmessage").removeAttr("disabled");
$('#message').keypress(function (e) {
if (e.keyCode == 13)
$('#sendmessage').click();
});
});
// Get the user name and store it to prepend to messages.
// Set initial focus to message input box.
$('#message').focus();
$.connection.hub.qs = { "room": "Grupprum 1" };
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
// This optional function html-encodes messages for display in the page.
function htmlEncode(value) {
var encodedValue = $('<div />').text(value).html();
return encodedValue;
}
</script>
}
Specifically I would want it at $.connection.hub.qs = { "room": "Grupprum 1" }; to replace the 1.
So I've created these controllers which are faulty and incomplete:
[HttpPost]
public ActionResult DynamicView(int? roomNumber)
{
return View(GroupRoom(roomNumber));
}
public ActionResult GroupRoom(int roomNumber)
{
return View();
}
Does anyone know how I should change my controllers and views so that I'm able to insert a number in my DynamicGroup view, and get a view back based on the inserted number and the lastly mentioned view?
You could pass the number from the model to the new action just how #Matt Bodily did. But if you want to use a different model on your new view, you can use the below code instead:
public ActionResult GroupRoom(int roomNumber)
{
ViewBag.RoomNumber = roomNumber;
return View();
}
This way, you can use a different model for this page, if you want to. To display this ViewBag on the page, use this code anywhere you want:
#ViewBag.RoomNumber
I hope that helps you out.
How you have it set up the Model.GroupID will be set on the first view so change your controller like this
[HttpPost]
public ActionResult DynamicView(GroupNumber model)
{
//model.GroupId here will be what was selected on the first view
return RedirectToAction("GroupRoom", "Controller", new { GroupId = model.GroupId });
}
public ActionResult GroupRoom(int GroupId)
{
var model = //build your model based on the selected GroupId
return View(model);
}