I am developing MVC application and I am using razor syntax.
I am trying to get the selected item from dropdown list value and to pass it to the controller method.
but I am getting error.
The name 'd' does not exist in the current context
The Updated Code is...
$("#btnForword").click(function(){
d = $('#HODList').val()
alert(d);
var url2 = "#Html.Raw(Url.Action("SendPaymentAdviceForApproval", "PaymentAdvice", new { paymentAdviceId = "idValue" , nHOD = "##D##" }))"
url2 = url2.replace("idValue",'#Model.Id');
url2 = url2.replace("##D##",d);
$.ajax({
url: url2, type: "POST", success: function (data) {
$("#btnForword").css("display","none");
}
});
return false;
});
Issue solved Issue solved
The problem in variable 'D' yes in "D".
I checked using inspect element property of Google chrome, when I saw it in console window....
When I click on the button , I can see the string formed in below way
ht...../PaymentAdvice/SendPaymentAdviceForApproval?paymentAdviceId=304&nHO8=D
jquery-1.7.1.min.js:4
see the last character in the above link, it should not be come as a "=D" isnt it ?
I used the below code...and it works perfectly.
$("#btnForword").click(function(){
var url2 = "#Html.Raw(Url.Action("SendPaymentAdviceForApproval", "PaymentAdvice", new { paymentAdviceId = "idValue" , nHOD = "HODId" }))";
url2 = url2.replace("idValue",'#Model.Id');
url2 = url2.replace("HODId",$('#HODList').val());
$.ajax({
url: url2, type: "POST", success: function (data) {
$("#btnForword").css("display","none");
}
});
return false;
});
Is this a bug in Jquery ?
You should use data property of $.ajax to pass parameter to controller-action.
$("#btnForword").click(function(){
var d = document.getElementById("HODList").value;
// define url
var url2 = 'Url.Action("SendPaymentAdviceForApproval", "PaymentAdvice")';
//url2 = url2.replace("idValue",'#Model.Id');
//url2 = url2.replace("d",'#d');
$.ajax({
url: url2,
type: "POST",
// add parameters in here...
data: { paymentAdviceId : #Model.Id, nHOD : d }
success: function (data) {
$("#btnForword").css("display","none");
}
});
return false;
});
And your controller should looks:
public ActionResult SendPaymentAdviceForApproval(int paymentAdviceId, int nHOD){...}
Try this
$(function(){
$("#btnForword").click(function(){
var d = $('#HODList').val();
var url2 = "#Html.Raw(Url.Action("SendPaymentAdviceForApproval", "PaymentAdvice", new { paymentAdviceId = "idValue" , nHOD = "##D##" }))";
url2 = url2.replace("idValue",'#Model.Id');
url2 = url2.replace("##D##",d);
$.ajax({
url: url2, type: "POST", success: function (data) {
$("#btnForword").css("display","none");
}
});
return false;
});
});
don't consider replacing "d" as it will affect your other part of url as well.. Try specific placeholder instead.
If this not works... Then can you please show Signature of your Action method too?
Your controller action should be like this
[HttpPost]
public JsonResult SendPaymentAdviceForApproval(int paymentAdviceId, int nHOD)
{
// Your existing logic here...
}
Cheers
Related
I'm working with mvc4 and knockout trying to understand all the cool stuff you can to with it.
the thing is, i have this code which loads info and sends it to the view.
public ActionResult AdministraContenidoAlumno()
{
Alumno NuevoAlumno = new Alumno();
NuevoAlumno.AlumnoId = 1;
NuevoAlumno.NombreCompleto = "Luis Antonio Vega Herrera";
NuevoAlumno.PlanEstudioActual = new PlanEstudio
{
PlanEstudioId = 1,
NombrePlan = "Ingenieria en sistemas",
ListaMateriasPlan = new List<Materias> {
new Materias{MateriaId=1,NombreMateria="ingenieria 1"},new Materias{MateriaId=2,NombreMateria="Ingenieria 2"}
}
};
return View(NuevoAlumno);
Basically, create a new object alumno, who contains a PlanEstudio, who contains a list of Materias, then send it to the view.
In the view i have this.
#model MvcRCPG.Models.Alumno
#{
ViewBag.Title = "AdministraContenidoAlumno";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script>
var data;
$(function () {
var jsonModel = '#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model))';
var mvcModel = ko.mapping.fromJSON(jsonModel);
data = mvcModel;
ko.applyBindings(mvcModel);
});
function Guardar() {
$.ajax({
url: "/DemoKnockuot/GuardarAlumno",
type: "POST",
data: JSON.stringify({ 'NuevoAlumno': ko.toJS(data) }),
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data == "Success") {
alert('entro')
} else {
alert('trono')
}
},
error: function () {
alert("An error has occured!!!");
}
});
}
</script>
With the mentioned above functions i can read and send data to the server and do stuff on the controller, however i need to add remove or manipulate the information in the view.
So the question is: how do i add a function to 'mvcModel' in order to push a new "materia" in the ListaMateriasPlan object?
Thank you, and if you have more tips in order to understand it better i appreciate your help.
The mvcModel created by the mapping plugin will have observable properties.
For example, to add a new "materia" do something like:
function Materias() {
this.MateriaId = ko.observable();
this.NombreMateria = ko.observable();
}
var newItem = new Materias();
newItem.MateriaId(3);
newItem.NombreMateria("Ingenieria 3");
mvcModel.PlanEstudioActual.ListaMateriasPlan.push(newItem);
And normally, you would wrap the "adding" logic as a method in a view model.
I have a div block in my view like this:
<div id="divStatus" style="margin-top:10px;width: 200px; height: 100px; overflow-y: scroll;">
</div>
then from the view, user clicks on a button that calls the controller. In the controller some tasks are executed so from the controller I want to update a div block within the view. In this div I print out phrasses.
How to do this?
example:
public ActionResult()
{
// Do something
Update_DIV_in_View("some thing has been done"); <--- DIV in the view must be updated by appending this message
// Do another thing
Update_DIV_in_VIEW("another thing has been done");<--- DIV in the view must be updated by appending this message
.... and so on
// All things done
Update_DIV_in_VIEW("All things have been done");<--- DIV in the view must be updated by appending this message
return View();
}
Create a second action in your controller which only shows the updated content of the div and on your normal page when you press the button load the status with an AJAX call (for example the jQuery.load() method).
You can do it as follows:
In your view use Ajax Form as follows:
#using (Ajax.BeginForm("ActionName", "ControllerName", new AjaxOptions { OnBegin = "beforeSubmitFunction()", HttpMethod = "POST",UpdateTargetId = "divStatus", OnComplete = "InsertRow()" }))
{
.. //your Html form Controls
}
function beforeSubmitFunction()
{
//Your code for before submitting...
}
Then in your controller return your partial view as result which will get updated in your div with id divStatus
[HttpPost]
public ActionResult Index(TypeName model)
{
return PartialView("PartialViewName", model);
}
Here are 3 examples what I am using:
example 1:
button (here with telerik css styling):
<a class="t-button t-button-icontext" onclick="ajaxCreateEquipment()"><span
class="t-icon t-add"></span>Create</a>
javascript: #equipment-table-container is the id of the target div:
<script type="text/javascript">
function ajaxCreateEquipment() {
$.ajax({
type: 'GET',
url: '#Url.Action("ShowCreate", "Equipment")',
dataType: 'html',
success: function (data) {
$('#equipment-table-container').html(data);
}
});
}
</script>
EquipmentController.cs:
[HttpGet]
public ActionResult ShowCreate()
{
// some calculation code, fetch model from DB something else
ViewData.Add("FormAction", "Create"); // some ViewData
return PartialView("Create", model); // returns the View html file
}
example 2:
function call here with id argument and Json return:
#{
var supplierQuoteId = Model.ID.ToString();
<a id="#supplierQuoteId" onclick="updateDiv(this.id)"></a>
}
javascript:
function updateDiv(id) {
var strUrl = "/LicenseTerm/UpdateUsedQuantity/" + id;
$.ajax({
type: "GET",
url: strUrl,
cache: false,
dataType: "json",
success: function (data) {
$('#licenseterm-usedquantity').html(data.sum);
}
});
}
LicenseTermController.cs
[HttpGet]
public JsonResult UpdateUsedQuantity(Guid id)
{
var licenseTerm = _repository.GetAll<LicenseTerm>().Where(l => l.ID == id).First();
int sum = 0;
foreach (LicenseAllocation l in licenseTerm.LicenseAllocations.Where(o => o.Deleted == false))
sum = sum + l.LicenseQuantity;
return Json(new { sum = sum }, JsonRequestBehavior.AllowGet);
}
example 3: simple get
function ajaxFieldDefinitionCreate(id) {
var strUrl = '/FieldDefinition/Create' + '/' + id.toString() + '?isRefreshAction=true';
$.get(strUrl, function (data) {
$('#equipmenttype-fielddefinition-createeditarea').html(data);
});
}
[HttpGet]
public ActionResult Create(Guid id, [Optional, DefaultParameterValue(false)] bool isRefreshAction)
{
var equipmentType = _equipmentTypeRepository.GetById(id);
var fieldDefinitionDto = new FieldDefinitionDto
{
ID = Guid.NewGuid(),
ParentName = equipmentType.Name,
};
return PartialView("Create", fieldDefinitionDto);
}
In response to the changes of the question, especially that the questioner would like to have more returns in the same Action:
the concept of HTTP request is to transmit relatively small pieces of data from the server to the client, which invoked the e.g. HTTP GET request.
You can not keep open the HTTP GET request for more transmissions.
I searched the web and extracted that especially HTML5 will address this requirement with the HTTP stream, but this is another topic. e.g.: I got this url: http://socket.io/ .
Bypass:
But as an idea of mine,
I would make a first ajax call to determine the count of the next requests, addressed in the controller Action1.
And then invoke several new requests in the success part of the first ajax request, with the url of the Action2, e.g. Calculate etc., which appends then the several pieces of data to the div content.
here some quickly invented javascript code:
function updateDiv() {
var strUrl = "/Home/RequestCount/";
$.ajax({
type: "GET",
url: strUrl,
cache: false,
dataType: "json",
success: function (count) {
var strUrlCalc = "/Home/Calc/";
for (var i = 0; i < count; i++) {
$.ajax({
type: "GET",
url: strUrlCalc,
cache: false,
dataType: "json",
success: function (data) {
$('#test').append(data);
}
});
}
}
});
}
I have a table where in i have a column of check-box. After user selects a particular check-box, suppose from row 20, and perform necessary actions, i want to call the grid but it should point to the row i have selected check-box. But currently it is not happening. Instead of window.location, what can be other method? I hope you got my question. Please help. Thanks in advance! Following is my code-
function UpdateStatus(status, id, cb) {
var Status = status;
var Id = id;
var projectId = $("#projectId").val();
if ($("#" + status + id).is(':checked')) {
if (confirm("Are you sure?")) {
var data = { Status: Status, Id: Id, projectId: projectId };
$.ajax({
url: '#Url.Action("EditDispatchStatus", "BOM")',
type: 'GET',
data: data,
async: false,
success: function (data) {
window.location = '#Url.Action("DispatchStatus","BOM")?Id=' + data.result;
}
});
}
}
}
Firs things first you should remove the async: false option, because this is a blocking call, not an AJAX call and is very bad.
Now to your actual question. Here's how you could get the containing row:
function UpdateStatus(status, id, cb) {
var Status = status;
var Id = id;
var projectId = $("#projectId").val();
var $checkbox = $("#" + status + id);
if ($checkbox.is(':checked')) {
if (confirm("Are you sure?")) {
var data = { Status: Status, Id: Id, projectId: projectId };
$.ajax({
url: '#Url.Action("EditDispatchStatus", "BOM")',
type: 'GET',
data: data,
context: $checkbox.closest('tr'),
success: function (data) {
// this will point to the <tr> that was clicked
}
});
}
}
}
Notice how we are passing as context: $checkbox.closest('tr') to the success callback. So inside this callback this will point to the <tr> row that was clicked. You could use it in order to do something with it.
I am working on asp.net MVC 3 applciation. I have a jquery ui dialog. On Ok button of this dialog, I am opening another jquery ui dialogue. In order to populate the newly opened popup, I am using jquery ajax call which returns a collection. I am using this collection to create table rows. Code is here:
$("#Prices").dialog({
autoOpen: false,
autoResize: true, buttons: {
"OK": function () {
var PirceCurrencies = $('#PirceCurrencies').val();
jQuery("#hdCurrencyId").val(PirceCurrencies);
jQuery(this).dialog('close');
$.ajax({
type: "POST",
dataType: "json",
url: "/Home/GetRecordingRates",
data: { Id: $("#hdCurrencyId").val() },
success: function (data) {
$("#results").find("tr:gt(0)").remove();
var messages = data.Result;
$.each(messages, function(k, v) {
var row = $('<tr>');
row.append($('<td>').html(v.DialPrefix));
row.append($('<td>').html(v.Rate));
$('#results').append(row);
});
jQuery('#RecordingRates').dialog({ closeOnEscape: false });
$(".ui-dialog-titlebar").hide();
$("#RecordingRates").dialog({ dialogClass: 'transparent' });
$('#RecordingRates').dialog('open');
}
});
}
},
open: function () {
$('.ui-dialog-buttonset').find('button:contains("OK")').focus();
$('.ui-dialog-buttonset').find('button:contains("OK")').addClass('customokbutton');
}
});
and controller action is:
public JsonResult GetRecordingRates(int Id)
{
List<DefaultRateChart> defaultRateCharts = new List<DefaultRateChart>();
Currency currency = new Currency();
using (IDefaultRateChartManager defaultRateChartManager = new ManagerFactory().GetDefaultRateChartManager())
{
defaultRateCharts = defaultRateChartManager.GetAll().Where(rc => rc.Currency.Id == Id
&& (!rc.NumberPrefix.StartsWith("#") && !rc.NumberPrefix.Equals("Subscription")
&& !rc.NumberPrefix.Equals("Default")) && rc.AccountCredit == "Credit").ToList();
}
using (ICurrencyManager currencyManager = new ManagerFactory().GetCurrencyManager())
{
currency = currencyManager.GetById(Id);
ViewBag.currecycode = currency.CurrencyCode;
ViewBag.countrycode = currency.CountryCode;
}
return this.Json( new {
Result = ( from obj
in defaultRateCharts
select new {
Id = obj.Id,
DialPrefix = obj.NumberPrefix,
Rate = obj.PurchaseRates
}
)
}, JsonRequestBehavior.AllowGet);
}
All this works fine but I need to show some other data on newly opened popup other than the collection which populates/create html table rows. Fort that do I need to make another ajax call to another controller action which will return the data ?
Please suggest
Look at what you return now in your controller:
new {
Result = ( ... )
}
You are returning an object with 1 property named Result. In your javascript code you get that object returned named data and you retrieve the Result property as your list.
What stops you from adding more properties to that list?
new {
result = ( ... ),
currencyCode = currency.CurrencyCode,
countryCode = currency.CountryCode
}
In javascript you can then use data.currencyCode and data.countryCode
From Controller Action Method you can Return Dictionary like below.
Sample Code - C#
var dic = new List<KeyValuePair<short, object>>
{
new KeyValuePair<Int16, object>(1, SomeObj),
new KeyValuePair<Int16, object>(2, SomeObj),
new KeyValuePair<short, object>(3, SomeObj),
new KeyValuePair<Int16, object>(4, SomeObj)
};
return Json(dic, JsonRequestBehavior.AllowGet);
Sample Code - JQuery- Access Dictionary objects
var obj1; //Global Variables
var obj2; //Global Variables
var obj3; //Global Variables
var obj4; //Global Variables
$.ajax({
url: url,
async: true,
type: 'GET',
data: JSON.stringify({ Parameter: Value }),
beforeSend: function (xhr, opts) {
},
contentType: 'application/json; charset=utf-8',
complete: function () { },
success: function (data) {
DataSources(data);
}
});
function DataSources(dataSet) {
obj1 = dataSet[0].Value; //Access Object 1
obj2 = dataSet[1].Value; //Access Object 2
obj3 = dataSet[2].Value; //Access Object 3
obj4 = dataSet[3].Value; //Access Object 4
}
return a Dictionary from your controller.
convert your collection to string and other object to string and return
dictionary<int, string>
in your javascript sucess function,
JSON.parse(data[0].key) will give you your collection
This will give you an idea
bool inCart = false;
Cart MyCart = default(Cart);
Dictionary<string, string> Result = new Dictionary<string, string>();
Result.Add("inCart", inCart.ToString().ToLower());
Result.Add("cartText", MyCart.CartText());
string ResultString = new JavaScriptSerializer().Serialize(Result);
return ResultString;
Here I am adding two types to a dictionary and returning my serialized dictionary
I have the following where I'm trying to send list/array to MVC controller method:
var id = [];
var inStock = [];
$table.find('tbody>tr').each(function() {
id.push($(this).find('.id').text());
inStock.push($(this).find('.stocked').attr('checked'));
});
var params = {};
params.ids = id;
params.stocked = inStock;
$.getJSON('MyApp/UpdateStockList', params, function() {
alert('finished');
});
in my contoller:
public JsonResult UpdateStockList(int[] ids, bool[] stocked) { }
both paramaters are null.
Note that if I change the params to single items
params.ids = 1;
params.stocked = true;
public JsonResult UpdateStockList(int ids, bool stocked) { }
then it works ok, so I don't think it's a routing issue.
Try setting the traditional flag:
$.ajax({
url: '/home/UpdateStockList',
data: { ids: [1, 2, 3], stocked: [true, false] },
traditional: true,
success: function(result) {
alert(result.status);
}
});
works fine with:
public ActionResult UpdateStockList(int[] ids, bool[] stocked)
{
return Json(new { status = "OK" }, JsonRequestBehavior.AllowGet);
}
Besides calling .ajax() instead of .getJSON() as Darin suggests or setting the global jQuery.ajaxSettings.traditional to true as jrduncans suggests, you can also pass the result of calling the jQuery .param() function on your params object:
var id = [];
var inStock = [];
$table.find('tbody>tr').each(function() {
id.push($(this).find('.id').text());
inStock.push($(this).find('.stocked').attr('checked'));
});
var params = {};
params.ids = id;
params.stocked = inStock;
$.getJSON('MyApp/UpdateStockList', $.param(params, true), function() {
alert('finished');
});
Unfortunately, while it seems that jquery provides a "traditional" flag to toggle this behavior on jQuery.ajax, it does not on jQuery.getJSON. One way to get around this would to be set the flag globally:
jQuery.ajaxSettings.traditional = true;
See the documentation for jQuery.param: http://api.jquery.com/jQuery.param/
Also see the release notes for this change: http://jquery14.com/day-01/jquery-14 (search for 'traditional')
In the view, generate multiple named fields (not id, as id should be unique per field), noting the use of Name not name:
#foreach (var item in Model.SomeDictionary)
{
#Html.TextBoxFor(modelItem => item.Value.SomeString, new { Name = "someString[]" })
}
Then retrieve the input field values using jQuery, so:
var myArrayValues = $('input[name="someString[]"]').map(function () { return $(this).val(); }).get();
You can use this directly in jQuery / AJAX as follows:
$.ajax({
type: "POST",
url: "/MyController/MyAction",
dataType: 'json',
data: {
someStrings: $('input[name="someString[]"]').map(function () { return $(this).val(); }).get(),
someDates: $('input[name="someDate[]"]').map(function () { return $(this).val(); }).get(),
Then in the controller action in MVC:
[HttpPost]
public JsonResult MyAction(string[] someStrings, DateTime[] someDates...