Empty model when passing JSON data from View - javascript

I am currently trying to pass data from AJAX to Controller, however, the model always shows up empty/count = 0.
AJAX call:
$("#btnSubmit").click(function(e) {
e.preventDefault();
var _this = $(this);
var url = _this.closest("form").attr("action");
var rows = [];
var items = $(".itemRow");
$.each(items, function(i, item) {
var tbOne = $(item).find("input[name='tbOne']").val();
var tbTwo = $(item).find("input[name='tbTwo']").val();
var row = {
Test1: tbOne,
Test2: tbTwo
};
rows.push(row);
});
//Let's post to server
$.ajax({
type: "POST",
url: url,
data: rows,
contentType: "application/json"
})
.done(function(result) {
//do something with the result
})
});
});
Model:
public class Test
{
public string Test1 {get; set;}
public string Test2 {get; set;}
}
Controller:
[HttpPost]
public ActionResult Insert(<SomeOtherModel> otherModel, IEnumerable<Test> model)
{
foreach (var item in model)
{
// to do here
}
}
I am not sure what I am missing... I tried to search on other posts and they did relatively the same thing as I did. But I just can't get the data to my controller..

Firstly,you passed one model to controller,so the Action should have only one parameter.Furthermore,your contentType is"application/json",and you data is not json data.Besides,if you want to pass json data to controller,you need to use [FromBody].
Here is a demo worked:
Controller:
[HttpGet]
public ActionResult Insert()
{
return View();
}
[HttpPost]
public ActionResult Insert([FromBody]IEnumerable<Test> model)
{
return View();
}
View:
#{
ViewData["Title"] = "Insert";
}
<h1>Insert</h1>
<button id="btnSubmit">submit</button>
#section scripts{
<script type="text/javascript">
$("#btnSubmit").click(function () {
var rows = new Array();
var row = {};
row.Test1 = "test1";
row.Test2 = "test2";
rows.push(row);
var row1 = {};
row1.Test1 = "test11";
row1.Test2 = "test21";
rows.push(row1);
var model = JSON.stringify(rows);
//Let's post to server
$.ajax({
type: "POST",
url: "Insert",
data: model,
contentType: "application/json; charset=utf-8"
});
});
</script>
}
Result:

Related

Cannot show value after AJAX call (ASP.NET MVC)

I have two <p> fields where I need to assign text
Here is html code:
<p id="appId" style="visibility: hidden;"></p>
<p id="calculationId" style="visibility: hidden;"></p>
I make AJAX call like this
$('#openCalculationConsumables').click(function() {
addConsumables();
});
function addConsumables() {
var patientName = $('#patientsId').val();
var finding = $('#findingvalue').val();
var procedure = $('#procedurevalue').val();
var model = {
findingValue: finding,
procedureValue: procedure,
patientId:patientName
}
$.ajax({
url: '#Url.Action("AddIndividualCalculation", "Calculations")',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(model),
type: 'POST',
dataType: 'json',
processData: false,
success: function (data) {
$('#masters_data').load('#Url.Action("IndividualCalculationConsumables", "Calculations")', function() {
var list = data;
$('#calculationId').text(list[0].calcid);
$('#appId').text(list[0].appid);
});
}
});
}
And here is my back end code:
public JsonResult AddIndividualCalculation(string findingValue, string procedureValue,int patientId)
{
using (var ctx = new ApplicationDbContext())
{
Calculation calc = new Calculation
{
};
ctx.Calculations.Add(calc);
ctx.SaveChanges();
int calculationId = calc.Id;
Appointment app = new Appointment
{
Calculation_id = calculationId,
FindingContent = findingValue,
ProcedureContent = procedureValue,
Patient_id = patientId
};
ctx.Appointments.Add(app);
ctx.SaveChanges();
int appointmentId = app.Id;
var items = new
{
appid = appointmentId,
calcid = calculationId
};
return Json(items,JsonRequestBehavior.AllowGet);
}
}
I set breakpoint and see , that I have values in items. In console log I have this {appid: 1006, calcid: 1006}
But I cant assign it to <p> and have this error.
Cannot read property 'calcid' of undefined
Where is my problem?
Thank's for help.
$('#masters_data').load('#Url.Action("IndividualCalculationConsumables", "Calculations")', function() {
var list = data;
$('#calculationId').text(list[0].calcid);
$('#appId').text(list[0].appid);
});
list[0] is not defined as you are returning just an anonymous object not a list of objects
new {
appid = appointmentId,
calcid = calculationId
};

Trying to Bind the gridview but after binding data and rows both disappear

I' m trying to bind a gridview using Ajax jquery.while I saw the data is bind with gridview and shown in the browser but after completion of debugging .all data that fill up the rows goes disappear.Trying to find out the issue but after execution of $("#THistory").click(function () { this function the debugger goes to Page_Load method
Ajax part
<%--GridView Populate--%>
<script type="text/javascript">
$(function () {
$("#THistory").click(function () {
$.ajax({
type: "POST",
url: "TDC.aspx/GetCustomers",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
alert(response.d);
},
error: function (response) {
alert(response.d);
}
});
});
function OnSuccess(response) {
var xmlDoc = $.parseXML(response.d);
var xml = $(xmlDoc);
var customers = xml.find("Table");
var row = $("[id*=gvCustomers] tr:last-child").clone(true);
$("[id*=gvCustomers] tr").not($("[id*=gvCustomers] tr:first-child")).remove();
$.each(customers, function () {
var customer = $(this);
$("td", row).eq(0).html($(this).find("REVISION").text());
$("td", row).eq(1).html($(this).find("P_GROUP").text());
$("[id*=gvCustomers]").append(row);
row = $("[id*=gvCustomers] tr:last-child").clone(true);
});
}
});
</script>
<%--GridView Populate--%>
.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.BindDummyRow();
}
}
private void BindDummyRow()
{
DataTable dummy = new DataTable();
dummy.Columns.Add("REVISION");
dummy.Columns.Add("P_GROUP");
dummy.Rows.Add();
gvCustomers.DataSource = dummy;
gvCustomers.DataBind();
//gvCustomers.Visible = false;
}
[WebMethod]
public static string GetCustomers()
{
string query = "SELECT REVISION, P_GROUP from tdc_product1 ";
OracleCommand cmd = new OracleCommand(query);
return GetData(cmd).GetXml();
}
private static DataSet GetData(OracleCommand cmd)
{
string strConnString = ConfigurationManager.ConnectionStrings["conndbprodnew"].ConnectionString;
using (OracleConnection con = new OracleConnection(strConnString))
{
using (OracleDataAdapter sda = new OracleDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataSet ds = new DataSet())
{
sda.Fill(ds);
return ds;
}
}
}
}

ASP.NET MVC ADO.NET Query per table row

Here I have this table:
If I click the button, I want to pass the table per row to the controller, then perform ADO.NET Query per row, like for example, perform "UPDATE tbluser SET note='INACTIVE' WHERE id=#id" per row.
One of the main purpose of this is when i filter the table, only the visible rows will be passed.
I already have a code here to pass to controller using AJAX but I don't know what to do afterwards.
JS:
var HTMLtbl =
{
getData: function (table) {
var data = [];
oTable.rows({ search: 'applied' }).every(function () {
var cols = [];
var rowNode = this.node();
$(rowNode).find("td").each(function () {
cols.push($(this).text().trim() || null);
});
data.push(cols);
});
return data;
}
}
$("btnSubmit").on("click", function () {
var data = HTMLtbl.getData($(".datatable"));
var parameters = {};
parameters.array = data;
var request = $.ajax({
async: true,
cache: false,
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/Home/SubmitTable",
data: JSON.stringify(parameters),
success: function () {
window.location.href = "/Home/Index";
}
});
request.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
});
Controller:
[HttpPost]
public JsonResult SubmitTable(string[][] array)
{
//I don't know what to do here now, please help
}
My Solution based on Mostafa's answer:
JS:
var HTMLtbl =
{
getData: function () {
var data = [];
oTable.rows({ search: 'applied' }).every(function () {
var cols = [];
var rowNode = this.node();
$(rowNode).find("td").each(function () {
cols.push($(this).text().trim() || null);
});
data.push(cols);
});
return data;
}
}
$("#btnSubmit").on("click", function () {
var data = HTMLtbl.getData($(".datatable"));
var parameters = {};
parameters.array = data;
var request = $.ajax({
async: true,
cache: false,
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/Home/SubmitTable",
data: JSON.stringify(parameters),
success: function () {
window.location.href = "/Home/Index";
}
});
request.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
});
Controller:
[HttpPost]
public JsonResult SubmitTable(string[][] array)
{
string result = string.Empty;
try
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Connection"].ConnectionString);
con.Open();
foreach (var arr in array)
{
SqlCommand cmd = new SqlCommand("UPDATE tbluser SET remark='INACTIVE' WHERE id = #id", con);
cmd.Parameters.AddWithValue("#id", arr[0]);
cmd.ExecuteNonQuery();
}
con.Close();
}
catch (Exception ex)
{
result = ex.Message;
}
return Json("Records updated successfully.", JsonRequestBehavior.AllowGet);
}
I can now use this for more complicated stuff, thanks
If you want to update a custom row you can add a button for each row with custom text and icon, then add a "data-" attribute to this button and path your row id,
<input type="button" data-rowId="1" class="changeActivationState">activate</input>
in this example I added a data field to my imput after that I define this javascript method:
$(".changeActivationState").click(function(){
$(this).data("rowId")//get the selected row id and call you service
});
using this code you can read first element for each row and perform a web service call for all rows
var arr = [];
$("#yourtable tr").each(function(){
arr.push($(this).find("td:first").text()); //put elements into array
});
and using this code you can read all rows into a json object
var tbl = $('#yourtable tr').map(function() {
return $(this).find('td').map(function() {
return $(this).html();
}).get();
}).get();
assume that you passed the list to action
int[] passedIDsfromBrowser = ///filled with data that comes from browser;
SqlConnection connection = ....
SqlCommand command = new SqlCommand(connection);
command.CommandText = "Update MYTABLENAME Set Active = true where ID in (" string.Join(",", passedIDsfromBrowser ) + ")";
connection.Open();
command.ExecuteNonQuery();
connection.Close();
this is a pseudo code.
or if you want a loop and updating each row with a loop
SqlConnection connection = ....
SqlCommand command = new SqlCommand(connection);
connection.Open();
for(int i = 0 ; i < passedIDsfromBrowser.Length; i++){
command.CommandText = "YOURQUERY";
command.ExecuteNonQuery();
}
connection.Close();

Unable to filter data from knockout view model with drop down selection change

I have a simple controller like this:
public JsonResult GetPosts(int? id)
{
var varid = id;
var ret = (from post in db.Posts.ToList()
orderby post.PostedDate descending
select new
{
NeighbourhoodId = varid,
Message = post.Message,
PostedByName = post.ApplicationUser.UserName,
PostedDate = post.PostedDate.ToString(),
PostId = post.PostId,
});
return Json(ret, JsonRequestBehavior.AllowGet);
}
Here, i am able to get the dropdown selected value.I am assigning it to a variable varid and then assigning it to NeighbourhoodId.
But, when the view page is rendered nothing changes all the 4 Post are showing.but in reality it should display only 2 Post.
This is my view page code:
<ul id="msgHolder" data-bind="foreach: posts">
<li class="postHolder">
<p><a data-bind="text: PostedByName"></a>: <span data-bind=" html: Message"></span></p>
and my wallpost.js file in script folder where all knockout view model related code is here.It first loads all the Post from database correctly but data doesnot get filtered if i am trying to filter it with dropdown change.
function Post(data) {
var self = this;
data = data || {};
self.PostId = data.PostId;
self.NeighbourhoodId = data.NeighbourhoodId;
self.Message = ko.observable(data.Message || "");
self.PostedByName = data.PostedByName || "";
self.PostedDate = getTimeAgo(data.PostedDate);
self.error = ko.observable();
function viewModel() {
var self = this;
self.posts = ko.observableArray();
self.newMessage = ko.observable();
self.error = ko.observable();
self.loadPosts = function () {
// to load existing posts
$.ajax({
url: postApiUrl,
datatype: "json",
contentType: "application/json",
cache: false,
type: 'Get'
})
.done(function (data) {
var mappedPosts = $.map(data, function (item)
{ return new Post(item); });
self.posts(mappedPosts);
})
.fail(function () {
error('unable to load posts');
});
}
return self;
};
ko.applyBindings(new viewModel());
and my dropdown related code is here:
#Html.DropDownList("Locations", ViewBag.NeighbourhoodId as SelectList,"Select a Location")
<script type="text/javascript">
$(document).ready(function () {
$("#Locations").change(function () {
var locationSelected = $("#Locations").val();
var url = '#Url.Action("GetPosts", "Post")';
$.post(url, { id: locationSelected },
function (data) {
});
});
});
</script>
When i debug, i am getting correct id value in controller but there is problem in filtering out data. Is there a need for some change in knockout file.what to do here ??
Instead of mixing jquery event handlers and knockout bindings, i think it's better for you handle all with knockout.
Bind your select element (drop down) with the options binding and load the locations array on view model initialization; bind the value to a observable property, ex: 'CurrentLocation'
Subscribe to the change of the property 'CurrentLocation', ex:
myViewModel.CurrentLocation.subscribe(function(newValue) {
//request to GetPosts here
});
On .done() function of the GetPosts request update the observableArray with the items received by the server
Hope this helps!
UPDATE
The following is a very simple example, i changed my mind and used "event" binding to handle the change event instead of "options" binding but the concept it's the same.
#Html.DropDownList("Locations", new SelectList(Model.Locations, "Id", "Name"), new { data_bind = "event: { change: reloadPosts}" })
<ul data-bind="foreach: posts">
<li data-bind="text:CompleteText"></li>
</ul>
<script>
function Post(data) {
var self = this;
self.Id = ko.observable(data.Id);
self.LocationId = ko.observable(data.LocationId);
self.Text = ko.observable(data.Text);
self.CompleteText = ko.computed(function () {
return self.Id() + " " + self.Text();
});
}
function PageViewModel() {
var self = this;
self.posts = ko.observableArray();
self.reloadPosts = function () {
$.ajax({
type:"POST",
url: "GetPosts",
data: { locationId: $("#Locations").val() }
}).done(function (data) {
var mappedPosts = $.map(data, function (item)
{ return new Post(item); });
self.posts(mappedPosts);
});
}
}
var vm = new PageViewModel();
ko.applyBindings(vm);
</script>
The GetPosts method in the controller:
[HttpPost]
public JsonResult GetPosts(string locationId)
{
var selectedPosts = posts.Where(x => x.LocationId == locationId);
return Json(selectedPosts, JsonRequestBehavior.AllowGet);
}
The posts collection in the controller in the example above it's just an inmemory collection, probably you will read it from a DB or something like that.
The post class on the c# code:
class Post
{
public string Id { get; set; }
public string LocationId { get; set; }
public string Text { get; set; }
}
And finally the viewmodel used:
public class TestViewModel
{
public List<Location> Locations { get; set; }
}

How to get rid of Serialization in MVC

I have created a jQuery code which will take a form(which is in my view) and it will serialize it and it will post that to my controller.......Jquery code looks like this......
$(document).ready(function () {
$('#submit').click(function () {
var jsonObj = $('#form').serialize();
$.ajax({
type: "POST",
url: "../Home/Index",
data: JSON.stringify({ "cus": jsonObj }),
success: function(data){
alert(data + "done");
},
error:function(){
alert("Error!!!!");
}
});
});
});
This is how my controller method looks like:..........
[HttpPost]
public ActionResult Index(Customer cus)
{
string str = null;
if (cus.Name == "jude")
str = "Success";
else
str = "Error!!";
return Json(str);
}
Now i need to undo the serialization inside my controller method......can someone please give me an idea to do this..........
I have tried two ways to do this but didn't work.....
1 - var model = (Customer)cus.Deserialize();
2 - JavaScriptSerializer js = new JavaScriptSerializer();
var cus1 = js.Deserialize<Customer>(cus);

Categories

Resources