I have ajax function like this to run on HTML select list
$.ajax({
type: "POST",
url: urlemp,
success: function (returndata) {
if (returndata.ok) {
// var data = eval("" + returndata.data + "");
select.empty();
select.append($('<option>' + "" + '</option>'));
$.each(returndata.data, function (rec) {
select.append($('<option>' + returndata.data[rec].Name + '</option>'));
});
select.show('slow');
select.change();
}
else {
window.alert(' error : ' + returndata.message);
}
}
}
);
and this is the HTML element
<select id="cmbDept"></select>
How can i get the value of the selected item in the controller using MVC 3 ?
you have 4 ways to do that
1. the you can bind ti the change event of the select $(select).change(function(){}) and send an ajax request again wrapping the selected value which you will be able to get in the controller
2. you can keep a hidden input in your view binded to a property in the view's model now bind to the change of the select and fill the input with the value this way whenever your form is posted back it will have the values properly binded to the model
3. #Don saved me from writing the third way so read his ans.
4. if you have a model that this view is binded to then simple keep a property in the model with the name cmbDept and selected value would be automatically posted back
Us FormCollection as parameter in your controller. And assign name to the select
<select id="cmbDept" name="cmbDept"></select>
Now the FormCollection has this posted value.
public ActionResult Index(FormCollection form)
{
string val = "";
foreach (var key in form.AllKeys)
{
if (key.Contains("cmbDept"))
{
val = form.Get(key);
}
}
--your code here with the posted values
return View();
}
To get the value of the select element on the client, just use $("#cmbDept").val().
To get the value of the element once it's submitted to the server, add a name="cmbDept" to your select and simply create a parameter named cmbDept in the controller action your $.ajax call is is posting to.
Related
I created this sample locally
http://demos.telerik.com/kendo-ui/mvvm/remote-binding
In my 'update' transport, I did modify the 'ProductName' from my WebAPI
public IHttpActionResult Update(Product prod)
{
prod.Price = prod.UnitPrice * prod.Quantity;
prod.ProductName = prod.ProductName + DateTime.Now.ToString();
return Ok(prod);
}
It did update and reflect on my 'dropdownlist'.
The issue is the textbox id=products is not showing the latest productname. The textbox is binded using
data-bind="value: selectedProduct.ProductName"
How can I refresh this text box ?
Thank you.
All is same except this
update: {
url: "/Product/Update",
contentType: "application/json",
type: "POST"
},
and this.
parameterMap: function (data, type) {
return kendo.stringify(data);
}
If these changes are not made; my webapi will not receive any value.
I notice like the binding somehow got broken momentarily; is it because its indirectly reference using the var 'selectedProduct' ?
The reason, I believe, that your textbox is not updating is because of two reasons: 1) you're changing the data on the server instead of the client, and 2) the textbox is tied to the selectedProduct variable which is in no way tied to the data source.
In other words, when you submit the update, because your dropdown list is bound to the productSource data source, it's data gets updated automatically and the list is refreshed to show you the changes. This is expected. On the other hand, selectedProduct is not tied to the data source in any way, so, it still holds the old value before the update was called.
The solution is you have to manually update selectedProduct after the update request returns.
Self explanatory question.
Between posts, the grid I have setup is retaining the HasSelection bit, even if the WebGrid has been re-loaded with new data. Therefore, the functionality I have wired into the physical selection of a WebGrid record runs, even though the user hasn't selected anything on the new resultset yet.
Thoughts?
WebGrid obtains the selected row thru the query string. by default, the query string field is row like http://localhost/grid?row=2
Ideally, you would remove that query string field before posting back like so http://localhost/grid
If it is not possible, set WebGrid.SelectedIndex to -1 instead.
Edit
Here are few ways to set WebGrid.SelectedIndex:
#{
WebGrid grid = new WebGrid(Model);
grid.SelectedIndex = ViewBag.SelectedIndex;
#grid.GetHtml(
columns: grid.Columns(
...
)
)
}
public ActionResult Index(int? row)
{
ViewBag.SelectedIndex = (IsKeepSelection() ? row.GetValueOrDefault() : 0) - 1; //TODO: add bound checking
return View(People.GetPeople());
}
Or (I prefer the previous one though since it's easier to understand):
#{
WebGrid grid = new WebGrid(Model);
if(ViewBag.ClearSelection) {
grid.SelectedIndex = -1;
}
#grid.GetHtml(
columns: grid.Columns(
...
)
)
}
public ActionResult Index(int? row)
{
ViewBag.ClearSelection = IsClearSelection();
return View(People.GetPeople());
}
The ultimate answer to this issue was to clear out the "action" on the form. Apparently, the WebGrid is tightly coupled to this value and therefore the makers of the WebGrid expected you to futz with the action attribute instead of the WebGrid itself.
I simply reset the querystring with document.forms[0].action = window.location.pathname; in my submission button. Since the form's action resolves to the querystring, this fixed it.
I have some jQuery that I'm using to open a pop-up window where a new consignor can be added to the database. The original window has a dropdownlist of all of the current consignors. When you add the new consignor in the pop-up window, that window closes and the original window then reloads the dropdownlist's data and selects the one just created.
All of that works perfectly. My issue is that when you fill out the rest of the form and submit it, it passes an empty string instead of the value of the selected item. Is this because it's an ASP.Net script? I don't know a lot about ASP.Net, but I've never had this issue with PHP. Can someone explain how I would go about refreshing the dropdownlist without refreshing the entire page and still get the list to pass it's value upon form submission?
My javascript code on the page that opens the pop-up and reloads the list is below:
function openConsignorAdd() {
var url;
url = "/admin/consignor/csAdd.aspx";
window.open(url, "WizardWindow", "width=400,height=500,resizable=yes,scrollbars=yes");
}
function loadNewAdded(fn, cs_txt_id) {
// var pagePath = window.location.pathname;
var pagePath = "/admin/getNewList.asp";
var paramList = "data=";
//Call the page method
$.ajax({
type: "POST",
url: pagePath + "?type=" + fn + "&cs_txt_id=" + cs_txt_id,
data: paramList,
success: function (data) {
//create jquery object from the response html
var $response = $(data);
//query the jq object for the values
var results = $response.filter('select#results').html();
if (fn == "consignor") {
$("select#<%=itemConsigner.ClientID%>").html(results);
} else if (fn == "cdr") {
$("select#<%=itemCDR.ClientID%>").html(results);
}
},
error: function () {
alert("Failed To Refresh!\n\nYou must manually refresh the page.");
}
});
}
My javascript code on the pop-up page to refresh the list is:
function refreshOpener(cs_txt_id) {
window.opener.loadNewAdded("consignor", cs_txt_id);
}
Those both work. And to get the value of my dropdownlist, I simply use:
if (itemConsigner.SelectedValue.ToString() != string.Empty)
{
itemCsTxtId = itemConsigner.SelectedValue.ToString();
}
with my dropdownlist being:
<asp:DropDownList ID="itemConsigner" runat="server" TabIndex="1"></asp:DropDownList>
If you need more info, just let me know. Any help is appreciated.
It seems that the issue is that since I am making the change after the page loads, the server does not see my new addition as one of the original options so ignores it completely. This is good so that people cannot just edit your forms I guess. So what I did was instead of getting the value of itemConsigner.SelectedValue, I grab the value for Request.Form["itemConsigner"] with the long ID. That way it doesn't validate that my submitted option was an original option.
Might be a silly observation but without all the code I'm not sure if this is the case. Are you just updating the original list with the id in the select options. The value needs to be populated as well for each. That could be why you are getting an empty value on after form submission.
i have an scenario where i have to perform some action according to selection of the
dropdown .
for basic refrence you can use the example of country,state,city.
i am able to populate the country list at that time i have set the other two drop downs to
disable.
after the countries are populated i want to select the state.it is getting populated .
two problems
1) how to retain the state of country ddl as it is coming back to its orisnal state.
2) how to enable the drop down through my controller.
myview code
Country
<p>
<label>
State</label>
<%=Html.DropDownList("ddlState", ViewData["ddlState"] as SelectList, "--not selected--",new { onchange = "document.forms[0].submit()", disabled = "disabled" })%>
</p>
<p>
<label>
City</label>
<%=Html.DropDownList("ddlCities", ViewData["ddlCities"] as SelectList, "--not selected--", new { onchange = "document.forms[0].submit()", disabled = "disabled" })%>
</p>
my controller code
public ActionResult InsertData()
{
var customers = from c in objDetailEntity.Country
select new
{
c.Cid,
c.Cname
};
SelectList countriesList = new SelectList(customers.Take(100), "Cid", "Cname");
ViewData["ddlCountries"] = countriesList;
SelectList EmptyState = new SelectList(customers);
ViewData["ddlState"] = EmptyState;
ViewData["ddlCities"] = EmptyState;
Session["ddlSesCountry"] = countriesList;
return View();
}
//
// POST: /RegisTest/Create
[HttpPost]
public ActionResult InsertData(FormCollection collection)
{
try
{
CountryId = Convert.ToInt16(Request.Form["ddlCountries"]);
stateid = Convert.ToInt16(Request.Form["ddlState"]);
if (CountryId > 0 && stateid <= 0)
{
var stateslist = from c in objDetailEntity.State
where c.Country.Cid == CountryId
select new
{
c.Sid,
c.Sname
};
SelectList stateList = new SelectList(stateslist.Take(100), "Sid", "Sname");
ViewData["ddlState"] = stateList;
Session["StateList"] = stateList;
ViewData["ddlCities"] = stateList;
}
if (stateid > 0)
{
var citieslist = from c in objDetailEntity.City
where c.State.Sid == stateid
select new
{
c.Ctid,
c.Cityname
};
SelectList cityList = new SelectList(citieslist.Take(100), "Ctid", "Cityname");
ViewData["ddlCities"] = cityList;
ViewData["ddlState"] = Session["StateList"];
}
ViewData["ddlCountries"] = Session["ddlSesCountry"];
return View();
}
catch
{
return View();
}
}
My choice would be not to post back the form at all. I would write an action in the controller that takes a CountryID and returns a JsonResult holding a list of states. The onchange event could call a jQuery function that uses AJAX to call this action, loads the new list, and enables the second drop-down list.
However, if you stick with the postback, here's why it's not working:
The Country list isn't retaining its selected value because the view is being reloaded from scratch each time and you're setting it to "not selected." The SelectList constructor has an overload that takes a "SelectedItem" object as the fourth parameter. When you initialize your SelectList, you should pass the appropriate value to this parameter, and not force it in the View.
You need to write an "if" clause in your View to choose whether or not to enable the list based on some criteria. You could bind to a ViewModel that has a Boolean property like "EnableStates," or you could use something like the count of values in the StateList - if the count is greater than zero, enable it, for example.
A tricky thing to get used to when you move from Web Forms to MVC is that you don't have ViewState anymore - your application is stateless. There's nothing that "remembers" what value is selected in a drop-down for you, you have to set it each time you load the page.
I recommend using JSON & jQuery - like this posted answer.
I'm trying to redirect to another page by calling an action in controller with a specific parameter. I'm trying to use this line:
window.open('<%= Url.Action("Report", "Survey",
new { id = ' + selectedRow + ' } ) %>');
But I couldn't make it work; it gives the following error:
CS1012: Too many characters in character literal.
Can't I generate the action URL this was on the client side? Or do I have to make an Ajax call by supplying the parameter and get back the needed URL? This doesn't seem right, but I want to if it's the only way.
Is there an easier solution?
Remember that everything between <% and %> is interpreted as C# code, so what you're actually doing is trying to evaluate the following line of C#:
Url.Action("Report", "Survey", new { id = ' + selectedRow + ' } )
C# thinks the single-quotes are surrounding a character literal, hence the error message you're getting (character literals can only contain a single character in C#)
Perhaps you could generate the URL once in your page script - somewhere in your page HEAD, do this:
var actionUrl =
'<%= Url.Action("Report", "Survey", new { id = "PLACEHOLDER" } ) %>';
That'll give you a Javascript string containing the URL you need, but with PLACEHOLDER instead of the number. Then set up your click handlers as:
window.open(actionUrl.replace('PLACEHOLDER', selectedRow));
i.e. when the handler runs, you find the PLACEHOLDER value in your pre-calculated URL, and replace it with the selected row.
I usually declare a javascript variable in the section to hold the root of my website.
<%="<script type=\"text/javascript\">var rootPath = '"
+ Url.Content("~/") + "';</script>" %>
To solve your problem I would simply do
window.open(rootPath + "report/survey/" + selectedRow);
Could you do
window.open('/report/survey/' + selectedRow);
instead where selected row I assume is the id? The routing should pick this up fine.
or use getJSON
Perhaps you could use JSONResult instead. Wherever the window.open should be call a method instead i.e. OpenSurveyWindow(id);
then add some jquery similar to below
function OpenSurveyWindow(id){
$.getJSON("/report/survey/" + id, null, function(data) {
window.open(data);
});
}
now in your controller
public JsonResult Survey(int id)
{
return Json(GetMyUrlMethod(id));
}
That code isnt syntactically perfect but something along those lines should work
Just if someone is still looking for this. The controller action can have normal parameters or a model object with these fields. MVC will bind the valus automatically.
var url = '#Url.Action("Action", "Controller")';
$.post(url, {
YearId: $("#YearId").val(),
LeaveTypeId: $("#LeaveTypeId").val()
}, function (data) {
//Do what u like with result
});
You wont be able to do this, the URL.Action is a server side process so will parse before the clientside selectedRow is available. Israfel has the answer I would suggest.
If selectedRow is a client-side variable, it won't work. You have to use #Israfel implementation to link. This is because the server-side runs before the client-side variable even exists.
If selectedRow is a server-side variable within the view, change to this:
window.open('<%= Url.Action("Report", "Survey", new { id = selectedRow } ) %>');
This is because the id will infer the selectedRow variable type, or you could convert to string with ToString() method (as long as it's not null).
A way to do this that might be considered cleaner involves using the T4MVC T4 templates. You could then write the JavaScript inside your view like this:
var reportUrl = '<%= Url.JavaScriptReplacableUrl(MVC.Survey.Report())%>';
reportUrl = myUrl.replace('{' + MVC.Survey.ReportParams.id + '}', selectedRow);
window.open(reportUrl);
The advantage of this is that you get compile-time checking for the controller, action, and action parameter.
One more thing that can be done, no so clean i guess:
var url = "#Url.RouteUrl(new { area = string.Empty, controller = "Survey", action = "Report" })";
var fullUrl = url + '?id=' + selectedRow;
The easiest way is to declare a javascript variable than concate your parameter value to the link.
var url = '#Url.Action("Action","Controller")' + "/" + yourjavascriptvariable;
<a href='" + url + "'>