AJAX post with model property - c#

I want to do Something like
$.ajax({
url: '/Home/AjaxTest',
data: {
id: #Model.Prop
},
type: 'post',
cache: false,
success: function (response) {
console.log(response);
}
...
However, It didn't work. I know that if I have a hidden field for it, like
#Html.HiddenFor(model => model.Id)
then I can get the property value by
data: { id: $('input[name="Id"]').val() },
Still I wonder. Are there any way else to access the Model property more directly?

data: { id: "#Model.Prop" } // may or may not need quotes depending on data type.
If you do this, it will be the value of the Model.Prop field at the time of rendering the page so any modifications to inputs using that property will not be reflected.
If you want the actual data from an input control that has been rendered using EditorFor, etc:
data: { #(Model.Prop.GetType().Name): $('input[name="#(ViewData.TemplateInfo.HtmlFieldPrefix + "." + Model.Prop.GetType().Name)"]').val() }
This will render the javascript using the property name as the json index and the same name but including the model (and any containing models) prefix as the name of the element to find the value of.

Yes you can do if you follow the Model pattern of java script.
This is your java script file.
var JSModel = (function(){
var model = {};
var init = function(){
//Perfome your operations
};
return {
init:init,
model :model //return beacuse we want to acccess it in cshtml
};
})();
$(document).ready(function() {
JSModel .init();
});
Now in cshtml, you will do this:
//Invlude your JS file here and then
<script>
JSModel.model = #Html.Raw(Json.Encode(Model)); // You will get the model in your js file. it will in JSON form
</script>

Related

Update List in ViewModel with Ajax ASP .NET MVC

I have a List (List) of Model objects which is presented in a view. I would like to add to that list without refreshing the page - therefore i thought Ajax is a great soloution. Im currently having a hard time getting it working.
My view is rendering a PartialView which contains the list.
Can somebody give me a hint how to pass a list to the controller and then back to the view without updating the whole page?
I hope my question makes sense.
/chris
EDIT:
I've been trying with JQuery. Looks like this:
<script>
$(document).ready(function () {
$("#btnSave").click(function () {
$.ajax(
{
type: "POST", //HTTP POST Method
url: "/Video/Index", // Controller/View
data: { //Passing data
testString: $("#txtArea").val(),
videoID: '#(Model.Video.iVideo_ID)',
taskID: document.getElementById('dropVal').value
}
}).success(function () {
$("#proever").load("/Video/Index");
});
})
})
With this method i get to HttpPost method in my controller. And i pass the parameters into it succesfully.
[HttpPost]
public ActionResult Index(CommentViewModel viewModel)
{
System.Diagnostics.Debug.WriteLine(viewModel.testString);
System.Diagnostics.Debug.WriteLine(viewModel.videoID);
System.Diagnostics.Debug.WriteLine(viewModel.taskID);
viewModel.testString = "new text string";
return View(viewModel);
}
The problem is now that i can't get the updated viewmodel back to the view.. What am i doing wrong?
In this example I don't update the list but just a test string to see if i can get it updated back to the view..
For those who's interested I solved the problem like this:
<script>
$(document).ready(function () {
$("#btnSave").click(function () {
$.ajax(
{
type: "POST", //HTTP POST Method
url: "/Video/AddComment", // Controller/View
data: { //Passing data
//Reading text box values using Jquery
sComment: $("#txtArea").val(),
videoID: '#(Model.Video.iVideo_ID)',
taskID: document.getElementById('dropVal').value
}
}).success(function () {
console.log("good");
var txt = document.getElementById('txtArea').value;
console.log(txt);
var taskId = document.getElementById('dropVal').value;
var taskCont = $("#dropVal option:selected").text();
var taskContNum = Number(taskCont) - 1
console.log(taskCont);
var node = document.createTextNode(txt);
var para = document.createElement("div");
para.appendChild(node);
document.getElementById('taskPalace').appendChild(para);
document.getElementById('cola-' + '' + taskContNum).appendChild(para);
document.getElementById('txtArea').value = "";
});
})
})
So if the request succeeds without any errors in the HttpPost method it adds the comment to the database(through the HttpPost) and the jquery adds it to the view.
You need to use persistent data store in your case. Currently, your async post request will change the view model data but data is lost in subsequent http requests when you try to load the view with .load(...) jquery function.
1- Send async request to http post controller action to change the data in db store for example.
2- Read the view model data from db in http get index action. ($("#proever").load("/Video/Index"))
You can try this:
$(document).ready(function () {
$("#btnSave").click(function () {
var model = {
testString: $("#txtArea").val(),
videoID: '#(Model.Video.iVideo_ID)',
taskID: document.getElementById('dropVal').value
};
$.ajax(
{
type: "POST", //HTTP POST Method
url: "/Video/Index", // Controller/View
data: JSON.stringify({ viewModel: model })
async: false,
processData: false,
contentType: false,
dataType: 'json'
}).success(function (json) {
$("#proever").html(json.responseText);
});
})
})

Ajax to MVC controller. Not passing parameters unless Ajax followed by alert

I have the strangest situation. I have two ajax POST. First I had problems passing the parameters to the controller but at some point I got them trough and with some debugging I figured out that I only get all of the values to the controller if my ajax definition is followed by an alert.
One of them:
$.ajax({
type: 'POST',
url: '/Contact/IntresseAnmälan/',
dataType: 'json',
data: {
Namn: $('#namn').val(),
Mail: $('#mail').val(),
Info: $('#meddelande').val(),
Telefon: $('#nr').val(),
IsEnkel: false,
PassId: function () {
var url = window.location.pathname;
var id = url.substring(url.lastIndexOf('/') + 1);
return id;
},
Participanter: getParticipant(),
ParticipantMail: getParticipantMail()
},
traditional: true,
success: function (result) {
// window.location.href = '#Url.Action("IntresseAnmälan", "Contact")';
}
});
alert("Hur sparas dina uppgifter?");
Here are my Getters for name and mail. The form-elements(input type mail and text) theese are dynamicly added to the form if the user wants clicks a button two inputs are added. Then theese functions returns an array with the inputed values from the form.
function getParticipant() {
var p = [];
for (var i = 1; i <= participantCount; i++) {
var name = '#anNamn' + i;
p[i -1] = $(name).val()
}
return p;
}
function getParticipantMail() {
var p = [];
for (var i = 1; i <= participantCount; i++) {
p[i -1] = $('#anMail' + i).val();
}
return p;
}
And here is my controller. I've removed the body in the controller. It saves to the Db and send a verification mail to the admin.
[HttpPost]
public ActionResult IntresseAnmälan(BokningContainer bokning)
{
//Saves to Db and Send a verification mail to admin
}
If I exclude the alert after the ajax some parameters are passed, I think it's Namn and Mail, but most of them not passed. I'm quite puzzled.
Also, is ajax the only way to pass an object to a controller from jQuery?
Also, is ajax the only way to pass an object to a controller from
jQuery?
No, you can use a regular HTML Form to submit your data, you just have to conform to the expected object in the controller Action (should be decorated with HttpPostAttribute) - There is a Model-Binding process which attempting to bind the Request data to your domain object.
You don't need to pass every field's value using jQuery. Instead you can create a form whose data you want to post like :
<form id="frmTest">
... add input types here
</form>
and you can pass data of form using $('#frmTest').serialize() method to the controller
$.ajax({
type: "POST",
data: $('#frmTest').serialize(),
url: "url",
dataType: "json",
success: function (data) { alert('worked!'); },
error: function (data) {
alert('error');
}
});

Ajax not returning Partial View

I reallly have a simple set of code to bring back a set of data that is triggered off a drop down.
this is the script:
function () {
$('#ProviderID').change(function () {
$.ajax({
url: '/servicesDisplay/Index',
type: 'Get',
data: { id: $(this).attr('value') },
success: function (result) {
// The AJAX request succeeded and the result variable
// will contain the partial HTML returned by the action
// we inject it into the div:
$('#serLocations').html(result);
}
});
});
This is the controller:
public ActionResult Index(string id)
{
int prid = Int32.Parse(id.Substring(0, (id.Length-1)));
string mulitval = id.Substring((id.Length-1), 1).ToString();
System.Data.Objects.ObjectResult<getProviderServiceAddress_Result> proList = theEntities.getProviderServiceAddress(prid);
List<getProviderServiceAddress_Result> objList = proList.ToList();
SelectList providerList = new SelectList(objList, "AddressID","Address1");
//ViewBag.providerList = providerList;
return PartialView("servicesDisplay/Index", providerList);
}
This is the view:
#model OCS_CS.Models.servicesDisplay
<div>
#Html.DropDownList(model => model.ServiceAdderssID, (IEnumerable<SelectListItem>)model)
</div>
When the drop down passes the in the value. The apps does hit the controller. But it highlightes the drop down in a light red and the view never displays.
Try this short version which uses the jquery load method.
$(function(){
$('#ProviderID').change(function () {
$('#serLocations').load("#Url.Action("Index","ServicesDisplay")?id="
+$(this).val());
});
});
If you want to avoid caching of result, you may send a unique timestamp along with the querystring to avoid caching.
$('#serLocations').load("#Url.Action("Index","ServicesDisplay")?id="
+$(this).val()+"&t="+$.now());
You are doing a GET, thats no meaning to pass data to ajax, you may pass data for POST:
First, put the value at the URL:
function () {
$('#ProviderID').change(function () {
$.ajax({
url: '/servicesDisplay/Index/' + $(this).attr('value'),
type: 'Get',
success: function (result) {
// The AJAX request succeeded and the result variable
// will contain the partial HTML returned by the action
// we inject it into the div:
$('#serLocations').html(result);
}
});
});
Second, mark the method as GET
[HttpGet]
public ActionResult Index(string id)
Hopes this help you!
You have quite a few problems with your code. First the model defined for your view is:
#model OCS_CS.Models.servicesDisplay
but in your action your're invoking the call to this view by passing in a SelectList:
SelectList providerList = new SelectList(objList, "AddressID","Address1");
return PartialView("servicesDisplay/Index", providerList);
this is not going to fly because the models do not match by type. Seconds problem is you are casting this SelectList into an IEnumerable. This is also not going to work. You need to cast to SelectList:
#Html.DropDownList(model => model.ServiceAdderssID, (SelectList)model)
but again until you match the type of your model in your action with the model on your view none of this will work. I suggest you install Fiddler to help you determine what sort of error are you getting.

ASP.NET MVC: passing a complex viewmodel to controller

firs of all i searched for my question but couldnt find anything that helped me get any further.
i am trying to implement a view which allows me to set permissions for the current user.
As the data-structure i use following recursive class where each PermissionTree-Object references the sub-permissions (permissions are hierarchically structured in my application) :
public class PermissionTree
{
public Permission Node; //the permission object contains a field of type SqlHierarchyId if that is relevant
public bool HasPermission;
public IList<PermissionTree> Children;
//i cut out the constructors to keep it short ...
}
here is how the controller looks like:
//this is called to open the view
public ActionResult Permissions()
{
//pass the root element which contains all permission elements as children (recursion)
PermissionTree permissionTree = PopulateTree();//the fully populated permission-tree
return View(permissionTree);
}
//this is called when i submit the form
[HttpPost]
public ActionResult Permissions(PermissionTree model)
{
SetPermissions(model);
ViewData["PermissionsSaved"] = true;
return View(model);//return RedirectToAction("Index");
}
in am using a strongly typed view like this:
#model PermissionTree
//....
#using (Html.BeginForm("Permissions", "Permission", null, FormMethod.Post, new { #class = "stdform stdform2" }))
{
<input name="save" title="save2" class="k-button" type="submit" />
<div class="treeview">
//i am using the telerik kendoUI treeview
#(Html.Kendo().TreeView()
.Name("Permissions")
.Animation(true)
.ExpandAll(true)
.Checkboxes(checkboxes => checkboxes
.CheckChildren(true)
)
.BindTo(Model, mapping => mapping
.For<PermissionTree>(binding => binding
.Children(c => c.Children)
.ItemDataBound( (item, c) => {
item.Text = c.Node.PermissionName;
item.Checked = c.HasPermission;
})
)
)
)
ok, so when i click the button, i want my viewmodel to be sent to the controller action that is decorated with [HttpPost]. But when i debug the application, the received model does not really contain my data (it is not null though).
Does anyone know how i can achieve my goal and get the whole viewmodel?
best regards,
r3try
I think it's better to use a JSON post here ,then it's easy to prepare the object in the javascript side.
I don't know how your HTML looks like or the names of the elements you can easyly use javascript/Jquery to build the client side json object with similar names and slimier hierarchy/dataTypes just like in the PermissionTree class. And then use Ajax post to post as JSON
var PermissionTree={Node:{},HasPermission:false,Children:{}}
$.ajax({ data:PermissionTree
type: "POST",
url: 'YourController/Permissions',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
}
);
The important thing is you need to find a better way of going throuth the tree view and build the object in javascript.
as i cant get that to work i was trying a slightly different approach:
example for adding a node:
- press add button -> execute ajax call -> add the node in nhibernate -> call the view again with the new data (the new node included)
controller-action that is called by the ajax request:
[Authorize]
[HttpPost]
public ActionResult AddPermission(string parentPermissionName, string permissionName)
{
var pd = ServiceContext.PermissionService.permissionDao;
Permission parentPermission = pd.GetPermissionByName(parentPermissionName);
if (parentPermission == null) {
parentPermission = pd.GetRoot();
}
if (parentPermission != null && !string.IsNullOrEmpty(permissionName) && !pd.PermissionExists(permissionName))//only add with a name
{
pd.AddPermission(parentPermission, permissionName);
}
//refresh data
PermissionTree permissionTree = LoadTreeSQLHierarchy(null, false);//start at root
return View("Permissions", permissionTree);
}
Ajax Request in the View:
function addNode() {
//... get the data here
var addData = { parentPermissionName: selectedNodeName, permissionName: newNodeName };
$.ajax(
{
data: addData,
type: "POST",
url: '#Url.Action("AddPermission", "Permission")',
dataType: "json",
success: function (result) {
//$('.centercontent').html(response);//load to main div (?)
return false;
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status + ":" + thrownError);
return false;
}
}
);
return false;
}
But when i execute this i get an error stating that json.parse hit an invalid character (i get this error at the alert in the ajax's error function).
Judging from that message i would say that the problem is that i am returning html but the ajax call expects json or so...
But what is the correct way to just reload my view with the new data? Can i somehow tell the ajax call to not go back at all and just execute the called controller-method?

How to pass a list of selected objects from javascript in an action in MVC?

I have a large data table that contains a checkbox for each row. I need to either pass all items that are selected as either a comma delimited list, or better yet a strongly typed IList to the controller. What is the best way to accomplish this? I know I can pass a string with no issue, but how do I get which checkboxes are selected?
Here's what the static code looks like:
#using (#Html.BeginForm("RemoveItems", "ResultList", new { IDList = "1,2,3,4" }, FormMethod.Post))
{
<input type="submit" value="Remove Items" name="RemoveItems" />
}
You can do it like this using jQuery.
$.ajax({
url: "/MyAction/Array",
data: JSON.stringify({ model: input }),
type: "POST",
contentType: "application/json"
});
Here "input" is your array, "model" - name of action parameter.
Make sure you've specified contentType as application/json.
I have had a site maybe similar to your.
I had a table with checkboxes at each row.
What i did was:
var firstPriorityArray = new Array();
$("Input:checkbox[name=FirstPriority]:checked").each(function () {
firstPriorityArray[firstPriorityArray.length] = $(this).val();
console.log(fp.toString());
});
The console.log is only to be able to see what happend and how it looks :)
Afterwards i used JSON.Stringify() and a object and sent it back to another ASPX site with AJAX like this:
var o = new Object();
o.primary = firstPriorityArray;
var json = JSON.stringify(o);
$.ajax({
url: 'getMeAJAX.aspx',
type: 'POST',
data: "json=" + json,
success: function (response) {
//On success
},
error: function (xhr, ajaxoptions, thrownError) {
alert(thrownError);
}
});
Maybe you can use this or be inspired. I cant say if this is the "perfect" and most "MVC" way to do it, but it works ;)
//Gerner

Categories

Resources