Paging/Sorting not working on web grid used in Partial View - asp.net-mvc-3

I have a partial view where I am showing a web grid depending upon a value selected from a page.
For drop down I have used
#Html.DropDownListFor(
x => x.ItemId,
new SelectList(Model.Items, "Value", "Text"),
new {
id = "myddl",
data_url = Url.Action("Foo", "SomeController")
}
)
For drop down item select I have used
$(function() {
$('#myddl').change(function() {
var url = $(this).data('url');
var value = $(this).val();
$('#result').load(url, { value: value })
});
});
and below is my action
public ActionResult Foo(string value)
{
SomeModel model = ...
return PartialView(model);
}
everything works good, but when I try doing a paging or sorting on my webgrid which is on my partial view I am showing a new window with the web grid.
I wanted to be able to sort and page on the same page without postback
Please help

The following example works fine for me.
Model:
public class MyViewModel
{
public string Bar { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Foo(string value)
{
var model = Enumerable.Range(1, 45).Select(x => new MyViewModel
{
Bar = "bar " + value + " " + x
});
return PartialView(model);
}
}
Index.cshtml view:
<script type="text/javascript">
$(function () {
$('#myddl').change(function () {
var url = $(this).data('url');
var value = $(this).val();
$.ajax({
url: url,
type: 'GET',
cache: false,
data: { value: value },
success: function (result) {
$('#result').html(result);
}
});
});
});
</script>
#Html.DropDownList(
"id",
new[] {
new SelectListItem { Value = "val1", Text = "value 1" },
new SelectListItem { Value = "val2", Text = "value 2" },
new SelectListItem { Value = "val3", Text = "value 3" },
},
new {
id = "myddl",
data_url = Url.Action("Foo", "Home")
}
)
<div id="result">
#Html.Action("Foo")
</div>
Foo.cshtml partial:
#model IEnumerable<MyViewModel>
#{
var grid = new WebGrid(
canPage: true,
rowsPerPage: 10,
canSort: true,
ajaxUpdateContainerId: "grid"
);
grid.Bind(Model, rowCount: Model.Count());
grid.Pager(WebGridPagerModes.All);
}
#grid.GetHtml(
htmlAttributes: new { id = "grid" },
columns: grid.Columns(
grid.Column("Bar")
)
)
Notice that I have used a GET request to refresh the grid instead of POST because this way the value query string parameter selected in the dropdown is preserved for future sorting and paging.

Related

Pushing array to select in knockout gives just one option

I am using MVC and a Razor View I'm trying to bound data received from a controller to a select using a knockout model, If I try to push directly the dynamic array I get only one option like this one
Only one option select:
I'm sure that I'm missing something stupid, I have already tried to return a new SelectList and using optionsText and optionsValue but didn't do the work.
I'm sure the knockout model is correct because if I write
viewModel.dliveryDates.push("option1","option2");
it works as expected
Here's my controller code that reads some data from database and send it back to the view
[HttpPost]
public JsonResult GetDeliveryDates(string code)
{
OrderHeaderPageModel instance = ObjectFactory.Create<OrderHeaderPageModel>();
instance.DeliveryDateRanges = PopulateDeliveryDateRanges(code);
return Json(instance.DeliveryDateRanges.ToArray());
}
Here's is my View code
#Html.DropDownList("deliveryranges", new SelectList(string.Empty, "Code", "Description"), "- Seleziona -", new { #data_bind = "options:dliveryDates" })
And finally my knockout model
function OrderHeaderViewModel() {
var self = this;
self.save = function () {
return true;
}
self.dliveryDates = ko.observableArray([]);
}
var viewModel = new OrderHeaderViewModel();
ko.applyBindings(viewModel, el);
$("#ordertypes").change(function () {
var postUrl = "/checkout/getdeliverydates";
$("#deliveryranges").empty();
$.post(postUrl,
{
code: $("#ordertypes").val(),
__RequestVerificationToken: Sana.Utils.getAntiForgeryToken()
}, function (data) {
var arry = [];
var array = $.map(data, function (value, index) {
return [value];
});
$.each(data, function (i, data) {
arry.push(data.Code);
});
viewModel.dliveryDates.push(arry);
}
);
})
It looks like the code is doing some extra work mapping data that is not used in the ajax callback. Hope the following code helps.
function OrderHeaderViewModel() {
var self = this;
self.getData = function() {
//function to simulate filling the array from the server.
var data = ["Item 1", "Item 2", "Item 3", "Item 4"];
self.dliveryDates(data);
var mappedData = data.map(function(item, index) {
return {
id: index,
description: item
};
});
viewModel.mappedDliveryDates(mappedData);
}
self.save = function() {
return true;
}
//added to put the selected values in
self.selectedValue = ko.observable();
self.selectedMappedValue = ko.observable();
self.mappedDliveryDates = ko.observableArray([]);
self.dliveryDates = ko.observableArray([]);
}
var viewModel = new OrderHeaderViewModel();
ko.applyBindings(viewModel);
$("#ordertypes").change(function() {
var postUrl = "/checkout/getdeliverydates";
$("#deliveryranges").empty();
$.post(postUrl, {
code: $("#ordertypes").val(),
__RequestVerificationToken: Sana.Utils.getAntiForgeryToken()
}, function(data) {
// if the data needs to be transformed and is already an array then you can use
var mappedData = data.map(function(item, index) {
return {
id: index,
description: item
};
});
// If the data is already in the format that you need then just put it into the observable array;
viewModel.mappedDliveryDates(mappedData);
viewModel.dliveryDates(data);
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
Server Data Values -
<select data-bind="options: dliveryDates, value:selectedValue, optionCaption: 'Choose...'"></select>
<br/> Mapped Values -
<select data-bind="options: mappedDliveryDates, optionsText:'description', value: selectedMappedValue, optionCaption: 'Choose...'"></select>
<br/>
<button data-bind="click: getData">Load Data</button>
<br/>
<br/>
<pre data-bind="text: ko.toJSON($root)"></pre>

How to get selected Drop down list value in view part of MVC?

I want to pass selected Drop down list value to Ajax Action Link which is I am using in Controller. Every time When I will change drop down list value. I want that respective value pass to the action link.
What I need to write here in Ajax Action Link ????
Drop Down List
<div class="form-group">
#Html.DropDownListFor(model => model.ComponentId, ((List<string>)ViewBag.Cdll).Select(model => new SelectListItem { Text = model, Value = model }), " -----Select Id----- ", new { onchange = "Action(this.value);", #class = "form-control" })
</div>
Ajax Action Link
<div data-toggle="collapse">
#Ajax.ActionLink("Accessory List", "_AccessoryList", new { ComponentId = ???? }, new AjaxOptions()
{
HttpMethod = "GET",
UpdateTargetId = "divacc",
InsertionMode = InsertionMode.Replace
})
</div>
Controller
public PartialViewResult _AccessoryList(string ComponentId)
{
List<ComponentModule> li = new List<ComponentModule>();
// Code
return PartialView("_AccessoryList", li);
}
Here is a new post. I do dropdowns a little different than you, so I am showing you how I do it. When you ask what to pass, I am showing you how to pass the dropdown for 'component' being passed. I also show how to pass from ajax back to the page.
Controller/Model:
//You can put this in a model folder
public class ViewModel
{
public ViewModel()
{
ComponentList = new List<SelectListItem>();
SelectListItem sli = new SelectListItem { Text = "component1", Value = "1" };
SelectListItem sli2 = new SelectListItem { Text = "component2", Value = "2" };
ComponentList.Add(sli);
ComponentList.Add(sli2);
}
public List<SelectListItem> ComponentList { get; set; }
public int ComponentId { get; set; }
}
public class PassDDLView
{
public string ddlValue { get; set; }
}
public class HomeController : Controller
{
[HttpPost]
public ActionResult PostDDL(PassDDLView passDDLView)
{
//put a breakpoint here to see the ddl value in passDDLView
ViewModel vm = new ViewModel();
return Json(new
{
Component = "AComponent"
}
, #"application/json");
}
public ActionResult IndexValid8()
{
ViewModel vm = new ViewModel();
return View(vm);
}
View:
#model Testy20161006.Controllers.ViewModel
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>IndexValid8</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#btnClick").click(function () {
var PassDDLView = { ddlValue: $("#passThis").val() };
$.ajax({
url: '#Url.Action("PostDDL")',
type: 'POST',
data: PassDDLView,
success: function (result) {
alert(result.Component);
},
error: function (result) {
alert('Error');
}
});
})
})
</script>
</head>
<body>
<div class="form-group">
#Html.DropDownListFor(m => m.ComponentId,
new SelectList(Model.ComponentList, "Value", "Text"), new { id = "passThis" })
<input type="button" id="btnClick" value="submitToAjax" />
</div>
</body>
</html>

Selecting Enum items on AJAX call

I am working on action result which returns JSON data to view and then loads on textFields by AJAX call
Action:
public ActionResult loadInf(string custm)
{
int smclientbranchid = Convert.ToInt32(Session["smclientbranchid"]);
var query = (from parent in db.Customer
join child in db.CustomerAddress on parent.CustomerId equals child.CustomerId
where parent.SMClientBranchId == smclientbranchid && parent.NIC == custm
select new SalesVM
{
Indicator = parent.Indicator,
//code removed
}).ToList();
return Json(query);
}
In View:
#Html.DropDownListFor(model => model.Indicator,
new SelectList(Enum.GetValues(typeof(ColorTypes))),
"<Select>",
new { #class = "form-control", id ="Indicator" })
<script type="text/javascript">
$(document).ready(function () {
$("#btnSearchCus").click(function () {
var custm = $('#custm').val();
$.ajax({
cashe: 'false',
type: "POST",
data: { "custm": custm },
url: '#Url.Action("LoadCustomerInfo", "Sales")',
dataType: 'json', // add this line
"success": function (data) {
if (data != null) {
var vdata = data;
$("#Indicator").val(vdata[0].Indicator);
//code removed
}
}
});
});
});
</script>
I am getting data right and also loading right except the "Indicator" field, which is of type enum.
How can I select an enum list item from the data I get.
For example:
0,1,2,3 index order
You need to be setting the Value attributes against all of the option values for the select list.
Use the following for your dropdown box to select by the text representation of the value:
#Html.DropDownListFor(model => model.Indicator, Enum.GetValues(typeof(ColorTypes)).Cast<ColorTypes>().Select(x => new SelectListItem { Text = x.ToString(), Value = x.ToString() }), new { #class = "form-control", id = "Indicator" })
Or use the following for it to select by the integer value:
#Html.DropDownListFor(model => model.Indicator, Enum.GetValues(typeof(ColorTypes)).Cast<ColorTypes>().Select(x => new SelectListItem { Text = x.ToString(), Value = ((int)x).ToString() }), new { #class = "form-control", id = "Indicator" })
This will allow your .Val() jQuery code to select the correct one.
If you retrieving string variable nm (0,1,2,3...) - would be better to change the type to int and try cast your integer variable to Enum type that you have.
public ActionResult loadInf(int nm)
{
ColorTypes enumValue = (ColorTypes) nm;
.......
You can take a look about details to this article: http://www.jarloo.com/convert-an-int-or-string-to-an-enum/

how to use cascading dropdownlist in mvc

am using asp.net mvc3, i have 2 tables in that i want to get data from dropdown based on this another dropdown has to perform.for example if i select country it has to show states belonging to that country,am using the following code in the controller.
ViewBag.country= new SelectList(db.country, "ID", "Name", "--Select--");
ViewBag.state= new SelectList("", "stateID", "Name");
#Html.DropDownListFor(model => model.Country, (IEnumerable<SelectListItem>)ViewBag.country, "-Select-")
#Html.DropDownListFor(model => model.state, (IEnumerable<SelectListItem>)ViewBag.state, "-Select-")
but by using this am able to get only the countries.
There is a good jQuery plugin that can help with this...
You don't want to refresh the whole page everytime someone changes the country drop down - an ajax call to simply update the state drop down is far more user-friendly.
Jquery Ajax is the best Option for these kind of questions.
Script Code Is Given below
<script type="text/javascript">
$(function() {
$("##Html.FieldIdFor(model => model.Country)").change(function() {
var selectedItem = $(this).val();
var ddlStates = $("##Html.FieldIdFor(model => model.state)");
$.ajax({
cache:false,
type: "GET",
url: "#(Url.Action("GetStatesByCountryId", "Country"))",
data: "countryId=" ,
success: function (data) {
ddlStates.html('');
$.each(data, function(id, option) {
ddlStates.append($('<option></option>').val(option.id).html(option.name));//Append all states to state dropdown through returned result
});
statesProgress.hide();
},
error:function (xhr, ajaxOptions, thrownError){
alert('Failed to retrieve states.');
statesProgress.hide();
}
});
});
});
</script>
Controller:
public ActionResult GetStatesByCountryId(string countryId)
{
// This action method gets called via an ajax request
if (String.IsNullOrEmpty(countryId))
throw new ArgumentNullException("countryId");
var country = GetCountryById(Convert.ToInt32(countryId));
var states = country != null ? GetStatesByConutryId(country.Id).ToList() : new List<StateProvince>();//Get all states by countryid
var result = (from s in states
select new { id = s.Id, name = s.Name }).ToList();
return Json(result, JsonRequestBehavior.AllowGet);
}
Try this,
<script type="text/javascript">
$(document).ready(function () {
$("#Country").change(function () {
var Id = $("#Country").val();
$.ajax({
url: '#Url.Action("GetCustomerNameWithId", "Test")',
type: "Post",
data: { Country: Id },
success: function (listItems) {
var STSelectBox = jQuery('#state');
STSelectBox.empty();
if (listItems.length > 0) {
for (var i = 0; i < listItems.length; i++) {
if (i == 0) {
STSelectBox.append('<option value="' + i + '">--Select--</option>');
}
STSelectBox.append('<option value="' + listItems[i].Value + '">' + listItems[i].Text + '</option>');
}
}
else {
for (var i = 0; i < listItems.length; i++) {
STSelectBox.append('<option value="' + listItems[i].Value + '">' + listItems[i].Text + '</option>');
}
}
}
});
});
});
</script>
View
#Html.DropDownList("Country", (SelectList)ViewBag.country, "--Select--")
#Html.DropDownList("state", new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text"), "-- Select --")
Controller
public JsonResult GetCustomerNameWithId(string Country)
{
int _Country = 0;
int.TryParse(Country, out _Country);
var listItems = GetCustomerNameId(_Country).Select(s => new SelectListItem { Value = s.CountryID.ToString(), Text = s.CountryName }).ToList<SelectListItem>();
return Json(listItems, JsonRequestBehavior.AllowGet);
}

cascade dropdownlist asp.net

i've two table in DB.
i want to create dropdownlist for city and corresponding area after that.this is my first cascade drodown menu in my entire life.i've tried to follow some examples.in the get action i've :
ViewBag.cities = db.cities.ToList();
ViewBag.areas = db.areas.ToList();
in the view i've:
<div class="editor-field">
#Html.DropDownListFor(model => model.city,new SelectList(ViewBag.cities as
System.Collections.IEnumerable, "city_id", "name"),
"Select City", new { id = "ddlCars" })
#Html.ValidationMessageFor(model => model.city)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.area)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.area, new
SelectList(Enumerable.Empty<SelectListItem>(), "area_id", "name"),
"Select Area", new { id = "ddlModels" })
#Html.ValidationMessageFor(model => model.area)
</div>
i've just copied a js file from a site that is
$(document).ready(function () {
$("#ddlCars").change(function () {
var idModel = $(this).val();
$.getJSON("/Post/LoadAreasByCity", { id: idModel },
function (carData) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Select Area"
}));
$.each(carData, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
$("#ddlModels").change(function () {
var idColour = $(this).val();
$.getJSON("/Home/LoadColoursByModel", { id: idColour },
function (modelData) {
var select = $("#ddlColours");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Select a Colour"
}));
$.each(modelData, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});
in my Post/LoadAreasByCity my method is:
public JsonResult LoadAreasByCity(string id)
{
PostManager pm = new PostManager();
if ( id=="") { id = "1"; }
int c_id =(int) Convert.ToInt32(id);
var areaList = pm.GetModels(c_id);
var modelData = areaList.Select(m => new SelectListItem()
{
Text = m.name,
Value = m.area_id.ToString(),
});
return Json(modelData, JsonRequestBehavior.AllowGet);
}
it propagate cities and area is correctly in the view page.but after submitting the data it gives errorin this line
#Html.DropDownListFor(model => model.city,new SelectList(ViewBag.cities as
System.Collections.IEnumerable, "city_id", "name"),"Select City", new { id =
"ddlCars" })
it says Value cannot be null.
Parameter name: items
Finally in my post action
int c_id = Convert.ToInt32(p.city);
int a_id = Convert.ToInt32(p.area);
area a = db.areas.Single(x=>x.area_id == a_id);
city c = db.cities.Single(s => s.city_id == c_id);
post.city = c.name;
post.area = a.name;
....Save to DB
what is the problem in this ..... thanks in advance
I suspect that in your POST action you have redisplayed the same view but forgot to populate the ViewBag.cities and ViewBag.areas items as you did in your GET action:
[HttpPost]
Public ActionResult Process()
{
... Save to DB
ViewBag.cities = db.cities.ToList();
ViewBag.areas = db.areas.ToList();
return View();
}

Resources