Kendo UI DateTimePicker does not bind properly into the controller - javascript

I have a complex object that I need to pass to the controller when submitting a form. This complex object has an object and a list of objects. This is my Web API controller that receives the complex object via post with ajax:
[HttpPost]
public IHttpActionResult CreatePurchaseInvoice(NewPurchaseInvoice newPurchaseInvoice)
{
try
{
var purchaseInvoice = new PurchaseInvoice
{
Id = newPurchaseInvoice.PurchaseInvoice.Id,
DatePurchaseInvoice = newPurchaseInvoice.PurchaseInvoice.DatePurchaseInvoice
};
// Here i do other stuff with the list of objects
_context.SaveChanges();
}
catch(Exception ex)
{
return BadRequest();
}
return Ok();
}
This is my html form:
<form id="purchaseInvoiceForm">
<div class="row">
<div class="col-lg-6">
<label>Order:</label>
<select id="numberOrder" class="form-control" required name="numberOrder">
<option value="">Select an order number...</option>
</select>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>Date of Purchase Invoice:</label><br />
<input id="datePurchaseInvoice" style="width: 70%" />
</div>
</div>
</div>
//Here i have an html table and every row i push into an array of the complex object
</form>
And this is my jQuery code where i send the complex object via ajax:
$(document).ready(function(){
//this is the declaration of my complex object
var newPurchaseInvoice = {
PurchaseInvoice: {},
PurchaseInvoiceDetails: []
}
$("#purchaseInvoiceForm").submit(function (e) {
e.preventDefault();
newPurchaseInvoice.PurchaseInvoice= {
Id: $("#numberOrder").val(),
DatePurchaseInvoice : $("#datePurchaseInvoice").val()
}
$.ajax({
url: "/api/purchaseInvoices",
method: "post",
data: newPurchaseInvoice
});
});
});
The problem I have is that the date of the KendoDateTimePicker is not sending correctly to the controller.
I get this date and not the one I select with the kendoDateTimePicker. This is the DatePurchaseInvoice property of my PurchaseInvoice model in spanish:
This is my KendoDateTimePicker for jQuery:
$("#datePurchaseInvoice").kendoDateTimePicker({
value: new Date(),
dateInput: true
});
And this is my NewPurchaseInvoice model:
public class public class NewPurchaseInvoice
{
public PurchaseInvoice PurchaseInvoice{ get; set; }
public List<PurchaseInvoiceDetail> PurchaseInvoiceDetails{ get; set; }
}
This is my PurchaseInvoice model:
public class PurchaseInvoice
{
public int Id { get; set; }
public DateTime DatePurchaseInvoice { get; set; }
}

You need to be specifying the type of data you are supplying:
contentType: 'application/json'
And possibly dataType too depending on your response type. And according to this post, you may need to stringify your response. I don't think I've needed to do that but I don't often use AJAX operations for complicated data types.

Related

move Employee ID from the selected rows of the table into a hidden List<string> column of the table

I am trying to store the employeeIds from the selected row of the table into the model column EmployeeReinstateVM.selectedEmployeeId from the click event of 'btnUpdate', each id must be stored to EmployeeReinstateVM.selectedEmployeeId. Currently the Ids are stored in to selectedEmployeeId hidden column as array string "23,24,25" So I am trying to store each employee id of the selected rows into the EmployeeReinstateVM.selectedEmployeeId from javascript to send the model into controller post method with selected employeeIds. I am looking for the help from someone. Here is the code
Model Class
public class EmployeeReinstateVM
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public List<string> selectedEmployeeId { get; set; }
public IEnumerable<EmployeeModel> employees { get; set; }
}
Views
<style>
.selectable-row.selected {
background-color: #ddd;
}
</style>
#model EmployeeReinstateVM
foreach (var item in Model.employees)
{
<tr class="selectable-row
#(Model.selectedEmployeeId.Contains(item.EmployeeID.ToString()) ? "selected" :"")"
employee-id="#item.EmployeeID">
<td>#item.EmployeeID</td>
<td>#item.EmployeeName</td>
</tr>
}
<input hidden id="selectedEmployeeId" asp-for="selectedEmployeeId" name="selectedEmployeeId" value="">
<button type="submit" class="btn btn-primary form-control" id="btnUpdate" name="btnActivate" value="update">
Update
</button>
<script type="text/javascript">
$(document).ready(function() {
var employeeIds = [];
$(".selectable-row").click(function() {
$(this).toggleClass("selected");
var employeeId = $(this).attr('employee-id');
if ($(this).hasClass("selected")) {
employeeIds.push(employeeId);
//employeeIds.push($(this).attr('employee-id'));
} else {
employeeIds = employeeIds.filter(function(id) {
return id !== employeeId;
});
}
});
$("#btnUpdate").click(function() {
$("#selectedEmployeeId").val(employeeIds);
console.log($("#selectedEmployeeId").val());
});
})
This seems to be simpler - you need to store the result
$(".selectable-row").click(function() {
$(this).toggleClass("selected");
$("#selectedEmployeeId")
.val(
$("tr[employee-id].selected")
.map(function() { return $(this).attr("employee-id") })
.get()
.join(",")
);
});
store each employee id of the selected rows into the
EmployeeReinstateVM.selectedEmployeeId from javascript to send the
model into controller post method with selected employeeIds
Do you want to try the below code?
$("#btnSave").click(function () {
$("#selectedEmployeeId").val(employeeIds);
console.log($("#selectedEmployeeId").val());
$.ajax({
type: "POST",
url: "/Keepselected/ReinstateEmployee",
data: { "selectedEmployeeId": employeeIds },
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (response) {
alert(response);
}
});
});
result:

How to pass javaScript value in view page to Controller Action parameter, when change drop down list

I want to pass student Id in my controller action, I used JsonResult action, I catch student id but can't pass in action,
this is my JavaScript code ,
<script type="text/javascript">
$(document).ready(function () {
$("#sId").change(function(){
var studentId = $(this).val();
debugger
$.ajax({
type:"post",
url:"/Department/GetDeptName/" + studentId,
contentType:"html",
success:function(response){
debugger
$("#dId").empty();
$("#did").append(response);
}
})
})
});
</script>
And I have a Dropdown list, I pass my list fron database using ViewBag. When I select a student name then need to pass his/her department name. This is the view code
<div class="row">
<div class="col-md-6 mb-4">
<label asp-for="Name" class="control-label">Student Name</label>
<select asp-for="Id" class="form-control" id="sId"
asp-items="#(new SelectList(#ViewBag.messageStudent,"Id", "Name"))">
</select>
</div>
<div class="col-md-6 mb-4">
<label asp-for="DeptName" class="control-label">Department Name</label>
<input asp-for="DeptName" id="dId" class="form-control mb-3" type="text" placeholder="Dept Name" disabled>
</div>
<input type="hidden" asp-for="Id" name="Id" id="DeptName" />
</div>
This is my controller code that is passed a list from database to View
public async Task<IActionResult> DropDown()
{
var model = _scope.Resolve<FormModel>();
await model.LoadStudenDataAsync();
var studentList = model.StudentList.ToList();
studentList.Insert(0, new Student { Id = 0, Name = "Select Group" });
ViewBag.messageStudent = studentList;
return View(model);
}
Now I need to pass student id from view page, if i pass student id then I solve my problem,
This is my JsonResult Action
public async Task<JsonResult> GetDeptName(int studentId)
{
var model = _scope.Resolve<FormModel>();
if (ModelState.IsValid)
{
await model.DeptList(studentId);
}
return Json(model);
}
Please help me anyone how to pass student id,Thanks in Advance
you have to use get ajax since you are not posting any data in the request body. And change data type to json since you are returning json
$.ajax({
type:"GET",
url:"/Department/GetDeptName/" + studentId,
dataType: 'json',
....
and action
[Route("~/Department/GetDeptName/{studentId}")]
public async Task<JsonResult> GetDeptName(int studentId)
and fix route config
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
but if you use old net that doesn't support attribute routing then just change ajax and leave the action as it is now
$.ajax({
type:"GET",
url:"/Department/GetDeptName?studentId=" + studentId,
dataType: 'json',
....

Checkbox Constantly Returns False?

I'm submitting a form using AJAX as follows:
$('#userUpdateForm').submit(function (e) {
//var attachment = $('form#userUpdateForm').serialize();
var blue = document.getElementById('blueCheck').checked;
var personDetails = {
Enabled: $('#eCheck').val(),
Authorised: $('#authCheck').val(),
Green: $('#greenCheck').val(),
Blue: blue,
//Blue: $('input[name="blueCheckbox"]').is(':checked'),
Red: $('#redCheck').val(),
Id: $('#idCheck').val()
};
$.ajax({
type: "POST",
//url: '<%= Url.Action("submitForm", "Home") %>',
url: '#Url.Action("submitForm", "Home")',
data: JSON.stringify({ jsonForm: personDetails}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
'#Url.Action("Index", "Home")';
alert("Success");
},
error: function (result) {
alert("A problem occured when submitting the form.");
}
});
e.preventDefault();
});
'Blue' refers to a checkbox. The form then submits to the controller HomeController/submitForm as below:
public class updatePersonDetails
{
public string Enabled { get; set; }
public string Authorised { get; set; }
public string Green { get; set; }
public bool Blue { get; set; }
public string Red { get; set; }
public string Id { get; set; }
}
[HttpPost]
public ActionResult submitForm(updatePersonDetails personDetails)
{
System.Diagnostics.Debug.WriteLine(personDetails.Blue.ToString());
return View();
}
But 'Blue' persistently returns 'False' when the checkbox has been checked and should return true. As you can see below, I have tried a variety of things to get the value:
var attachment = $('form#userUpdateForm').serialize();
var blue = document.getElementById('blueCheck').checked;
Blue: $('input[name="blueCheckbox"]').is(':checked'),
What's even stranger is the jsonForm on the browser shows 'Blue:true' in the request payload. Is there something I'm missing from getting the proper value on the server side?
Edit: the HTML for the form
<form id="userUpdateForm" method="post">
<fieldset>
<legend>User Details</legend>
<input type="checkbox" name="authorisedCheckbox" value="Authorised" id="authCheck" />Authorised<br />
<input type="checkbox" name="enabledCheckbox" value="Enabled" id="eCheck" />Enabled<br />
</fieldset>
<fieldset>
<legend>Favourite Colours</legend>
<input type="checkbox" name="blueCheckbox" value="Blue" id="blueCheck" />Blue<br />
<input type="checkbox" name="greenCheckbox" value="Green" id="greenCheck" />Green<br />
<input type="checkbox" name="redCheckbox" value="Red" id="redCheck" />Red<br />
<input type="hidden" name="personId" id="idCheck" value='#ViewData["personId"]'>
</fieldset>
<input type="submit" value="Save Changes" name="Save Changes">
<button type="button">Cancel</button>
</form>
There's also a onload function to set the checkboxes to reflect the original data of the person, but I wouldn't have thought that would set the checkbox state as 'False' permanently.
var blueVal = '#ViewData["blue"]';
if (blueVal == "checked") {
document.getElementById("blueCheck").checked = true;
}
On the javascript side you send your data like this:
data: JSON.stringify({ jsonForm: personDetails}),
But your Action signature in the Controller is this:
[HttpPost]
public ActionResult submitForm(updatePersonDetails personDetails)
The default MVC Binder can't bind that together. In the POST your ViewModel is nested in an object with "jsonForm" property, MVC can't match that to the "personDetails" parameter.
You need to either:
Change the JSON property name to match the parameter name in your Action:
data: JSON.stringify({ personDetails: personDetails})
Or just delete the nested property. For simple POSTs there is no need for that. You can just POST your data like this:
data: JSON.stringify(personDetails)
I like this solution more because then it doesn't matter what the parameter name in your action is. The MVC will bind the data solely based on the property names in updatePersonDetails class.
Try to execute same code after removing below statement
e.preventDefault();
For more information about preventDefault please check below link
https://www.w3schools.com/jsref/event_preventdefault.asp
Hope this will help you!
Try this
var blue = $('#blueCheck').is(":checked") ? true : false;

ajax JavaScript not deleting from DataTable (using API's)

Newbie ALERT
Basically I have a web application that has a dropdown list. When you select an item in the drop-down list the table is drawn to show all the credentials that are tied to that drop-down option.
Problem: When running, everything functions properly except for the JavaScript piece that does not remove the line in the table, but deletes the record on the back-end. So once i refresh and go back to that credential type the one I deleted is gone.
I've tried a lot of different stuff, but i pretty new to JavaScript and C#, don't know if there is a better way of doing this. Probably supplied too much information but i rather too much than not enough! :)
Any help, tips, ideas are greatly appreciated.
Credential API Controller: Delete Function
[HttpDelete]
public IHttpActionResult DeleteCustomer(int id)
{
var credentialInDb = _context.Credentials.SingleOrDefault(c => c.Id == id);
if (credentialInDb == null)
return NotFound();
_context.Credentials.Remove(credentialInDb);
_context.SaveChanges();
return Ok();
}
Model for Credential
public class Credentials
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
[Required]
[StringLength(255)]
public string Username { get; set; }
[Required]
[StringLength(255)]
public string Password { get; set; }
public string Website { get; set; }
public string Notes { get; set; }
public CredentialType CredentialType { get; set; }
[Display(Name = "Credential Type")]
public int CredentialTypeId { get; set; }
}
ViewModel for CredentialFormViewModel
This allows the selectedCredential variable for the page below
public class CredentialFormViewModel
{
public IEnumerable<CredentialType> CredentialTypes { get; set; }
public Credentials Credentials { get; set; }
public int SelectedCredentialTypeId { get; set; }
}
View that displays the DataTable:
#model Appp.ViewModels.CredentialFormViewModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Select a Credential Type</h2>
#Html.DropDownListFor(m => m.SelectedCredentialTypeId, new SelectList(Model.CredentialTypes, "Id", "Name"), "Select Credential Type", new { #class = "form-control", onchange = "SelectCredType()" })
<br/>
<table id="credentials" class="table table-bordered table-hover">
<thead>
<tr>
<th>Credential</th>
<th>Username</th>
<th>Password</th>
<th>Website</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
#section scripts
{
<script>
function SelectCredType() {
var credId = $('#SelectedCredentialTypeId').val();
if ($.fn.dataTable.isDataTable("#credentials")) {
if (credId == "") {
var table = $("#credentials").DataTable();
table.destroy();
} else {
var table = $("#credentials").DataTable();
table.destroy();
SelectCredType();
}
} else {
$(document)
.ready(function() {
var table = $("#credentials")
.DataTable({
ajax: {
url: "/api/credentials?credentialTypeId=" + credId,
dataSrc: ""
},
columns: [
{
data: "name",
},
{
data: "username"
},
{
data: "password"
},
{
data: "website"
},
{
data: "id",
render: function(data, type, credentials) {
return "<button class='btn btn-primary btn-xs js-delete' data-credential-id=" + credentials.id + ">Delete</button>";
}
}
]
});
}
);
}
};
$("#credentials")
.on("click",
".js-delete",
function() {
var button = $(this);
bootbox.confirm("Are you sure you want to delete this?",
function(result) {
if (result) {
$.ajax({
url: "/api/Credentials/" + button.attr("data-credential-id"),
method: "DELETE",
sucess: function() {
table.row(button.parents("tr")).remove().draw();
}
});
}
});
});
</script>
}
First issue
Your JavaScript code does not work because the table variable is undefined within your delete function.
There are many ways you could approach to fix that. But first you will need to get your head around variable scopes in JavaScript.
Your simplest solution is to make table a globally-scoped variable that way you can access the instance from any function you create. So instead of defining it here:
...
$(document)
.ready(function() {
var table = $("#credentials")
...
Move it up to the top of your script file:
var table;
function SelectCredType() {
...
$(document)
.ready(function() {
table = $("#credentials")
...
}
Now when you access it from your Delete function, it will be defined.
Note: I would also change the name of the table variable to something else as global variables in JavaScript will conflict with any script you import which can lead to a debugging nightmare. Best to name it something that will be most likely unique, eg. coberlinTable.
Second Issue
I don't know if you did a cut and past error, but you have misspelled success in your ajax Delete function.

Kendo UI KendoTreeView HierarchicalDataSource not showing nodes

My Kendo UI TreeView is not getting the returned JSON objects added to the treeview.
I can see from the controller method that gets called that the Json being given to the DataSource looks like this (but with more files and folders)
{"NodeID":-842352767,
"Name":"/",
"Folders":[{"NodeID":1804712307,"Name":"/$Recycle.Bin","Folders":null,"Files":null},{"NodeID":-582712839,"Name":"/Windows","Folders":null,"Files":null}],
"Files":["/.rnd","/msdia80.dll"]}
My view is as follows:
#model ProjName.Models.BrowseNode
<div id ="wrapper">
<h1>Browser</h1>
<div id="treeview" style="float:left;margin: 40px;">
</div>
</div>
<script>
function populateTreeView() {
var remoteDataSource = new kendo.data.HierarchicalDataSource({
type: "json",
transport: {
read: "FileBrowser/GetHierarchy"
},
schema: {
model: {
id: "NodeID",
text: "Name",
expanded: false,
children: "Folders",
},
}
});
$("#treeview").kendoTreeView({
dataSource: remoteDataSource,
dataTextField: "Name"
});
}
$(document).ready(function () {
populateTreeView();
});
With BrowseNode defined as:
public class BrowseNode
{
public int NodeID {
get
{
if (null == Name)
return default(int);
return Name.GetHashCode();
}
}
public string Name { get; set; }
public List<BrowseNode> Folders { get; set; }
public List<string> Files { get; set; }
}
Anything obviously wrong or any tips for debugging this sort of thing?
It turned out my JSON wasn't what the DataSource wanted. It should have been an array returned at the top level, so the JSON is surrounded by [ ] brackets as follows:
[{"NodeID":-842352767, "Name":"/", "Folders":[{"NodeID":1804712307,"Name":"/$Recycle.Bin","Folders":null,"Files":null},{"NodeID":-582712839,"Name":"/Windows","Folders":null,"Files":null}], "Files":["/.rnd","/msdia80.dll"]}]

Categories