I am getting value in a dropdown list and I wanted to get the selected value in controller when user select any value from the dropdown list. My view is -
#using (Html.BeginForm("ApReport", "Sales", FormMethod.Post))
{
#Html.DropDownList("Ddl", null, "All", new { #class = "control-label"})
#Html.Hidden("rddl")
}
controller -
[HttpPost]
public ActionResult ApReport(ApReport Ddl)
{
string Ddlvalue = string.Empty;
if (Request.Form["rddl"] != null)
{
Ddlvalue = Request.Form["rddl"].ToString();
}
}
but I am not getting any value. Also, I donot want to use any submit button.
Thanks in advance
The use of Ajax allows you as the developer to update the main view without reloading the entire page, as well as send data to the server in the background.
This is how I would have accomplished this task.
Firstly, I would have created an action in my controller which returns a JsonResult. This will return a JSON object to your calling jquery code, that you can use to get values back into your views. Here is an example of the action method.
[HttpGet]
public JsonResult YourActionName(string selectedValue) //Assuming key in your dropdown is string
{
var result = DoYourCalculation(selectedValue);
return Json(new { myResult = result }, JsonRequestBehavior.AllowGet);
}
Now, you need to add your jquery code. I would recommend you place this in a seperate javascript file referenced by your view.
Here is the JQuery code, with the ajax call to the Action in your controller. The Ajax call to the server is initiated by the 'change' event of your DropDown, handled in JQuery, as can be seen below.
$(function () {
$(document)
.on('change', '#Ddl', function(){
var valueofDropDown = $(this).val();
var url = '/YourControllerName/YourActionName';
var dataToSend = { selectedValue: valueofDropDown }
$.ajax({
url: url,
data: dataToSend,
type: 'GET',
success: function (dataReceived) {
//update control on View
var receivedValue = dataReceived.myResult ;
$('YourControlIDToUpdate').val(receivedValue);
}
})
});
};
Related
I am trying to mimic an mvc ActionLink. I want the whole row to be clickable. when the actionlink is clicked, it calls the connected controller and executes the code within. I want my Jquery/ajax call to do the same.
I've tried multiple ways of doing this with no luck. I'm currently at a point where the row is clickable and the Jquery sees that, however the ajax call does not execute. Or, if it does, the controller does not execute correctly
Here is the Jquery code that catches the click.
$(document).ready(function () {
$('#policyTable').on('click', '.clickable-row', function (event) {
$(this).addClass('primary').siblings().removeClass('primary');
var Id = $(this).closest('tr').children('td:first').text();
var url = "/Home/ReviewPolicy";
var uc = $(this).closest('tr').children('td:first').text();
alert("Does the click work? " + Id);
$.ajax({
type: "POST",
url: "/Home/ReviewPolicy",
dataType: 'text',
data: { Id: Id }
});
})
})
Here is the controller it is calling:
[HttpPost]
public ActionResult ReviewPolicy(string Id)
{
//Declare policyVM for individual policy
PolicyRenewalListVM model;
int val = Convert.ToInt32(Id);
using (Db db = new Db())
{
//Get the row
PolicyRenewalListDTO dto = db.RenewalPolicies.Find(val);
//confirm policy exists
if (dto == null)
{
return Content("This policy cannot be found.");
}
//initialize the PolicyRenewalListVM
model = new PolicyRenewalListVM(dto);
}
//return view with model
return View(model);
}
When the actionlink itself is clicked (It's not here in the code as I didn't see it being necessary for this problem) it fires and everything works as it should, but the jquery call, sending the very same value (Id) does not.
How to pass jQuery variable value to c# mvc ?
I need to fetch the value of the variable btn in mvc code behind.
$('button').click(function () {
var btn = $(this).attr('id');
alert(btn);
$.ajax({
type: 'GET',
url: '#Url.Action("ActionName", "ControllerName")',
data: { id: btn },
success: function (result) {
// do something
}
});
});
Based on the variable value (Submit Button (or) Preview Button), my model will have Required validation on certain fields.
In my controller , i am calling as
[HttpGet]
public ActionResult ActionName(string id)
{
var vm = id;
return View(vm);
}
Though , ActionResult in controller is not invoked.
Jquery : alert(btn); -- is calling. I can see the alert window showing with the id. However, I am not able to retrieve the id in the controller.
You need to use jQuery.ajax() (or its shortened form jQuery.get()/jQuery.post()) with GET/POST method and set up a controller action with an argument to pass button ID:
jQuery (inside $(document).ready())
$('button').click(function () {
var btn = $(this).attr('id');
var url = '#Url.Action("ActionName", "ControllerName")';
var data = { id: btn };
// if controller method marked as POST, you need to use '$.post()'
$.get(url, data, function (result) {
// do something
if (result.status == "success") {
window.location = '#Url.Action("AnotherAction", "AnotherController")';
}
});
});
Controller action
[HttpGet]
public ActionResult ActionName(string id)
{
// do something
return Json(new { status = "success", buttonID = id }, JsonRequestBehavior.AllowGet);
}
[HttpGet]
public ActionResult AnotherAction()
{
// do something
return View(model);
}
If you want to pass retrieved button ID from AJAX into other action method, you can utilize TempData or Session to do that.
It is a nice coincidence that you use the word "fetch" to describe what you want to do.
jQuery runs in the browser as a frontend framework. Meaning that it runs on the client`s computer. Your MVC-C#-Code lies on the server. Therefore, if you want to send data between those two computers, you need to use the http protocol.
1. Ajax and REST:
Using an ajax call using http methods (post or put) to push your variable value as JSON to the backend`s REST api (route).
For this option, you might want to have a look at the fetch function of javascript.
2. HTML Forms
Use a html form where you store the variable value inside one input element. A form submission will perform a http post (by default) request to the backend as well and use all input element values as post parameters.
There are many ways to accomplish what you are looking to do, but I'll stick to using your code sample.
So what you need to do is utilize the .ajax call in jquery to send data from your view to your controller. More on that here: http://api.jquery.com/jquery.ajax/
Using your code, you'd put the .ajax call within your logic flow of what to do based on which button is clicked.
$("button").click(function ()
{
var btn = this.id;
if (btn == "previewButton")
{
$.ajax({
url: "/MyApp/MyAction",
type: "POST",
data: { btnId: btn },
dataType: "json",
async: true,
cache: false
}).success(function(data){
// do something here to validate if your handling worked
}).error(function(){
// Do something here if it doesnt work
});
}
}
You'll see that there is a URL. In my example i've chose MyApp as my controller and MyAction as the method of the controller in which we are posting values to. The ajax call posts 1 parameter with a property of btnId. If you need to pass more data, the property name in the jquery call should correspond with an argument of the actions method signature within the controller.
So my controller looks like
public MyAppController : Controller
{
[HttpPost]
public JsonResult MyAction(string btnId)
{
Debug.WriteLine("btnId: {0}", btnId);
return Json(new{ ButtonId= btnId });
}
}
This would be one way to handle passing values from your view to your controller using .ajax calls with jquery.
My preferred way is to use the Html helpers of Ajax.BeginForm which could be another option for you.
https://www.aspsnippets.com/Articles/ASPNet-MVC-AjaxBeginForm-Tutorial-with-example.aspx
Currently on the I have some inline javascript, which makes an ajax call to a partial view controller which should have updated the viewbag along with it. However this does not seem to be the case, the data seems to persist from the main view which is null because it was never set there and if it was set then the data would still persist(tested).
Here is my javascript ajax call.
$.ajax({
url: btn.data('action-url'),
data: {
id: btn.data('id')
},
type: 'GET',
success: function (data) {
//delete all panels before showing new ones
$('.panel.panel-default').remove();
//push the new panels into the view
//$('#dash-content').html(data);
//Construct the partial view to be input into the main view
//Checks to see if browser supports templates
if ('content' in document.createElement('template')) {
var widgetModel = #Html.Raw(Json.Encode(ViewBag.widgets));
for (var i = 0; i < widgetModel.length; i++) {
var clone = loadwidgets(widgetModel[i]); //This function is in an external js file
var inputDestination = document.querySelector('#col2');
inputDestination.appendChild(clone);
console.log(inputDestination);
}
}
and here is the Action that it is calling.
public ActionResult Dashboard(int? id)
{
ModelState.Clear();
//get all widgets associated dashboard
var getWidgetsQuery = (from widgets in db.widgets
where widgets.DashID == id
select widgets);
ViewBag.widgets = getWidgetsQuery.ToList();
return PartialView();
}
Add an action to return the data i.e.
public ActionResult DashboardJson(int? id)
{
//get all widgets associated dashboard
var getWidgetsQuery = (from widgets in db.widgets
where widgets.DashID == id
select widgets);
var widgets = getWidgetsQuery;
return Json(widgets, JsonRequestBehavior.AllowGet);
}
Declare and serialize your model above the json call as you have done:
var widgetModel = #Html.Raw(Json.Encode(ViewBag.widgets));
Then within your success call simply re-assign it to the returned data:
widgetModel = data;
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.
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?