I am working on an asp.net mvc web application. and i have a WebGrid, where i added a Page-size drop-down list to enable users to select how many records they like to have per page.
the Action method is:-
[OutputCache(CacheProfile = "NoCache")]
public ActionResult Disposed(string filter = null, int page = 1, int? pageSize = null, string sort = "Technology.Tag", string sortdir = "ASC")
{
GridList<DisposedResources> gridrecords = repository.GetDisposedResourcesForGrid(filter, page, pageSize, sort, sortdir, "rack");
ViewBag.PagedSizeOptions = new PageOptions().FilterOptions;
if (Request.IsAjaxRequest())
{
return PartialView("_disposed", gridrecords);
}
return View("Disposed", gridrecords);
}
and here is the repository method :-
public GridList<DisposedResources> GetDisposedResourcesForGrid(string filter, int page, int? pageSize, string sort, string sortdir, string resourcetype)
{
if (!pageSize.HasValue)
{
pageSize = Int32.Parse(System.Web.Configuration.WebConfigurationManager.AppSettings["TechPageSize"]);
}
var records = new GridList<DisposedResources>();
records.currentfilter = filter;
records.TotalRecords = GetDisposedResourcesForGridCount(filter, resourcetype);
records.hasNetworkInfo = false;
records.hasSystemInfo = false;
records.CurrentPage = page;
records.PageSize = pageSize.Value;
records.currentsort = sort;
records.currentsortdir = sortdir;
records.Content = tms.DisposedResources.Include(a=>a.Technology).Where(x => (filter == null ||
(x.Technology.Tag.ToLower().StartsWith(filter.ToLower()))
) && x.ResourceType.ToLower() == resourcetype.ToLower())
.OrderBy(sort + " " + sortdir)
.Skip((page - 1) * pageSize.Value)
.Take(pageSize.Value).ToList();
return records;
}
the Disposed view is :-
#model S.ViewModels.GridList<S.Models.DisposedResources>
Show #Html.DropDownList("FilterSize", new SelectList(ViewBag.PagedSizeOptions, "Value", "Text", ViewBag.pagesize ), new { #id= "FilterSize1",#class="SmallDropDown3"}) <span class="hidden-phone">per page.</span>
<div id="disposed">
#Html.Partial( "_disposed",Model)
</div>
#section Scripts {
<script type="text/javascript">
$("body").on('change', '#FilterSize1', function () {
//$(SizeProgressSort).show();
$.ajaxSetup({ cache: false });
$.ajax({
type: "Get",
url: '#Url.Action("Disposed")',
data: { pageSize: $('#FilterSize1').val(), page: "1", sort: $('#currentsort').val(), sortdir: $('#currentsortdir').val() },
success: successFunc,
error: errorFunc
});
function successFunc(data, status) {
$('#disposed').html(data);
}
function errorFunc() {
alert('error');
}
});
</script>
}
and the _disposed partial view is:-
#model S.ViewModels.GridList<S.Models.DisposedResources>
var gridcolumns = new List<WebGridColumn>();
gridcolumns.Add(new WebGridColumn()
{
ColumnName = "Technology.Tag",
Header = Html.DisplayNameFor(model => model.Content.FirstOrDefault().Technology.Tag).ToString(),
CanSort = true
});
//code goes here...
var grid = new WebGrid(
canPage: true,
rowsPerPage: Model.PageSize,
canSort: true,
ajaxUpdateContainerId: "grid");
grid.Bind(Model.Content, rowCount: Model.TotalRecords, autoSortAndPage: false);
grid.Pager(WebGridPagerModes.All);
#grid.GetHtml(htmlAttributes: new { id = "grid" }, // id for ajaxUpdateContainerId parameter
fillEmptyRows: false,
tableStyle: "table table-bordered table-hover",
mode: WebGridPagerModes.All,
columns: gridcolumns
);
}
</div></div></div>
<input type="hidden" value="#Model.currentsort" id="currentsort" /> #Model.currentsort
<input type="hidden" value="#Model.currentsortdir" id="currentsortdir" /> #Model.currentsortdir
the problem i am facing is that the two parameters; currentsort + currentsortdir which are being passed as part of the javascript will not be changed,and the user will loose the current sort order if he chose to chnage the page size drop down-list. so can anyone advice what is the problem, now even if i chose to display the two values:-
Model.currentsort
&
Model.currentsortdir
they will always have the defualt value, although these values are being changed inside the repository method... but seems the partial view is somehow caching the old values for these two parameter ?
The ModelState is probably overriding the values you changed in your model. Call ModelState.Clear() in your action method and you should see the changed values.
I know that you have done the cache setting through ajaxSetup but try putting cache:false inside your script and see if that makes a difference.
$.ajax({
cache: false
type: "Get",
url: '#Url.Action("Disposed")',
--------
Related
I am converting Kendo dropdownlist from the existing code into Kendo multiselect.
Role Code: Currently Dropdownlist (converting to Kendo multiselect).
I am not getting the correct output.
I have the following code:
<div class="col-md-4 form-group">
#Html.LabelFor(model => model.RoleCode, htmlAttributes: new { }) <span style="color: Red">*</span>
<select id="DDRolecode" multiple="multiple" data-placeholder="Select attendees...">
</select>
</div>
...
...
var url = '#Url.Action("GetRoleCode", "FlowGenerator")';
url = url + '?FlowID=' + flowid + '&RegID=' + RegId;
$.ajax({
url: url,
dataType: 'json',
type: 'POST',
success: function (result) {
debugger;
//$("#DDRolecode").kendoDropDownList({
// dataTextField: "Name",
// dataValueField: "ID",
// optionLabel: "Select",
// dataSource: result
//});
$("#DDRolecode").kendoMultiSelect({
dataTextField: "Name",
dataValueField: "ID",
dataSource: result,
});
var selectedData = [];
for (var i = 0; i < result.length; i++) {
selectedData.push({
text: result[i].Name,
value: result[i].ID
})
}
DDRoleCode.dataSource.data(selectedData);
//DDRoleCode.setDataSource(selectedData);
DDRoleCode.value('');
DDRoleCode.enable(true);
},
error: function (data) {
debugger;
var itemRow = "<ul id='listError'><li>" + "Data Not Bind" + "</li></ul>";
FUNMessageBox(itemRow, "E", 0, 0, "", "");
// alert("error");
}
});
The below is the controller code where I am getting the role codes:
public JsonResult GetRoleCode(int FlowID,int RegID)
{
IEnumerable<GenericValues1> RoleCode = _repository.Context.Database.SqlQuery<GenericValues1>("PROC_GET_ROLECODE #DATA_FLOW_ID={0},#REG_ID={1}", FlowID, RegID).ToList().AsQueryable();
// ViewBag.Tariffs = RoleCode;
return Json(RoleCode, JsonRequestBehavior.AllowGet);
}
As you can see, I tried using the multiselect functionality in the above code. But it didn't work.
To avoid the long comment chain.
From the second image you have provided it looks like the issue of multiple multiselects being added to the same item. This is due to you attaching a a new multiselect control to the same input.
this is a simple fix really.
There are two ways to fix it.
1) Destroy the kendo widget and recreate it
2) Assuming the same structure is used in the underlying datasource and other settings just apply the new datasource data to the widget.
Here is a dojo showing you both examples:
https://dojo.telerik.com/UxetijUy/2
Personally I would go with option 2 as it is a cleaner solution and avoids having to constantly destroy and recreate widgets.
So if you change the required person in the second example it will take a random number of people from the data array for the multiselect and then rebind those options to that control.
So that is all you would have to do with your ajax call is once you have the result just apply the new data to the datasource and then you don't need to keep recreating the widget as you are currently doing.
So in your example:
$("#DDRolecode").data('kendoMultiSelect').value(null);
$("#DDRolecode").data('kendoMultiSelect').dataSource.data(selectedData);
This ensures you have cleared off any selected items before you have attached the new data source.
If you need more info on what is happening. Please ask and I will update my answer accordingly.
The below code worked for me:
$(document).ready(function () {
debugger;
$("#DDRolecode").kendoMultiSelect({
dataTextField: "Name",
dataValueField: "ID",
});
....
....
//go to controller and call Sp and get the result
success: function (result) {
debugger;
var multiSelect = $('#DDRolecode').data("kendoMultiSelect");
multiSelect.value([]);
$("#DDRolecode").data("kendoMultiSelect").setDataSource(new kendo.data.DataSource({ data: result }));
var selectedData = [];
for (var i = 0; i < result.length; i++) {
selectedData.push({
Text: result[i].Name,
Value: result[i].ID
})
}
I am working on a C# Asp.Net web application, and I am trying to add the ability to dynamically add some select2 dropdowns on our project creation form.
So far, I've been able to add a single dropdown with a partial view, and get the results from it back to the controller using the viewmodel. I can also add additional dropdowns using jquery, and those dropdowns search correctly. But I'm having trouble getting the results from those additional inputs into the controller.
Methods I have tried:
Appending the partial ... tag instead of the select...
Changing the select asp-for="TeamMembers... to select asp-for="TeamMembers[0]... [1][2], ect.
Adding the #if... statement from the controller to the var html string
Escaping the # in the #if ... line
Partial View that successfuly works once
#model Waypoints.ViewModels.ProjectsCreateViewModel
<h5>Add Team Members</h5>
<div class="form-group" id="teamMembersAddDiv">
<select asp-for="TeamMembers" class="project-team-members-enabled form-control">
#if (null != Model && null != Model.TeamMembers)
{
foreach (var item in Model.TeamMembers.OrderBy(i => i))
{
<option selected="selected">#item</option>
}
}
</select>
</div>
<input type="button" class="btnAdd" value="+" />
Javascript that adds a select2 dropdown that doesn't add to the viewmodel
function addRow() {
var html = '<select asp-for="TeamMembers" class="project-team-members-enabled form-control">'
+'#if (null != Model && null != Model.TeamMembers){foreach (var item in Model.TeamMembers.OrderBy(i => i)){<option selected="selected">#item</option>}}'
+ '</select>'
$(html).appendTo($("#teamMembersAddDiv"))
$('.project-team-members-enabled').select2({
tokenSeparators: [","],
minimumInputLength: 1,
ajax: {
delay: 150,
url: '#Url.Action("TypeaheadSearch", "Profiles")',
dataType: 'json',
async: true,
data: function (params) {
return {
pageSize: 10,
pageNum: params.page || 1,
searchTerm: params.term
};
},
processResults: function (data, params) {
params.page = params.page || 1;
return {
results: data.results,
pagination: {
more: (params.page * 10) <= data.total
}
};
},
cache: true
},
createTag: function (params) {
var term = $.trim(params.term).replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() +
txt.substr(1).toLowerCase();
});
if (term === '') {
return null;
}
if (!/^[a-zA-Z0-9_]+( [a-zA-Z0-9_]+)*$/g.test(term)) {
return null;
}
return {
id: term,
text: term
}
}
});
};
Viewmodel TeamMembers
TeamMembers = new List<string>();
...
public IList<string> TeamMembers { get; set; }
I would assume that there is some way to get the selected text item from a dropdown, and save it to the viewmodel before the viewmodel is posted to the controller. But I haven't been able to find it so far, and I'm hoping someone else might know.
Here is my view in image
The code is working fine, but...
When i submit the form, it only sends the value of first dropdownlist (I checked on browser network received arguments), also when i view the page source it doesn't show the generated options that I generated using ajax function.
Here is my Code
Action that generate my first dropdownList
public ActionResult TwoDropDownList()
{
HotelContext H = new HotelContext();
ViewBag.DropDownListOne = new SelectList(H.Continent.ToList(), "Id", "Name");
return View();
}
Action that return json of second dropdownlist data
[HttpPost]
public JsonResult UpdateCountryDropDownList(int ContinentId)
{
HotelContext H = new HotelContext();
List<SelectListItem> CountryNames = new List<SelectListItem>();
List<Country> Co = H.Country.Where(x => x.ContinentId == ContinentId).ToList();
Co.ForEach(x =>
{
CountryNames.Add(new SelectListItem { Text = x.Name, Value = x.Id.ToString() });
});
return Json(CountryNames , JsonRequestBehavior.AllowGet);
}
My Ajax call
#model Hotel.Models.Continent
<script>
$(document).ready(function () {
$("#Name").change(function () {
var ContinentoId = $(this).val();
$.ajax({
type: "POST",
dataType: "json",
data: { ContinentId: ContinentoId },
url: '#Url.Action("UpdateCountryDropDownList","Home")',
success: function (result) {
var Country = "<select id='ddlCountry'>";
Country = Country + '<option value="">--Select--</option>';
for (var i = 0; i < result.length; i++) {
Country = Country + '<option value=' + result[i].Value + '>' + result[i].Text + '</option>';
}
Country = Country + '</select>';
$('#Countries').html(Country);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(arguments)
}
});
});
})
</script>
My View
#using(Html.BeginForm()){
SelectList se = ViewBag.DropDownListOne;
#Html.DropDownListFor(x=>x.Name,se,"--Select--")
<div id ="Countries">
#Html.DropDownList("ddlCountry",new List<SelectListItem>(),"--Select--")
</div>
<input type="submit" value="submit" style="margin-top:100px;" />
}
HTTPPost Action
[HttpPost]
public string TwoDropDownList(string Name, string ddlCountry)
{
if (string.IsNullOrEmpty(Name) || string.IsNullOrEmpty(ddlCountry))
{
return ("you must select Both");
}
else
return ("everything is working fine");
}
You already have a <select> element with name="ddlCountry" (generated by #Html.DropDownList("ddlCountry", new List<SelectListItem>(), "--Select--") but in the ajax call, you overwrite it and create a new <select> element without a name attribute (so its value is not posted back.
In the success callback, you should be creating <option> elements and appending them to the existing <select>
success: function (result) {
var country = $('#ddlCountry); // get the existing element
country.empty().append($('<option></option>').val('').text('--Select--'));
$.each(result, function(index, item) {
country.append($('<option></option>').val(item.Value).text(item.Text));
});
}
Side note: Your methods should be returning a collection of anonymous objects, not SelectListItem There is no point sending extra data (the other properties of SelectListItem) across the wire when you don't use them.
I think you are missing the end tag </div> for the <div id ="Countries">.
Try this:
<div id ="Countries">
#Html.DropDownList("ddlCountry",new List<SelectListItem>(),"--Select--")
</div>
i have a dropdown, where i can select AgencyName, with that selected AgencyName, i tried to display its AgentName in the next dropdown. But my code does'nt display the AgentName in the next dropdown.
i have my view page like:
<span class="LabelNormal">Agency</span>
#Html.DropDownListFor(m => m.LightAgencies.agencykey, new SelectList(Model.LightAgencies.Agency, "Key", "Value"), "", new {#id = "OwnerAgency" })
<span class="LabelNormal">Agent</span>
#Html.DropDownListFor(m => m.LightOwnerAgent.au_key, new SelectList(""), "", new { #id = "OwnerAgent" })
And i have my jquery like,
$(document).ready(function () {
$("#OwnerAgency").change(function () {
var procemessage = "<option value=`0`> Please wait...</option>";
$("#OwnerAgent").html(procemessage).show();
var url = "/Index/GetOwnerAgent/";
// Get agency key
var OwnerAgency = $("#OwnerAgency :selected").val();
// Get agent
var OwnerAgent = $("#OwnerAgent :selected").val();
$.ajax({
url: url,
data: { agencykey: OwnerAgency },
cache: false,
type: "POST",
success: function (data) {
var OwnerAgent = $("#OwnerAgent :selected").val();
alert(OwnerAgent);
},
error: function (reponse) {
alert("error : " + reponse);
}
});
});
where my controller "/Index/GetOwnerAgent/" giving the exact value for OwnerAgent. As iam the beginner i dont know how to do this, Kindly tell me.
In your code, you display the selected value in the dropdownlist as soon as the controller responds. I think you want to select the result from the controller in the dropdown.
Assuming that the data returned from the controller is a value that exists in the dropdownlist, you should be able to use:
...
success: function (data) {
$("#OwnerAgent").val(data);
}
...
I have a dropdownlist:
<div class="a">
#Html.DropDownList("StorageId", null, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.StorageId)
</div>
Html:
<div class="a">
<select class="form-control" id="StorageId" name="StorageId"><option selected="selected" value="1">Brak Brak</option>
<option value="2">First</option>
<option value="23">Second</option>
<option value="24">Third</option>
</select>
<span class="field-validation-valid" data-valmsg-for="StorageId" data-valmsg-replace="true"></span>
</div>
populated with code:
ViewBag.StorageId = new SelectList(unitOfWork.storageRepository.Get(), "Id", "Name", deviceusage.StorageId);
all data is send to controller with this Ajax request:
$.ajax({
url: "/DeviceUsage/Edit",
type: "POST",
contentType: "application/json; charset=utf-8",
headers: {
'RequestVerificationToken': '#TokenHeaderValue()'
},
data: JSON.stringify({
deviceusage: {
DeviceInstanceId: $('.a').children("#DeviceInstanceId").val(),
UserId: $('.a').children('#UserId').val(),
StorageId: $('.a').children('#storageId').val()
}
}),
error: function (data) {
alert("wystąpił nieokreślony błąd " + data);
},
success: function (data) {
if (data.ok) {
$("#Modal").modal('hide');
window.location = data.newurl;
}
else {
$('.modal-body').html(data);
}
}
})
No Matter what I select in this dropdown it's not updated. After changing first selection always first one is send to controller.
#Update:
Here is a controller method I use for handling 'Post` calls:
public ActionResult Edit([Bind(Include="StorageId,UserId,DeviceInstanceId")] DeviceUsage deviceusage)
{
ValidateRequestHeader(Request);
if (deviceusage.UserId == 6 && deviceusage.StorageId == (int)Storage.Biurko)
{
ModelState.AddModelError("", "Zarezerwowane urządzenie nie moze byc przypisane do biurka");
}
if (deviceusage.UserId == 1 && deviceusage.StorageId == (int)Storage.Biurko)
{
ModelState.AddModelError("", "Wolne urządzenie nie może przebywać na jakimś biurku");
}
if ((deviceusage.UserId != 1 & deviceusage.UserId != 6) & deviceusage.StorageId != (int)Storage.Biurko)
{
ModelState.AddModelError("", "Urzązenie przypisane do kogos nie moze przebywac w magazynie");
}
if (ModelState.IsValid)
{
unitOfWork.deviceUsageRepository.Update(deviceusage);
unitOfWork.Save();
return Json(new { ok = true, newurl = Url.Action("Index") });
}
ViewBag.DeviceInstanceId = new SelectList(unitOfWork.deviceInstanceRepository.Get(), "Id", "SerialNo", deviceusage.DeviceInstanceId);
ViewBag.StorageId = new SelectList(unitOfWork.storageRepository.Get(), "Id", "Name", deviceusage.StorageId);
var data = unitOfWork.userRepository.Get()
.Select(s => new
{
Id = s.Id,
Credentials = s.Name + " " + s.Surname
}
);
ViewBag.UserId = new SelectList(data, "Id", "Credentials", deviceusage.UserId);
return PartialView(deviceusage);
}
As you can see its returning a PartialView because dropdown is in modal windows which is updated with a return of Ajax call.
#Update2
During test using browser console with this code:
$('#StorageId').val()
I managed to find that:
its correctly returning values before first send
if the modal is reloaded because of that the data was wrong. Changing selected value using list does not change anything. The value returned with this code is falue send with ajax.
The reason behind the issue that always first value is getting submitted to controller is because of this attr which is set to first option in your dropdown list box,selected="selected".
You could bypass this behaviour with change event call back like this
JQUERY CODE:
$('.a select').on('change',function() {
$(this).find('option:selected').attr("selected","selected");
});
Add the above event listener inside the $(document).ready( function() { ...... }) or onload of the body of your page.
Happy Coding :)
Try:
StorageId: $('.a').children('#StorageId').val()
note uppercase 'S' on #StorageId
Also you could probably just do:
StorageId: $('#StorageId :selected').val();
I've created a jsfiddle to demonstrate: http://jsfiddle.net/2qpBZ/