im using PagedList with ajax. everything work fine. but the only problem is that the page links are not getting update as i click on them.
this is partial view containing the list
#model IEnumerable<UniProject.Models.Short_Code>
<table class="table table-condensed table-bordered table-hover table-striped">
<tr>
<th>
Shortcode
</th>
<th>
Service
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ServiceCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.Service)
</td>
</tr>
}
</table>
this is my view
#model PagedList.IPagedList<UniProject.Models.Short_Code>
#using PagedList.Mvc
<link type="text/css" rel="stylesheet" href="~/Content/PagedList.css" />
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<div class="col-lg-8">
<div id="tableDiv">
#Html.Partial("_shortcode_table" , Model)
</div>
<div id="myPager">
#Html.PagedListPager(
Model,
page => Url.Action(
"Index",
new
{
page = page
}
)
)
</div>
</div>
<script>
$(function () {
$('#myPager').on('click', 'a', function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
success: function (result) {
$('#tableDiv').html(result);
}
});
return false;
});
});
</script>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
please help with this issue that where am i doing wrong. any help would be welcome . thanks
Related
I'm learning web dev with a Razor app. I have a Page, PeopleIndex where a table shows a people list and after each row there is, 1st an <a ...> to Edit person data, and 2nd a <input ...> from where I would like to call the jQuery UI confirm dialog (which I already have the code in the .cshtml), from where if I click "Yes" button that person registry should be deleted, this is, call the Delete() method that is in the .cshtml.cs file. I clear out that this procedure is not a submit action, I say this because all what I found on the Internet related to my problem was about "form method = POST and type=submit" and that all this should be done in another Page, that I want to just do it in my person listing Page. But, if I'm wrong, I will listen to ideas.
I attach both files of my PeopleIndex Razor Page:
************* PeopleIndex.cshtml *****************
#page
#model WebAppPersonas.Pages.PersonasIndexModel
#{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head title="Lista de personas">
<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
// Confirmation Dialog
$('#confirmDialog').dialog({
autoOpen: false,
width: 500,
height: auto,
modal: true,
resizable: false,
buttons: {
"Yes": function () {
$(".ui-dialog-buttonpane button:contains('Si')").button("disable");
$(".ui-dialog-buttonpane button:contains('No')").button("disable");
call Delete() C# method from .cs file // neither know what goes here
$(this).dialog("close");
},
"No": function () {
$(this).dialog("close");
}
}
});
$('#deleteReg').click(function (e) {
e.preventDefault();
$('#confirmDialog').dialog('open');
});
});
</script>
</head>
<body>
<a asp-page="./InsertUpdate" class="btn btn-primary"> Add person </a>
<h2> People LIst </h2>
<table class="table">
<thead>
<tr>
<th> #Html.DisplayNameFor(Model => Model.people[0].Id) </th>
<th> #Html.DisplayNameFor(Model => Model.people[0].Name) </th>
<th> #Html.DisplayNameFor(Model => Model.people[0].Age) </th>
<th> #Html.DisplayNameFor(Model => Model.people[0].Email) </th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.people)
{
<tr>
<td> #Html.DisplayFor(modelItem => item.Id) </td>
<td> #Html.DisplayFor(modelItem => item.Name) </td>
<td> #Html.DisplayFor(modelItem => item.Age) </td>
<td> #Html.DisplayFor(modelItem => item.Email) </td>
<td> <a asp-page="./InsertUpdate" asp-route-id="#item.Id"> Update </a> | <input type="button" value="Delete" onclick="I don't know what goes here"/> </td>
</tr>
}
</tbody>
</table>
<div id="confirmDialog" title="Confirm delete">
<p> You are about to delete a registry ¿Are you sure?</p>
</div>
</body>
</html>
********** PeopleIndex.cshtml.cs *****************
public void OnGet()
{
people = dataAccess.GetPeople();
}
public ActionResult Delete(int? id)
{
dataAccess.DeletePerson(id.Value);
return Redirect("./PeopleIndex");
}
I had to cut off the header of the .cshtml.cs file because the site didn't allow me to format that code and then because of that the site didn't allow me to post the question. I hope now it allows me to post the question. This is very complicated. I think it should be easier the duty of formatting code in different languages, but well, ... this is what there is ...
Thank you in advance.
EDIT***
Hi, Michael
I edited the files with the code you gave me. But I put a breakpoint in:
$('.deleteButton').click(function (e) {
e.preventDefault();
const id = $(e.target).data("id");
$('#confirmDialog').data("id", id);
$('#confirmDialog').dialog('open');
});
And it doesn't enter that code, which comes from the button here:
<tbody>
#foreach (var item in Model.people)
{
<tr>
<td> #Html.DisplayFor(modelItem => item.Id) </td>
<td> #Html.DisplayFor(modelItem => item.Name) </td>
<td> #Html.DisplayFor(modelItem => item.Age) </td>
<td> #Html.DisplayFor(modelItem => item.Email) </td>
<td> <a asp-page="./InsertUpdate" asp-route-id="#item.Id"> Update </a> | <button class="deleteButton" data-id="#item.Id"> Delete </button> </td>
</tr>
}
</tbody>
So it is not working by now, but at least we now know where is the problem.
I attach again the affected files with current updates, I don't put the .cs because it's the only that is Ok.
1st, the .cshtml.cs (Now we know that when clicking deleteButton it doesn't enter the JS function. I tried changing class for name but the same.)
#page
#model WebAppPersonas.Pages.PeopleIndexModel
#section Head
{
<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />
#*<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>*#
<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
// Confirmation Dialog
$('#confirmDialog').dialog({
autoOpen: false,
width: 500,
height: auto,
modal: true,
resizable: false,
buttons: {
"Yes": function () {
$(".ui-dialog-buttonpane button:contains('Yes')").button("disable");
$(".ui-dialog-buttonpane button:contains('No')").button("disable");
DeletePerson($(this).data("id"));
$(this).dialog("close");
},
"No": function () {
$(this).dialog("close");
}
}
});
$('.deleteButton').click(function (e) {
e.preventDefault();
const id = $(e.target).data("id");
$('#confirmDialog').data("id", id);
$('#confirmDialog').dialog('open');
});
});
</script>
<script>
const token = document.getElementsByName('__RequestVerificationToken')[0].nodeValue;
function DeletePerson(id) {
const formData = new FormData();
formData.append("id", id);
fetch(window.location.href, {
method: 'DELETE',
headers: { 'XSRF-TOKEN': token },
body: formData
})
.then(result => { window.location.reload(); })
.catch(error => alert("Error sending DELETE request."))
}
</script>
}
<div id="confirmDialog" title="Confirm delete">
<p> You are about to delete a registry. Are you sure? </p>
</div>
<a asp-page="./InsertUpdate" class="btn btn-primary"> Add person </a>
<h2> List of People </h2>
<table class="table">
<thead>
<tr>
<th> #Html.DisplayNameFor(Model => Model.people[0].Id) </th>
<th> #Html.DisplayNameFor(Model => Model.people[0].Name) </th>
<th> #Html.DisplayNameFor(Model => Model.people[0].Age) </th>
<th> #Html.DisplayNameFor(Model => Model.people[0].Email) </th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.people)
{
<tr>
<td> #Html.DisplayFor(modelItem => item.Id) </td>
<td> #Html.DisplayFor(modelItem => item.Name) </td>
<td> #Html.DisplayFor(modelItem => item.Age) </td>
<td> #Html.DisplayFor(modelItem => item.Email) </td>
<td> <a asp-page="./InsertUpdate" asp-route-id="#item.Id"> Update </a> | <button class="deleteButton" data-id="#item.Id"> Delete </button> </td>
</tr>
}
</tbody>
</table>
#Html.AntiForgeryToken()
2nd, the _Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - WebAppPersonas</title>
#*<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />*#
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
#*<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>*#
#RenderSection("Head", false)
</head>
<body>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">WebAppPersonas</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
#RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - WebAppPersonas - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
#*<script src="~/lib/jquery/dist/jquery.min.js"></script>*#
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
#await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Blockquote
Razor pages are a server side technology. You can't call C# functions in javascript. Instead
you can make a request. This request will be assigned to a method in your Razor page using
the routing middleware.
To illustrate the problems that this implies we have a simple PageModel:
public class Person
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
}
public class PersonsModel : PageModel
{
private static List<Person> _persons = new List<Person>
{
new Person{Id = 1, Firstname = "FN1", Lastname = "LN1"},
new Person{Id = 2, Firstname = "FN2", Lastname = "LN2"},
new Person{Id = 3, Firstname = "FN3", Lastname = "LN3"},
new Person{Id = 4, Firstname = "FN4", Lastname = "LN4"}
};
public List<Person> Persons => _persons;
public void OnGet()
{
}
// Called from fetch (JavaScript)
public IActionResult OnDelete(int id)
{
var person = _persons.Find(p => p.Id == id);
if (person == null) { return NotFound(); // HTTP 404 triggers .catch() in fetch }
_persons.Remove(person);
return new NoContentResult(); // HTTP 204
}
}
As you can see, OnDelete returns no redirect, because the server response is not interpreted by
the browser. It is up to you to respond to this return value.
In our Razor view we have a list of persons and a delete button for each of them.
#page
#model RazorDemo.Pages.PersonsModel
#{
}
<ul>
#foreach (var p in Model.Persons)
{
<li>#p.Id - #p.Firstname #p.Lastname <button onclick="deletePerson(#p.Id)">Delete</button></li>
}
</ul>
#*Generate a hidden field with the RequestVerificationToken.*#
#Html.AntiForgeryToken()
<script>
const token = document.getElementsByName('__RequestVerificationToken')[0].value;
// Send a DELETE request as multipart/form-data (an ordinary HTML form)
function deletePerson(id) {
// Crates a HTML form with one parameter (id)
const formData = new FormData();
formData.append("id", id);
fetch(window.location.href, {
method: 'DELETE',
headers: { 'XSRF-TOKEN': token },
body: formData
})
.catch(error => alert("Error sending DELETE request."));
}
</script>
A server generated HTML form contains a hidden input element with an anti forgery token
(request verification token, more information at www.learnrazorpages.com).
We have to create this element manually by using #Html.AntiForgeryToken().
The JavaScript gets the value of this token. After that we are creating the payload of an ordinary
HTML form, because we want to use standard model binding and validation at server side.
Now we need to do some configuration, because we are sending the anti forgery token in the
request header.
public void ConfigureServices(IServiceCollection services)
{
// Other services
services.AddAntiforgery(o => o.HeaderName = "xsrf-token");
}
Now you can delete a person, but your UI dosen't refresh. Only after reloading the deleted
person disappears. Now you come to a point where you need a JavaScript MVVM framework instead of JQuery.
A small JavaScript framework is Knockout. A JavaScript MVVM framework
generates the html content based on json values from your server. You can send your list of persons
to the client as JSON and store it in an array. When you delete a person, you
can delete that person in that array and the templates engine will update your view automatically.
Razor pages supports JSON results and different handlers, so you don't need a separate controller for that.
// GET Persons?handler=AllPersons
public IActionResult OnGetAllPersons()
{
return new JsonResult(Persons);
}
Using jQuery UI
To include the jQuery UI references you can define a section in your main layout (_Layout.cshtml).
The default template uses bootstrap and jQuery. To get jQuery UI to work, you have to reference
to the bundled version of jQuery which comes with jQuery UI. We also define a section in the head element, which can be used by
the razor page.
_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Other references (bootstrap css, ...) -->
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
#RenderSection("Head", false)
</head>
<body>
<!-- Your layout with RenderBody() -->
<!-- NO REFERENCE TO JQUERY! -->
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
#await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Important: Delete (or comment out) the reference to lib/jquery/dist/jquery.min.js at the end of
the body.
Now we can add a dialog to the Persons page:
#page
#model RazorDemo.Pages.PersonsModel
#section Head
{
<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
// Confirmation Dialog
$('#confirmDialog').dialog({
autoOpen: false,
width: 500,
height: "auto",
modal: true,
resizable: false,
buttons: {
"Yes": function () {
$(".ui-dialog-buttonpane button:contains('Si')").button("disable");
$(".ui-dialog-buttonpane button:contains('No')").button("disable");
// Call deletePerson with data-id of the dialog div.
deletePerson($(this).data("id"));
$(this).dialog("close");
},
"No": function () {
$(this).dialog("close");
}
}
});
$('.deleteButton').click(function (e) {
e.preventDefault();
// We have a generic event handler for all buttons.
// So we have to look at the event source and read the data-id attribute.
const id = $(e.target).data("id");
// Now we create a data attribute for <div id="confirmDialog">
$('#confirmDialog').data("id", id);
$('#confirmDialog').dialog('open');
});
});
function deletePerson(id) {
const token = document.getElementsByName('__RequestVerificationToken')[0].value;
const formData = new FormData();
formData.append("id", id);
fetch(window.location.href, {
method: 'DELETE',
headers: { 'XSRF-TOKEN': token },
body: formData
})
.then(result => { window.location.reload(); }) // Reloading the page. This is not AJAX, but it will do the job.
.catch(error => alert("Error sending DELETE request."));
}
</script>
}
<div id="confirmDialog" title="Confirm delete">
<p> You are about to delete a registry. Are you sure?</p>
</div>
<ul>
#foreach (var p in Model.Persons)
{
<li>#p.Id - #p.Firstname #p.Lastname <button class="deleteButton" data-id="#p.Id">Delete</button></li>
}
</ul>
#*Generate a hidden field with the RequestVerificationToken.*#
#Html.AntiForgeryToken()
Instead of onClick you can use a generic event handler (defined with .click() in jQuery).
Therefore the buttons have a data-id attribute. Inside the event handler we retrieve this id
with $(e.target).data("id") and assign a data-id attribute dynamically to the dialog div.
This is a C# MVC code wherein after searching the records from the database I am trying to display the records in each row (which is working). Each row consists of Update School button along with other details including the ChdId. After clicking this button my View should return schId (after selecting the school from the drop-down) and ChdId corresponding to that row. But after submitting the Update School of any row I am getting the ChdId of the first row always in my Controller (not of the row that I am updating).
Question:
Has anyone ever run into this issue before? Or does anyone know why this is happening, or what I'm doing wrong?
Please check out my code below and thanks for checking my question!
Controller:
[HttpPost]
public ActionResult UpdateSchool(int SchoolNames, int ChdId, Child model)
{
}
View:
#model Ass4Final.Models.Child
#{
ViewBag.Title = "Search";
var listOfSchoolNamesAndIds = ViewBag.SchoolNameAndId;
Layout = "~/Views/Shared/_Layout.cshtml";
}
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="~/scripts/jquery-1.10.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script src="~/JS/Search.js"></script>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<h2>Search</h2>
<br /> <br />
<div>
<table class="table" id="myTable" style="width:100%">
<tr>
<th>
#Html.Label("Child ID")
</th>
<th>
#Html.Label("Child Name")
</th>
<th>
#Html.Label("DOB")
</th>
<th>
#Html.Label("School Name")
</th>
<th></th>
</tr>
#foreach (var item in Model.DataChdNamCurrSchDOBProp)
{
<tr>
<td>
#item.ChdId
</td>
<td>
#item.ChdName
</td>
<td>
#item.DOB
</td>
<td>
#item.School
</td>
<td>
<div data-role="main" class="ui-content">
Update School
<div data-role="popup" id="myPopup" class="ui-content" style="min-width:250px;">
#using (Html.BeginForm("UpdateSchool", "Home", FormMethod.Post))
{
<h3>Enter New School</h3>
#Html.DropDownList("SchoolNames", new SelectList(ViewBag.SchoolNameAndId, "schId", "schName"), "Select New School", new { #id = "MySearch" })
<input type="hidden" value="#item.ChdId" name="ChdId" />
<input type="submit" data-inline="true" value="UpdateSchool">
}
</div>
</div>
</td>
</tr>
}
</table>
</div>
</body>
</html>
i am working on an application. i am using two partial view in a single view. one of them is a create form for shortcode and the other one lists the shortcodes having a pagination.
this is my create form which is partial view
#model UniProject.Models.Short_Code
<div id="formDiv">
#using (Ajax.BeginForm("Create", "Service", new AjaxOptions { HttpMethod = "post" , UpdateTargetId = "formDiv" }))
{
<table>
<tr>
<td>#Html.LabelFor(model => model.ServiceCode)</td>
<td>#Html.TextBoxFor(model => model.ServiceCode , new { #class = "form-control input-sm"})</td>
</tr>
<tr>
<td></td>
<td>#Html.ValidationMessageFor(model => model.ServiceCode , "", new { #class = "text-danger"})</td>
</tr>
<tr>
<td>#Html.LabelFor(model => model.Service)</td>
<td>
#Html.DropDownList("Service" ,new List<SelectListItem> {
new SelectListItem { Text = "Select" , Value = ""},
new SelectListItem { Text = "Package" , Value = "Package"},
new SelectListItem { Text = "Per-SMS" , Value = "Per-SMS"},
new SelectListItem { Text = "Barcode" , Value = "Barcode"}
}, new { #class = "form-control input-sm" })
</td>
</tr>
<tr>
<td></td>
<td>#Html.ValidationMessageFor(model => model.Service , "" , new { #class = "text-danger"})</td>
</tr>
<tr>
<td><input type="submit" value="Submit" class="btn btn-default btn-sm"/></td>
<td>#ViewBag.Record</td>
</tr>
</table>
}
this is my list which is also a partial view
#model IEnumerable<UniProject.Models.Short_Code>
<table class="table table-condensed table-bordered table-hover table-striped">
<tr>
<th>
Shortcode
</th>
<th>
Service
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ServiceCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.Service)
</td>
</tr>
}
this is index view
#model PagedList.IPagedList<UniProject.Models.Short_Code>
#using PagedList.Mvc
<link type="text/css" rel="stylesheet" href="~/Content/PagedList.css" />
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h3>Service Management</h3>
<script type="text/javascript" src="~/Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript" src="~/Scripts/jquery.unobtrusive-ajax.js"> </script>
<div class="col-lg-4">
#Html.Partial("_shortcode_form")
</div>
<div class="col-lg-8">
#Html.Partial("_shortcode_table")
</div>
<div id="pager">
#Html.PagedListPager(
Model ,
page => Url.Action(
"Index" ,
new {
page = page
}
)
)
</div>
<script>
$(function () {
$("#pager").on('click', 'a', function () {
$.ajax({
url: this.href,
type: 'GET',
cashe: false,
success: function (respons) {
$('#table').html(respond);
}
})
return false;
})
});
</script>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
this is controller
public ActionResult Index(int? page)
{
var codes = db.Codes.AsQueryable();
codes = codes.OrderBy(c => c.Id);
if (Request.IsAjaxRequest())
{
return PartialView("_shortcode_table", codes.ToPagedList(pageNumber: page ?? 1, pageSize: 2));
}
return View(codes.ToPagedList(pageNumber: page ?? 1, pageSize: 2));
}
the problem is that when i pass this
codes.ToPagedList(pageNumber: page ?? 1, pageSize: 2)
to the view, this error generates
The model item passed into the dictionary is of type
'PagedList.PagedList`1[UniProject.Models.Short_Code]', but this
dictionary requires a model item of type
'UniProject.Models.Short_Code'.
please help how can is solve this issue. any help or assist would be welcome.
View
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<fieldset>
<br />
<br />
<br />
<div align="center">
#{
#(Html.Telerik().Grid<SmartTrack.Web.DAL.SysUserList>()
.DataBinding(dataBinding => dataBinding.Ajax().Select("Index", "User"))
.Name("UserList")
.DataKeys(keys => keys
.Add(c => c.UserName)
.RouteKey("UserName"))
.Columns(columns =>
{
columns.Bound(o => o.UserName).Width(100);
columns.Bound(o => o.FirstName).Width(200);
columns.Bound(o => o.LastName).Width(250);
columns.Bound(o => o.Active).ClientTemplate("<input type='checkbox' disabled='disabled' name='Active' <#=Active? checked='checked' : '' #> />").Width(70).HtmlAttributes(new { style = "text-align:center" }); ;
})
.Pageable(pagerAction => pagerAction.PageSize(20))
.Sortable()
.Selectable()
.Scrollable()
.Groupable()
.Filterable()
.HtmlAttributes(new { style = "width:50%;" })
)
}
</div>
<br/>
<div align="center">
<table>
<tr>
<td>
<button id="btnAdd" type="submit" style="height:40px;width:70px" ">Add</button>
</td>
<td>
<button style="height:40px;width:70px" ">Edit</button>
</td>
<td>
<button style="height:40px;width:70px" ">Delete</button>
</td>
</tr>
</table>
</div>
</fieldset>
<script type="text/javascript">
$(function () {
$('#btnAdd').click(function () {
$.ajax({
type: "POST",
url: '#Url.Action("Create","User")',
success: function (result) {
$('#cuscreate').html(result)
}
});
});
});
</script>
This view contain a script from which the UserController Create method is call when the add button is clicked
Control
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SmartTrack.Web.Attributes;
using SmartTrack.Web.Models;
using SmartTrack.Web.DAL;
using Telerik.Web.Mvc;
namespace SmartTrack.Web.Controllers
{
public class UserController : Controller
{
SMARTTrackerEntities db = new SMARTTrackerEntities();
//
// GET: /User/
[GridAction]
public ActionResult Index()
{
//ViewData["UserGroup"] = DisplayContentEngine.getUserGroupList();
return View(new GridModel(UserListEngine.getAllSystemUser()));
}
[HttpPost]
public ActionResult Create()
{
ViewData["Location"] = DisplayContentEngine.getLocationList();
ViewData["Branch"] = DisplayContentEngine.getBranchList();
//var v = ViewData.Model = UserListEngine.getAllSystemUser();
var user = new SysUserList();
return View(user);
}
[HttpPost]
public ActionResult Create(SysUserList user)
{
try
{
// TODO: Add insert logic here
if (ModelState.IsValid)
{
//Save Registration
db.SysUserLists.AddObject(user);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
catch
{
return View();
}
}
public ActionResult Edit(string username)
{
SysUserList sysuserlist = db.SysUserLists.Single(s => s.UserName == username);
return View(sysuserlist);
}
}
}
This controller that is called
Create View
#model SmartTrack.Web.DAL.SysUserList
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
<div id="cuscreate">
<fieldset>
<table>
<tr>
<td>
<label>First Name</label>
</td>
<td>
#Html.TextBoxFor(model => model.FirstName)
</td>
<td>
<label>Last Name</label>
</td>
<td>
#Html.TextBoxFor(model => model.LastName)
</td>
</tr>
<tr>
<td>
<label>User Name</label>
</td>
<td>
#Html.TextBoxFor(model => model.UserName)
</td>
<td>
<label>Password</label>
</td>
<td>
#Html.PasswordFor(model => model.userPwd)
</td>
</tr>
<tr></tr>
<tr>
<td>
<label>Location</label>
</td>
<td>
#(Html.Telerik().DropDownList()
.Name("ddLocation")
.BindTo((IEnumerable<DropDownItem>)ViewData["Location"])
.CascadeTo("ddlBranch")
)
</td>
<td>
<label>Branch</label>
</td>
<td>
#(Html.Telerik().DropDownList()
.Name("ddlBranch")
.BindTo((IEnumerable<DropDownItem>)ViewData["Branch"])
)
</td>
</tr>
</table>
</fieldset>
</div>
}
When the add button is click nothing happen can someone tell my whats my issue?
Thanks in advance
Regards
Kurt
I cannot see the form tags in your html that could be the reason where it does not know where to post
The view with action link Create New and the telerik grid does not have form tags in it
Make sure you cancel the default action of the submit button by returning false from your click handler in order to give your AJAX call chance to execute:
<script type="text/javascript">
$(function () {
$('#btnAdd').click(function () {
$.ajax({
type: "POST",
url: '#Url.Action("Create", "User")',
success: function (result) {
$('#cuscreate').html(result)
}
});
});
return false; // <!-- That's the important bit
});
</script>
You don't have a data element in your ajax request, so you are POSTing nothing.
If you want to get the data from the form you can just use .serialize():
$.ajax({
type: "POST",
data: $('form').serialize(),
url: '#Url.Action("Create","User")',
success: function (result) {
$('#cuscreate').html(result)
}
});
Keep in mind, this will only work if its the only on the page, otherwise you should use another selector, but you get the idea.
UPDATE from HatSoft's answer (upvote it!):
generally inside your tags you should have tags, to do that in MVC:
<fieldset>
#using(Html.BeginForm())
{
<p>your form</p>
}
</fieldset>
In correcting my problem I had to modify my index view to include div id = cuscreate which resulted in the CreateUser view displaying
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<div id="cuscreate" align="center">
<fieldset>
<br />
<br />
<br />
#using (Html.BeginForm())
{
//#{
#(Html.Telerik().Grid<SmartTrack.Web.DAL.SysUserList>()
.DataBinding(dataBinding => dataBinding.Ajax().Select("Index", "User"))
.Name("UserList")
.DataKeys(keys => keys
.Add(c => c.UserName)
.RouteKey("UserName"))
.Columns(columns =>
{
columns.Bound(o => o.UserName).Width(100);
columns.Bound(o => o.FirstName).Width(200);
columns.Bound(o => o.LastName).Width(250);
columns.Bound(o => o.Active).ClientTemplate("<input type='checkbox' disabled='disabled' name='Active' <#=Active? checked='checked' : '' #> />").Width(70).HtmlAttributes(new { style = "text-align:center" }); ;
})
.Pageable(pagerAction => pagerAction.PageSize(20))
.Sortable()
.Selectable()
.Scrollable()
.Groupable()
.Filterable()
.HtmlAttributes(new { style = "width:50%;" })
)}
</fieldset>
<br/>
<div align="center">
<table>
<tr>
<td>
<button id="btnAdd" type="submit" style="height:40px;width:70px" ">Add</button>
</td>
<td>
<button style="height:40px;width:70px" ">Edit</button>
</td>
<td>
<button style="height:40px;width:70px" ">Delete</button>
</td>
</tr>
</table>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#btnAdd').click(function () {
$.ajax({
type: "POST",
data: $('form').serialize(),
url: '#Url.Action("CreateUser", "User")',
success: function (result) {
$('#cuscreate').html(result)
}
});
});
return false; // <!-- That's the important bit
});
</script>
Thanks for your assistance was really appreciated
Regards
Kurt
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>