Partial razor page won't render in ASP .NET Core - asp.net-core

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:

Related

how to get data from database using ajax asp.net core

According to the following codes i have created the Get Handler in Index Model
public IActionResult OnGetCustomer(CustomerSearchModel searchModel)
{
CustomerCombine combine = new CustomerCombine
{
MyViewModels = _customerApplication.GetAll(searchModel)
};
return Partial("./Customer", combine);
}
and this is my Razor View:
#model CustomerCombine
<form asp-page="./Index" asp-page-handler="Customer"
method="get"
data-ajax="true"
data-callback=""
data-action="Refresh"
>
<div class="form-group">
<input asp-for="#Model.MySearchModel.FullName" class="form-control " placeholder="search..." />
</div>
<button class="customer-submit btn btn-success" type="submit">جستجو</button>
</form>
<table>
#foreach (var item in #Model.MyViewModels)
{
<tr>
<td>#item.Id</td>
<td>#item.FullName</td>
<td>#item.Mobile</td>
<td>#item.Email</td>
<td>#item.Address</td>
<td>#item.Image</td>
</tr>
}
</table>
My modal is displayed successfully,and i can see my database's data, but when i fill search field and click on search button , nothing happens
can any one help me plz?:)
and this is my jquey codes: i dont anything about Jquery and these codes were ready and now i dont knoe how i should use from it
$(document).on("submit",
'form[data-ajax="true"]',
function (e) {
e.preventDefault();
var form = $(this);
const method = form.attr("method").toLocaleLowerCase();
const url = form.attr("action");
var action = form.attr("data-action");
if (method === "get") {
const data = form.serializeArray();
$.get(url,
data,
function (data) {
CallBackHandler(data, action, form);
});
} else {
var formData = new FormData(this);
$.ajax({
url: url,
type: "post",
data: formData,
enctype: "multipart/form-data",
dataType: "json",
processData: false,
contentType: false,
success: function (data) {
CallBackHandler(data, action, form);
},
error: function (data) {
alert("خطایی رخ داده است. لطفا با مدیر سیستم تماس بگیرید.");
}
});
}
return false;
});
});
function CallBackHandler(data, action, form) {
switch (action) {
case "Message":
alert(data.Message);
break;
case "Refresh":
if (data.isSucceced) {
window.location.reload();
} else {
alert(data.message);
}
break;
case "RefereshList":
{
hideModal();
const refereshUrl = form.attr("data-refereshurl");
const refereshDiv = form.attr("data-refereshdiv");
get(refereshUrl, refereshDiv);
}
break;
case "setValue":
{
const element = form.data("element");
$(`#${element}`).html(data);
}
break;
default:
}
}
function get(url, refereshDiv) {
const searchModel = window.location.search;
$.get(url,
searchModel,
function (result) {
$("#" + refereshDiv).html(result);
});
}
1.The third parameter of $.get() is the success function.
2.There is no isSucceced property in your postback data. The postback data is the partial view html code. You need use $("xxx").html(data); to update the partial view code.
3.Model Binding binds the property by name, <input asp-for="#Model.MySearchModel.FullName"/> does not match the CustomerSearchModel searchModel.
public IActionResult OnGetCustomer(CustomerSearchModel MySearchModel)
Whole working demo and more details I have commented on the code pls check carefully:
Model
public class CustomerCombine
{
public List<MyViewModel> MyViewModels { get; set; }
public CustomerSearchModel MySearchModel { get; set; }
}
public class CustomerSearchModel
{
public string FullName { get; set; }
}
public class MyViewModel
{
public int Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string Mobile { get; set; }
public string Address { get; set; }
public string Image { get; set; }
}
View(Index.cshtml)
#page
#model IndexModel
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
#Html.Partial("Customer",Model.CustomerCombine)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
#section Scripts
{
<script>
$(document).on("submit",'form[data-ajax="true"]',function (e) {
e.preventDefault();
var form = $(this);
const method = form.attr("method").toLocaleLowerCase();
const url = form.attr("action");
var action = form.attr("data-action");
if (method === "get") {
const data = form.serializeArray();
$.get(url,data,function (data) {
console.log(data); //you can check the response data in Console panel
CallBackHandler(data, action, form);
});
} else {
var formData = new FormData(this);
$.ajax({
url: url,
type: "post",
data: formData,
enctype: "multipart/form-data",
dataType: "json",
processData: false,
contentType: false,
success: function (data) {
CallBackHandler(data, action, form);
},
error: function (data) {
alert("خطایی رخ داده است. لطفا با مدیر سیستم تماس بگیرید.");
}
});
}
return false;
});
//}); //remove this.......
function CallBackHandler(data, action, form) {
switch (action) {
case "Message":
alert(data.Message);
break;
case "Refresh":
$(".modal-body").html(data); //modify here....
break;
case "RefereshList":
{
hideModal();
const refereshUrl = form.attr("data-refereshurl");
const refereshDiv = form.attr("data-refereshdiv");
get(refereshUrl, refereshDiv);
}
break;
case "setValue":
{
const element = form.data("element");
$(`#${element}`).html(data);
}
break;
default:
}
}
function get(url, refereshDiv) {
const searchModel = window.location.search;
$.get(url,
searchModel,
function (result) {
$("#" + refereshDiv).html(result);
});
}
</script>
}
Partial View does not change anything
#model CustomerCombine
<form asp-page="./Index" asp-page-handler="Customer"
method="get"
data-ajax="true"
data-callback=""
data-action="Refresh"
>
<div class="form-group">
<input asp-for="#Model.MySearchModel.FullName" class="form-control " placeholder="search..." />
</div>
<button class="customer-submit btn btn-success" type="submit">جستجو</button>
</form>
<table>
#foreach (var item in #Model.MyViewModels)
{
<tr>
<td>#item.Id</td>
<td>#item.FullName</td>
<td>#item.Mobile</td>
<td>#item.Email</td>
<td>#item.Address</td>
<td>#item.Image</td>
</tr>
}
</table>
PageModel
public IActionResult OnGetCustomer(CustomerSearchModel MySearchModel)//change here....
{
CustomerCombine combine = new CustomerCombine
{
MyViewModels = _customerApplication.GetAll(searchModel) //be sure here contains value...
};
return Partial("./Customer", combine);
}
Result:

Pass value from one controller to another in ASP.NET Core MVC

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>

How to dynamically add an item to a list within a list in a ViewModel using Razor and .NET Core 2.2?

I've been following this tutorial (i did it in asp.net core 2.2):
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ on how to edit a variable lenght list in asp.net. In this tutorial, we're just handling a list of gifts. I'm trying to apply this method to a more complex model.
I have an object called Workout.cs who contains a List of Section.cs. The Section.cs object contains a List of Movement.cs
public class Workout
{
public string Name { get; set; }
public IEnumerable<Section> Sections { get; set; } = new List<Section>();
}
public class Section
{
public int NbRounds { get; set; }
public string Name { get; set; }
public IEnumerable<Movement> Movements { get; set; } = new List<Movement>();
}
public class Movement
{
public string Name { get; set; }
}
WorkoutController
public IActionResult BlankSection()
{
return PartialView("_SectionEditor", new Section());
}
public IActionResult BlankMovement()
{
return PartialView("_MovementEditor", new Movement());
}
Index.cshtml
#model Workout
<h2>Workout</h2>
<form asp-action="Index" method="post" asp-controller="Workout">
<div id="editorRows">
#foreach (var item in Model.Sections)
{
<partial name="_SectionEditor" model="item" />
}
</div>
<a id="addItem" asp-action="BlankSection" asp-controller="Workout">Add Section...</a> <br />
<input type="submit" value="Finished" />
</form>
#section scripts {
<script>
$("#addItem").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) { $("#editorRows").append(html); }
});
return false;
});
</script>
}
_SectionEditor.cshtml
#model Section
#{
Layout = "~/Views/Shared/_LayoutEditor.cshtml";
}
<div class="editorRow">
#using (Html.BeginCollectionItem("sections"))
{
<span>Name: </span> #Html.EditorFor(m => m.Name);
<span>Rounds: </span>#Html.EditorFor(m => m.NbRounds, new { size = 4 });
}
delete
<div id="editorMovement">
#foreach (var item in Model.Movements)
{
<partial name="_MovementEditor" model="item" />
}
</div>
<a id="addMovement" asp-action="BlankMovement" asp-controller="Workout">Add Movement...</a> <br />
</div>
#section Scripts {
<script>
$(document).ready(function () {
$("a.deleteRow").on("click", function () {
$(this).parents("div.editorRow:first").remove();
return false;
});
});
$("#addMovement").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) { $("#editorMovement").append(html); }
});
return false;
});
</script>
}
MovementEditor.cshtml
#model Movement
#{
Layout = "~/Views/Shared/_LayoutEditor.cshtml";
}
<div class="editorMovement">
#using (Html.BeginCollectionItem("movements"))
{
<span>Name: </span> #Html.TextBoxFor(m => m.Name);
}
delete
</div>
#section Scripts {
<script>
$(document).ready(function () {
$("a.deleteMovement").on("click", function () {
$(this).parents("div.editorMovement:first").remove();
return false;
});
});
</script>
}
With the tutorial, it's working fine when I'm adding sections to my workout, but when I'm trying the same to add movements to my sections, it's not working anymore. I would like to be able to add as many sections as I want to my workout, and for each section, as many movements as I want, and send it to the controller. How could I do that ?
thanks a lot
First: MovementEditor appears to be a partial in the controller, but not in the view file (despite the '_').
Second: since _SectionEditor is a partial view, you can't define #section scripts in it, because it's already defined in the main view Index. To solve this issue, you need to put all the scripts in the main view Index.
P.S: don't forget to change jquery selectors for items in the partial views, i.e: $("#addMovement") will not point to the anchor tag because it was not there when the DOM tree was created. Instead write $("body #addMovement") and it will get the anchor tag.

knockout.js binding issue when trying to refresh data

I am using knockout.js data binding. At the page load the binding works fine and data is shown on the page correctly. Then I try to push data back to the database and the push is successful. The database receives the data OK.
The problem comes when I try to reload the data upon push success. At this time the binding already happen once (at the page load). If I don't bind it again the data on the page does not refresh. If I do the binding again knockout.js issues an error "cannot bind multiple times". If I do a cleanup before rebinding I receive an error "nodeType undefined".
Can anyone tell me what I have missed here? I am using ASP.NET MVC 4.0 with knockout.js 3.0.0.
Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplJSON.Controllers
{
public class KnockoutController : Controller
{
//
// GET: /Knockout/
public ActionResult Index()
{
return View();
}
[HttpGet]
public JsonResult GetProductList()
{
var model = new List<Product>();
try
{
using (var db = new KOEntities())
{
var product = from p in db.Products orderby p.Name select p;
model = product.ToList();
}
}
catch (Exception ex)
{ throw ex; }
return Json(model, JsonRequestBehavior.AllowGet);
}
// your controller action should return a JsonResult. There's no such thing as a controller action that returns void. You have specified dataType: 'json' so return JSON. That's it. As far as what parameter this controller action should take, well, from the JSON you are sending ({"Name":"AA"}) it should be a class that has a Name property of type string.
// modify your action signature to look like this: [HttpPost] public ActionResult SaveProduct (Product product) { ... return Json(new { success = true }); }. Or get rid of this dataType: 'json' attribute from your AJAX request if you don't want to return JSON. In this case you could return simply status code 201 (Created with empty response body): return new HttpStatusCodeResult(201);.
[HttpPost]
public ActionResult SaveProduct(Product product)
{
using (var db = new KOEntities())
{
db.Products.Add(new Product { Name = product.Name, DateCreated = DateTime.Now });
db.SaveChanges();
}
return Json(new { success = true });
}
}
}
View:
#{
ViewBag.Title = "Knockout";
}
<h2>Knockout</h2>
<h3>Load JSON Data</h3>
<div id="loadJson-custom" class="left message-info">
<h4>Products</h4>
<div id="accordion" data-bind='template: { name: "product-template", foreach: product }'>
</div>
</div>
<h3>Post JSON Data</h3>
<div id="postJjson-custom" class="left message-info">
<h4>Add Product</h4>
<input id="productName" /><br />
<button id="addProduct">Add</button>
</div>
#section Scripts {
#Scripts.Render("~/bundles/knockout")
#Scripts.Render("~/bundles/livequery")
<script src="/Scripts/jquery.livequery.min.js"></script>
<style>
#accordion { width: 400px; }
</style>
<script id="product-template" type="text/html">
<h3><a data-bind="attr: {href:'#', title: Name, class: 'product'}"><span data-bind="text: Name"></span></a></h3>
<div>
<p>Here's some into about <span data-bind="text: Name" style="font-weight: bold;"></span> </p>
</div>
</script>
<script>
var isBound;
function loadJsonData() {
$.ajax({
url: "/knockout/GetProductList",
type: "GET",
contentType: "application/json",
dataType: "json",
data: {},
async: true,
success: function (data) {
var loadJsonViewModel = {
product: ko.observableArray(),
init: function () {
loadAccordion();
}
};
var a = $('loadJson-custom');
loadJsonViewModel.product = ko.mapping.fromJS(data);
if (isBound) { }
else
{
ko.applyBindings(loadJsonViewModel, $('loadJson-custom')[0]);
isBound = true;
}
loadJsonViewModel.init();
}
});
}
// push data back to the database
function pushJsonData(productName) {
var jData = '{"Name": "' + productName + '"}';
$.ajax({
url: "/knockout/SaveProduct",
type: "POST",
contentType: "application/json",
dataType: "json",
data: jData,
async: true,
success: function (data, textStatus, jqXHR) {
console.log(textStatus + " in pushJsonData: " + data + " " + jqXHR);
//ko.cleanNode($('loadJson-custom')[0]);
loadJsonData();
},
error: function (jqXHR, textStatus, errorThrown) {
alert(textStatus + " in pushJsonData: " + errorThrown + " " + jqXHR);
}
});
}
function loadAccordion() {
$("#accordion > div").livequery(function () {
if (typeof $("#accordion").data("ui-accordion") == "undefined")
{
$("#accordion").accordion({ event: "mouseover" });
}
else
{
$("#accordion").accordion("destroy").accordion({ event: "mouseover" });
}
});
}
$(function () {
isBound = false;
loadJsonData();
$("#addProduct").click(function () {
pushJsonData($("#productName").val());
});
});
</script>
}
Here is a complete solution for your question.
I have just implemented and checked.
Please have a look.
I have created a class for getting some records ie: Records.cs.
public static class Records
{
public static IList<Student> Stud(int size)
{
IList<Student> stud = new List<Student>();
for (int i = 0; i < size; i++)
{
Student stu = new Student()
{
Name = "Name " + i,
Age = 20 + i
};
stud.Add(stu);
}
return stud;
}
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
Here is a controller for the respective view.
//
// GET: /HelpStack/
private static IList<Student> stud = Records.Stud(10);
public ActionResult HelpStactIndex()
{
return View();
}
[HttpGet]
public JsonResult GetRecord()
{
return Json(stud, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public void PostData(Student model)
{
//do the required code here as All data is in "model"
}
Here is a view as HTML, I have taken two section one for list and other to Add records
<div id="loadJson-custom">
<h4>Student</h4>
<table width="100%">
<tr>
<td style="width: 50%">
<div id="accordion" data-bind='template: { name: "product-template", foreach: Student }'>
</div>
</td>
<td valign="top">
<div id="NewStudent">
<input type="text" data-bind="value: Name" /><br />
<input type="number" data-bind="value: Age" /><br />
<input type="submit" data-bind="click: Save" value="AddNew" />
</div>
</td>
</tr>
</table>
Here is your scripts for Knockoutjs.
<script id="product-template" type="text/html">
<h3><a data-bind="attr: { href: '#', title: Name, class: 'product' }"><span data-bind=" text: Name"></span></a>
<br />
Age: <span data-bind="text: Age"></span>
</h3>
<div>
<p>Here's some into about <span data-bind="text: Name" style="font-weight: bold;"></span></p>
</div>
</script>
<script type="text/javascript">
//Model for insert new record
var Model = {
Name: ko.observable(''),
Age: ko.observable(''),
};
var Student = ko.observableArray([]); // List of Students
function loadData() { //Get records
$.getJSON("/HelpStack/GetRecord", function (data) {
$.each(data, function (index, item) {
Student.push(item);
});
}, null);
}
function Save() { //Save records
$.post("/HelpStack/PostData", Model, function () { //Oncomplete i have just pushed the new record.
// Here you can also recall the LoadData() to reload all the records
//Student.push(Model);
Student.unshift(Model); // unshift , add new item at top
});
}
$(function () {
loadData();
ko.applyBindings(Model, $('#NewStudent')[0]);
});
</script>
You are declaring your model inside loadJsonData function success callback, & creating new object on every success callback, move the model outside that function, create an object & use it inside loadJsonData function, it will fix the issue.

asp.net mvc modal popup

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