Getting html select value on postback - asp.net

I'm having a bit of trouble here, hoping someone can help:
I am dynamically populating an html select element in a razor script and onChange I am hoping to get this posted value.
It is posting back as the page is refreshing but I don't seem to be getting the value of the select; The reason I know is that I am passing a category and filtering on it. This filtering works when I change the querystring in the URL manually and post it.
Razor Script:
#using umbraco.MacroEngines
#inherits DynamicNodeContext
#{
dynamic rootNode = #Model.NodeById(1066);
DynamicNodeList list = rootNode.Descendants();
List<dynamic> categories = new List<dynamic>(list.Cast<dynamic>());
List<string> alias = new List<string> { "GeneralPage" };
var filtered = categories.Where(n => alias.Contains(n.NodeTypeAlias));
}
<form method="post" action="">
<select id="selectCategory" name="selectCategory" onchange="this.form.submit(); alertMe(selectCategory)">
#foreach (var node in filtered)
{
<option value="#node.Name">#node.Name</option>
}
</select>
</form>
<script type="text/javascript">
function alertMe(selectCategory) {
alert(selectCategory)
}
</script>
You'll notice I have a function to alert the selected value but this is coming back as [object HTMLSelectElement]
I can post more code if needed to show what's happening on the server, but as I said the filtering DOES work, however I am trying capture the value in the following way:
string category = Request["selectCategory"];
if (category != null)
{
Any help much appreciated.
Thanks

Try:
ViewContext.RouteData.Values["selectCategory"]
As for the javascript, you are passing in the dom reference to the select list, not the selected item. If you want to see the value of it, you need to use
alert(selectCategory.value)

Related

Create variable in view and assign

I need to create a string variable in my View and assign to a hidden input which is bound to a property on my strongly typed model
I guess it is something like
#Html.HiddenFor(m=>m.nodelist, new {#value = myVar})
however not working
Don't try to be setting the #value attribute on the html helper. That's not how those helpers have been designed to work. They have been designed to bind to the value of the corresponding property on the view model you passed to this view.
So it's as simple as:
#Html.HiddenFor(m => m.nodelist)
and in the controller action rendering this view you would assign the corresponding property on the view model to the desired value:
public ActionResult Index()
{
MyViewModel model = ...
model.nodelist = someVariable;
return View(model);
}
If on the other hand this variable is actually a javascript variable then you should obviously use javascript to assign it to the hidden field:
<script type="text/javascript">
var myVar = 'some value';
$('#nodelist').val(myVar);
</script>
or if you are not using jQuery:
<script type="text/javascript">
var myVar = 'some value';
document.getElementById('nodelist').value = myVar;
</script>
use simple html hidden field and keep it's name same as property name.
This works perfectly
#{
string val=myVar;
}
<input type="hidden" name="nodelist" value="#val" />
Is myVar a javascript variable?
You could assign your hidden field an ID property.
#Html.HiddenFor(m=>m.nodelist, new {#id = "hdnNodeList"})
and using javascript or jquery you could do the following
$('#hdnNodeList').val(myVar);
or if myVar is a C# variable you could try the following (this will render an html output, although you could do it here, its better to assign a value to m.nodelist in your controller if possible)
$('#hdnNodeList').val('#myVar');

How to get last selectedindex

I need to get the last selected value from a dropdown control. But I get wrong information.
I need this kind of control to allow users to select every option they want. But I've to validate every option they select after getting the selectedvalue.
I've deployed an ASP.NET dropdown control in a webform. It's databinded in server side, and the resulting hmtl is the following:
<select name="ddl" id="ddl" multiple="multiple" data-native-menu="false">
<option value=""></option>
<option value="1">1800346</option>
<option value="2">1800353</option>
<option value="3">1800358</option>
<option value="4">1800509</option>
<option value="5">1800514</option>
</select>
And this is my jQuery code: It alerts the selectedIndex and the selected text.
$("#ddl").on("change", function () {
alert($("#ddl")[0].selectedIndex);
alert($("#ddl option:selected").text());
});
With alert($("#ddl")[0].selectedIndex) I get the first selected index. For example, if you click on the first checkbox, you'll get "1" the first time. After that, if you click on the third checkbox you'll get "1" again (instead of "3"). Because the first option is selected.
I also tried with alert($("#ddl option:selected").text()) but I get everything.
Is there any way to get only the last selected value? I'm only able to get the first selected index.
You can find my code also here: http://jsfiddle.net/bDvkQ/342/
Any help will be very welcome,
Regards,
Check for this code
$("#ddl").on("change", function () {
var lastText = "";
var last = 0;
$("#ddl option:selected").each(function () {
lastText = this.text;
last = this.value;
});
alert(lastText);
alert(last);
});
and you can find from this link to http://jsfiddle.net/bDvkQ/344/
I think it wasn't clear for you.
When you click on the ddl, it will choose the selected value. Just return it.
Do something like this:
$("#ddl").on("change", function () {
alert($("#ddl").val());
alert($("#ddl option:selected").text());
});
It works well for me.
Hope this helped.
Here is how we can select the last selected value (and first one),
$("#ddl").on("change", function () {
var selValues = $("#ddl").val();
alert(selValues[0]);
alert(selValues[selValues.length - 1]);
});
However, if user starts selecting values in the reverse direction (from bottom), you will not get the last selected/clicked value but you will always get the selected value that comes last in the dropdown.
I would suggest to create another function/handler that gets all the selected values and validates them one by one rather than doing validation on every single click/selection of this multi select control.

knockoutjs creating new model from input elements?

jsFiddle: http://jsfiddle.net/Piercy/mD4kG/
So I have recently started working with knockout.js. I have started to get my head around it but am struggling with the following scenario.
I have the following model and view model structure:
function ViewModel() {
var self = this;
self.Emails = ko.observableArray([]);
self.AddEmail = function() {
// make ajax call here
self.Emails.push(new EmailModel(data));
};
}
function EmailModel(data) {
this.Id = data.Id;
this.Name = data.Name;
this.Subject = ko.observable(data.Subject);
this.DisplayId = ko.observable(data.DisplayId);
}
I want the ViewModel.Emails array to be an array of EmailModel's and my problem is how to create a new model to insert.
I imagine something like this:
<select data-bind="options: Emaillistdata, optionsText: 'Name', optionsValue: 'Id', optionsCaption: 'Choose...', value: DisplayId"></select><br /><br />
<input type="text" data-bind="value: Name"/><br />
<input type="text" data-bind="value: Subject"/><br />
<button data-bind="click: AddEmail">Add Email</button>
However, doing this would mean the the Name,Subject and DisplayId bindings would need to be in the ViewModel (which they are not). Also, it seems odd that I would have to add these to the ViewModel. I am kind of expecting to able to click the button and have a data variable that i can just do data.Name, data.Subject and data.DisplayId and have these variables not bound to any model, they are just submitted because i've named them as such or something? Then i can add them to the array and make them part of the ViewModel.
I could do all this with standard JS and then add it to the model but that also seems odd when everything else is using knockout. However maybe this is the answer?
jsFiddle: http://jsfiddle.net/Piercy/mD4kG/
Without knowing what you are trying to achieve from a UX point of view im not sure what your trying to achieve.
Have you looked at this ko tutorial. It shows you how to structure your code to be able to add new items
http://learn.knockoutjs.com/#/?tutorial=collections

Ajax.BeginForm using ASP.NET MVC 3 - Nothing Happens

All I need to do is create a simple search page that displays results in a partial view. I have a search text box and a search submit button. I followed a tutorial I found online that seems very easy and quick to implement, but I am missing something here. When I click the search button nothing happens. Any ideas on what I am doing wrong or missing would be greatly appreciated.
I include the following script files in the main layout page
#Script("jquery-1.5.1.min.js")
#Script("modernizr-1.7.min.js")
#Script("jquery-ui.min.js")
#Script("jquery.unobtrusive-ajax.js")
#Script("jquery.validate.min.js")
#Script("jquery.validate.unobtrusive.min.js")
#helper Script(string scriptName)
{
<script src="#Url.Content("~/Scripts/" + scriptName)" type="text/javascript"> </script>
}
The main search view is called AdminMenu. This is listed under a Area in my project called Admin.
The following code in my main view
#using (Ajax.BeginForm("AdminSearch", "AdminMenu", new {area = "Admin"}, new AjaxOptions { HttpMethod = "GET", InsertionMode = InsertionMode.Replace, UpdateTargetId = "searchResults"}))
{
<input type="text" name="q" />
<input type="submit" value="Search"/>
}
<div id="searchResults">
</div>
Code in my partial view _adminSearch
<div id="searchResults">
<div class="entitybox">
#{
var grid = new WebGrid(
Model,
defaultSort: "Name", canPage: false
);
}
#grid.GetHtml(
tableStyle: "_tableGrid",
columns: grid.Columns
(
grid.Column("Name", "Name", item => #Html.ActionLink((string)item.Name, "SelectRecord", new { controller = "Menu", agencyKey = item.Id, name = item.Name }))
)
)
</div>
</div>
Code for the Controller
public class AdminMenuController : Controller
{
public ActionResult AdminMenu()
{
return View();
}
public PartialViewResult AdminSearch(string q)
{
Records results = AgencyBusiness.GetAdminSearch(q);
return PartialView("_adminSearch", results);
}
}
When the search button is clicked nothing happens. If you put a break point on the AdminSearch method in the controller class it never gets hit.
Thanks in advance for your time.
I think the problem is that you have a div called "searchResults" in both your main view and partial view. Ajax is probably getting confused.
You need to include the MicrosoftAjax.js file when using Ajax.BeginForm.
I solved this issue. Odd thing. I used a shared view to show the current user at the top of the view using the following line.
#RenderPage("~/Views/Shared/_LoginBar.cshtml")
The main problem was that #Ajax.BeginForm function did not output any form tags to the browser.
By using the following line instead, the form tags appeared in the HTML source and the ajax function worked.
#Html.Partial("~/Views/Shared/_LoginBar.cshtml")

MVC3 webgrid filtering advice?

I'm trying to figure out the best way (minimal effort) to apply filtering to a webgrid that I have displayed in my Main/Index view (MVC3).
I added a multiselet that would allow filtering by a certain column and I would like to catch the click event (which I already have implemented and working) per select item and then somehow re-invoke my Index() method that contains all the code to rebuild the view based on if it was invoked from a filter (multiselect).
What is the best way to go about this? I know that this is a broad ask but any information would be greatly appreciated.
Thanks!
You could place the multiselect inside a form. Then you have 2 possibilities to submit this form:
Using a submit button
Using the onchange event of the multiselect (in this case you will have to use javascript)
The first point is straightforward:
#using (Html.BeginForm())
{
#Html.ListBoxFor(x => x.SelectedItems, Model.Items)
<button type="submit">Filter</button>
}
To implement the second you could use jQuery and subscribe to the change event of the multiselect. First, let's give this multiselect an id so that we can more easily select it:
#using (Html.BeginForm())
{
#Html.ListBoxFor(x => x.SelectedItems, Model.Items, new { id = "filter" })
}
and then in a separate javascript file:
$(function() {
$('#filter').change(function() {
// when the selection changes we manually trigger the submission
// of the containing form
$(this).closest('form').submit();
});
});
In both cases the controller action that we are submitting to will take an array of strings as argument which will represent the selected values in the multiselect which will be used to filter the resultset.

Resources