Asp.net MVC action link to post with routed parameters - asp.net

Hi I have the following data table in which u can click move button , the issue is that it always use get link instead of post how to apply post with parameters
<div class="box-body">
#using (#Html.BeginForm("QueueDetails", "Home", FormMethod.Post))
{
<table id="example1">
<tbody>
#foreach (var errorMesseage in Model.ErrorMesseages)
{
<tr>
<td>#errorMesseage</td>
<td>
#Html.ActionLink(
"Move",
"QueueDetails",
new { errorMesseage = #errorMesseage, model = Model },
new { #class = "saveButton", onclick = "return false;" })
</td>
</tr>
}
</tbody>
</table>
}
</div>
$(document).ready(function () {
createChart();
$('.saveButton').click(function () {
if(confirm('Are you sure you wish to Move this messeage back?'))
{
$(this).closest('form')[0].submit();
}
});
});
it always redirect to the get with url like Home/QueueDetails?errorMesseage=Error%20messeage%201&model=xxxx

Related

How to repeat bound controls based on clicking Add new in Asp.net mvc and Knockoutjs

I want to repeat a dropdownlist that is already bound using a Viewbag property and another textbox when a user click on Add Course.
I have used asp.net mvc and knockout.js based on a tutorial i saw, but the tutorial does not exactly handle using bound controls, please how can i achieve this using asp.net mvc and knockout.js.
Below is my code.
Thanks
<table id="jobsplits">
<thead>
<tr>
<th>#Html.DisplayNameFor(m => m.selectedCourse.FirstOrDefault().FK_CourseId)</th>
<th>#Html.DisplayNameFor(m => m.selectedCourse.FirstOrDefault().CourseUnit)</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: courses">
#for (int i = 0; i < Model.selectedCourse.Count; i++)
{
<tr>
<td>
#Html.DropDownListFor(model => model.selectedCourse[i].FK_CourseId, new SelectList(ViewBag.Course, "Value", "Text", Model.FK_CourseId), "Select Course", new { #class = "form-control", data_bind = "value: courses" })
</td>
<td>
#Html.TextBoxFor(model => model.selectedCourse[i].CourseUnit, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly", data_bind = "value: courseUnit" } })
</td>
<td>
<button type="button" data-bind="click: $root.removeCourse" class="btn delete">Delete</button>
</td>
</tr>
}
</tbody>
</table>
<div class="col-md-4">
<button data-bind="click: addCourse" type="button" class="btn">Add Course</button>
</div>
This is the script section
#section Scripts{
#Scripts.Render("~/bundles/knockout")
<script>
function CourseAdd(course, courseUnit) {
var self = this;
self.course = course;
self.courseUnit = courseUnit;
}
function CourseRegViewModel() {
var self = this;
self.addCourse = function () {
self.courses.push(new CourseAdd(self.course, self.courseUnit));
}
self.courses = ko.observableArray([
new CourseAdd(self.course, self.courseUnit)
]);
self.removeCourse = function (course) {
self.courses.remove(course)
}
}
ko.applyBindings(new CourseRegViewModel());
</script>
}
Edit:
i have been able to get this sample working from: http://learn.knockoutjs.com/#/?tutorial=collections
but it is only an hard-coded observableArray.
I want to be able to populate the select from the database. But it is not getting populated.
This is my sample code below:
<table id="jobsplits">
<thead>
<tr>
<th>Persenger Name</th>
<th>Meal</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: seats">
<tr>
<td>
<input data-bind="value: name" />
</td>
<td>
<select data-bind="options:coursesArray, optionsText:'Text', optionsValue:'Value', optionsCaption: 'Choose...'"></select>
</td>
<td>
<button type="button" data-bind="click: $root.removeSeat" class="btn delete">Delete</button>
</td>
</tr>
</tbody>
</table>
<div class="col-md-4">
<button data-bind="click: addSeat">Add Seat</button>
</div>
This is the adjusted script section:
<script>
function SeatReservation(name, initialMeal) {
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);
}
function ReservationsViewModel() {
var self = this;
//This is what i want to put in dropdown instead
self.thecourses.subscribe(function () {
getCourses();
});
// Editable data
self.seats = ko.observableArray([
new SeatReservation("Steve", self.thecourses),
new SeatReservation("Bert", self.thecourses)
]);
self.addSeat = function () {
self.seats.push(new SeatReservation("", self.availableMeals[0]));
}
self.removeSeat = function (seat) { self.seats.remove(seat) }
var getCourses = function () {
var collegeCode = $("#Colleges").val();
var departmentCode = $("#Departments").val();
var url = '#Url.Action("GetCourses", "Student")';
$.getJSON(url, { deptId: departmentCode, collegeId: collegeCode }, function (data) {
self.coursesArray(data)
});
}
}
ko.applyBindings(new ReservationsViewModel());
</script>

get table column value of selected row in table asp.net in jQuery

I am working on asp.net mvc project.
I want to get the cell value from the selected row (row in which "Manage "button is clicked).
in this case value of userID.
<table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-example">
<thead>
<tr>
<th width="45%">User ID</th>
<th width="45%">User Name</th>
<th width="5%">View</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TypeList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.UserId)
</td>
<td>
#Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
<input id="Manage2" class="btn btn-primary" type="button" value="Manage" />
</td>
</tr>
}
</tbody>
I am calling jQuery click function and Ajax call and want to send the UserId value in data from selected row to the controller.
below is the jQuery ajax call,
<script type="text/javascript">
$(document).ready(function () {
$('#Manage2').click(function () {
//alert(1);
var url = '#Url.Action("ManageUserRole", "UserRoleCompany")';
$.ajax({
url: url,
data: { Id: '1' },
cache: false,
type: "POST",
success: function (data) {
$("#Data").html(data);
},
error: function (reponse) {
alert("error : " + reponse);
}
});
});
});
</script>
Below is the view screen shot,
You can actually store the UserId value with html 5 data attribute on the button itself.
Your current code has Id attribute value hard coded inside a loop, which will create more than one element with same Id value. That is invalid HTML!
Remove the Id and use a more generic selector to wire up the click event. Here I added another CSS class "manage" to the button.
<input data-userid="#item.UserId" class="btn btn-primary manage"
type="button" value="Manage" />
and now
$(document).ready(function () {
$('.manage').click(function () {
var id = $(this).data("userid");
alert(id);
// use id for your ajax call
});
});
You do not necessarily need to add the extra css class only to use that as the selector later. Since you are adding a data attribute, you may simply use that as well for your jQuery selector.
$(function () {
$('[data-userid]').click(function () {
var id = $(this).data("userid");
alert(id);
// use id
});
});
You have invalid html because of the duplicate id attributes in your button.
Remove the id="Manage2" and replace with a class name and data- attribute for the value
<input data-id="#item.UserId" class="btn btn-primary Manage2" type="button" value="Manage" />
Then in the script, get the value using
$('.Manage2').click(function () { // class selector
var id = $(this).data('id);
var url = '#Url.Action("ManageUserRole", "UserRoleCompany")';
$.ajax({
url: url,
data: { Id: id },
....
Alternatively you could use relative selectors
$('.Manage2').click(function () {
var id = $(this).closest('tr').children('td:first').text();
....

Automatic Logout on Ajax call in ASP.net

I have a dropdownlist with different soccer Clubs from my database. When I select one, an ajax call will be made to show all the Games that Club will play in.
The problem is whenever I'm logged on as an AspNetUser I automatically get logged off the second I submit the dropdownlist.
When I'm not logged in everything works as it should.
I'm really confused why exactly this happens.
Controller
[Authorize]
public class WedstrijdController : Controller
{
[AllowAnonymous]
public ActionResult Index()
{
ploegService = new PloegService();
ViewBag.PloegId = new SelectList(ploegService.All(),
"Id", "Naam");
return View();
}
[AllowAnonymous]
public ActionResult IndexAjax(int? ploegId)
{
if (ploegId == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
wedstrijdService = new WedstrijdService();
var wedstrijden = wedstrijdService.WedstrijdenByPloeg(Convert.ToInt16(ploegId));
return PartialView("_SearchWedstrijdenPartial", wedstrijden);
}
}
Index.cshtml
#{
ViewBag.Title = "Lijst";
}
<h2>Wedstrijden</h2>
<div class="panel panel-default">
<div class="panel-heading">Kies een wedstrijd</div>
<div class="panel-body">
#using (Ajax.BeginForm("IndexAjax", "Wedstrijd",
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
LoadingElementId = "ajax-loader",
UpdateTargetId = "searchresults",
}))
{
<div class="form-horizontal">
<div class="form-group">
#Html.Label("Ploeg", htmlAttributes: new { #class = "control-label col-md-1" })
<div class="col-md-10">
#Html.DropDownList("PloegId", null, "---Kies ploeg---", htmlAttributes: new { #class = "form-control" })
<img id="ajax-loader"
src="#Url.Content("~/content/Images/ajax-loader.gif")"
style="display: none" />
</div>
</div>
</div>
}
<div id="searchresults"></div>
</div>
</div>
#section scripts
{#Scripts.Render("~/bundles/jqueryUnobtrusive")
<script>
$("#PloegId").on("change",
function() {
$("form").trigger("submit");
});
</script>
}
_SearchWedstrijdenPartial.cshtml
#model IEnumerable<VoetbalMVC.Models.Wedstrijd>
<table class="table">
<tr>
<th>
Thuisploeg
</th>
<th>
Bezoekersploeg
</th>
<th>
#Html.DisplayNameFor(model => model.Stadion)
</th>
<th>
#Html.DisplayNameFor(model => model.Datum)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Ploeg1.Naam)
</td>
<td>
#Html.DisplayFor(modelItem => item.Ploeg.Naam)
</td>
<td>
#Html.DisplayFor(modelItem => item.Stadion.Naam)
</td>
<td>
#Html.DisplayFor(modelItem => item.Datum)
</td>
<td>
#Html.ActionLink("Order tickets", "Detail", new { wedstrijdId = item.Id })
</td>
</tr>
}
</table>
Indeed, by using the $("form") jQuery selector you are targeting all form elements on the page. You can verify the forms being submitted from the client to the server with tools like Fiddler, Postman, or the developer tools of your browser (by hitting F12 or CTRL+Shift+I on Windows/Linux, or Command+Option+I on Mac).
As far as the logout form is concerned, if you haven't customized the folder/file structure of your MVC project, it should be located in Views/Shared/_LoginPartial.cshtml:
#using Microsoft.AspNet.Identity
#if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", #class = "navbar-right" }))
{
// ...
}
}
..so it is generating a form with an ID of #logoutForm, but since you are submitting all forms at once, you are subsequently logging out the user each time.
This means you need to modify the call to only submit the form you want. Assuming the ID of your form being AjaxForm, you would do:
$("#AjaxForm").trigger("submit");
This piece of code was causing the error
$("form").trigger("submit");
As you can see this includes all forms. I suspect this means the logout button is included in some sort of form which triggers this action when logged in. Simply add an Id to your AjaxForm and only trigger the submit of that AjaxForm.

Validation for search input when model is a list

In the view, the model is:
#model List<ParamsTaskLib.ParamRecord>
I want to create a form with an input field which will be the DeviceID to search for:
public class ParamRecord
{
[Required]
[RegularExpression(#"^[0-9a-fA-F]{8}$", ErrorMessage = "Invalid Device ID (hex)")]
public Int64 DeviceID { get; set; }
other fields in here...
I tried editing the view in the following way:
<form method="get" >
#Html.EditorFor(model => model.First().DeviceID)
#Html.ValidationMessageFor(model => model.First().DeviceID)
But it doesn't work obviously, it doesn't seem like it SHOULD work:)
I'm confused with how to work with a list as a model, combined with a search box...
The error I get is "Value can't be NULL" on this line:
#Html.EditorFor(model => model.First().DeviceID)
Extra clarification: the purpose of this page is to display a table which contains many lines (ParamRecord) of a specific DeviceID from the database.
The purpose of the form + input field is to supply the web server with the DeviceID of which I want to see data (a collection of ParamRecord)
This is the complete View page:
#model List<ParamsTaskLib.ParamRecord>
#{
ViewBag.Title = "SearchResults";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript" >
function UpdateFunc() {
$.get("/home/GetProgress", function(data) {
$("#UpdatePercentage").text(data);
if (data == "100")
location.reload();
else
setTimeout(UpdateFunc, 2000);
});
}
function Update() {
var id = $("#id").val();
$.post("#Url.Content("~/Home/UpdateID/")" + id, function (data) {
UpdateFunc();
});
$("#UpdateAni").attr("src", "#Url.Content("~/Content/Images/ajax-loader.gif")");
$("#UpdatePercentage").show();
}
</script>
<div>
<form method="get" >
#Html.TextBox("id")
#*#Html.EditorFor(model => model.First().DeviceID)*#
#Html.ValidationMessageFor(model => model.First().DeviceID)
<input type="submit" value="Search" />
<img id="UpdateAni" src="#Url.Content("~/Content/Images/ajax-loader_static.gif")" onclick="Update()"/>
<span id="UpdatePercentage" style="display:none" >0</span>
</form>
#if (Model != null )
{
<h4>ID 0x<span>#ViewBag.ID</span> , last update was at #ViewBag.LastUpdateTS</h4>
<h3>Total #ViewBag.NumOfParams parameters</h3>
<hr />
<table border="1" >
<thead>
<tr>
<th>Parameter Number</th>
<th>Device Inner ID</th>
<th>Device Type</th>
<th>Value (Int)</th>
<th>Value (Float)</th>
<th>Value (String)</th>
</tr>
</thead>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Model[i].ParamIndex</td>
<td>#Model[i].DeviceInnerID</td>
<td>#Model[i].DeviceType</td>
<td>#Model[i].ParamValInt</td>
<td>#Model[i].ParamValFloat</td>
<td>#Model[i].ParamValSTR</td>
</tr>
}
</table>
}
else if (ViewBag.NoResults == 1)
{
<h3>No results for ID 0x<span>#ViewBag.ID</span></h3>
}
</div>

Can only update the first record of a result set in MVC

I have taken over support of an MVC application, but unfortunately have pretty much zero experience or knowledge of MVC, so I apologise in advance if this is a stupid question.
We are placing every single result into a listed item in the HTML, then hiding all but one record, so you can filter through the different entries using First/Prev/Next/Last buttons, all via jQuery:
$("a#next").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":last-child")) {
return false;
}
nextli.removeClass("first").addClass("record").next().addClass("first").removeClass("record");
});
$("a#previous").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":first-child")) {
return false;
}
nextli.removeClass("first").addClass("record").prev().addClass("first").removeClass("record");
});
This is fine, and displays the records without any problem, however when you try to edit any record but the first, you get a "System.ArgumentNullException: Value cannot be null." error.
Here's the code in the controller for the edit function:
[HttpPost]
public ActionResult Edit(RecordsView rv)
{
if (ModelState.IsValid)
{
repository.EditRecord(rv.Records.FirstOrDefault().DogIncident);
}
return RedirectToAction("Index");
}
This is defined at the start of the cshtml file:
#using (Html.BeginForm("Edit", "Home", FormMethod.Post,new {#class="record-view"}))
And finally, here is how the HTML is generated on the view:
<li class="first" id="record-1805">
<form action="/Home/Edit" class="record-view" method="post">
<ul>
[form elements]
<li><input type="submit" style="margin: 18px 0;" value="Save"></li>
</ul>
</form>
</li>
<li class="record" id="record-1804">
<form action="/Home/Edit" class="record-view" method="post">
<ul>
[form elements]
<li><input type="submit" style="margin: 18px 0;" value="Save"></li>
</ul>
</form>
</li>
<li class="record" id="record-1803">
<form action="/Home/Edit" class="record-view" method="post">
<ul>
[form elements]
<li><input type="submit" style="margin: 18px 0;" value="Save"></li>
</ul>
</form>
</li>
Does anyone please know why I can only edit the first record that is displayed and not the others? Even if I go through the records using the next/back buttons and back to the first record to submit it, it updates fine, but updating any other record generates an error.
Referencing Darin's post: Pass a parameter to a controller using jquery ajax takes you halfway. He's using an input val in jQuery and passing it to the Controller Action.
Typically you'd provide one input link or #Html.ActionLink per record to be clicked for editing and MVC will bind to the controls parameter to your action (ID or what ever you want) just use the same name on the action link as the parameter and it will be mapped during the post.
data: { input: $('#caption').val() },
Change the signature of your controller action , or add another that takes an 'int' as shown below.
[HttpPost]
public ActionResult Edit(int ID = 0)
{
if (ModelState.IsValid)
{
repository.EditRecord(rv.Records.Where(r => r.ID == ID).DogIncident);
}
return RedirectToAction("Index");
}
Can you post the complete view so we can complete a solution ?
Was expecting the cshtml view. Here's an example:
#model IEnumerable<yourModelName>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.NID)
</th>
<th>
#Html.DisplayNameFor(model => model.CreatedOn)
</th>
<th>
#Html.DisplayNameFor(model => model.ExtensionAttribute15)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.yourElement1)
</td>
<td>
#Html.DisplayFor(modelItem => item.yourElement2)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
</td>
</tr>
}
</table>
#section Scripts{
<script type="text/javascript">
$("a#next").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":last-child")) {
return false;
}
nextli.removeClass("first").addClass("record").next().addClass("first").removeClass("record");
});
$("a#previous").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":first-child")) {
return false;
}
nextli.removeClass("first").addClass("record").prev().addClass("first").removeClass("record");
});
</script>
}

Resources