Ajax.BeginForm model binding fails with SelectElement,Onchange - c#

I'm experiencing an odd issue .
I got both a text input search field, and a dropdown list.
I've set that with every change on the select menu it will submit said form with the values .
It does bind the values but it bypasses the OnSuccess function and then basically things fall apart
Relevant Code:
#Html.EnumDropDownListFor(x => x.AreaCodes, "בחר אזור", new
{
#class = "select_field w-select",
onchange = "this.form.submit()"
})
ReloadLocations = () => {
$.ajax({
url:`#Url.Action("LocationsList","Locations")`,
method: 'POST',
dataType: 'html',
contentType: 'charset=utf-8',
success: function (data) {
$("#LocationList").empty();
$("#LocationList").append(data);
},
In this version it submits the form, However it goes straight to the function without actually going into the "success" part of the ajax call,
Just returns a view.
which results in me getting a partial view back.
How can I fix this?
Edit:
Full Controller Methode:
{
public ActionResult LocationsList(SearchLocationVM searchVm)
var locationsVM = new List<LocationVM>();
var locations = new List<Locations>();
var searchTerm = searchVm.SearchTerm;
var searchArea = (int)searchVm.AreaCodes;
using (var unitOfWork = new UnitOfWork(new FriendsEntities()))
{
if (searchVm.AreaCodes == 0 && string.IsNullOrWhiteSpace(searchVm.SearchTerm))
{
locations = unitOfWork.Locations.Find(x => x.Visibility).OrderBy(x => x.Order).ToList();
locationsVM = locations.Select(x => new LocationVM()
{
ActivityHours = x.location_open_time ?? string.Empty,
ContactName = x.location_contact_name ?? string.Empty,
FirstPHone = x.first_phone_number ?? string.Empty,
SecondPHone = x.second_phone_number ?? string.Empty,
IsRefrigirated = x.location_refrigerated_medication,
LocationAdress = x.location_address ?? string.Empty,
LocationAreaName = x.location_general_area ?? string.Empty,
WhatsappNumber = x.location_whatsapp ?? string.Empty,
Logo = x.location_logo ?? string.Empty,
Id = x.Id,
}).ToList().ToList();
}
else
{
if (!string.IsNullOrWhiteSpace(searchTerm) && searchArea == 0)
{
locations = unitOfWork.Locations.Find(x => x.Visibility
|| x.location_name.Contains(searchTerm)
|| x.location_address.Contains(searchTerm)
|| x.location_general_area.Contains(searchTerm))
.OrderBy(x => x.Order)
.ToList();
}
if (string.IsNullOrWhiteSpace(searchTerm) && searchArea != 0)
{
locations = unitOfWork.Locations.Find(x => x.Visibility && x.location_area == searchArea).OrderBy(x => x.Order).ToList();
}
if (!string.IsNullOrWhiteSpace(searchTerm) && searchArea != 0)
{
locations = unitOfWork.Locations.Find(x => x.Visibility && x.location_area == searchArea
|| x.location_name.Contains(searchTerm)
|| x.location_address.Contains(searchTerm)
|| x.location_general_area.Contains(searchTerm))
.OrderBy(x => x.Order)
.ToList();
}
locationsVM = locations
.Select(x => new LocationVM()
{
ActivityHours = x.location_open_time ?? string.Empty,
ContactName = x.location_contact_name ?? string.Empty,
FirstPHone = x.first_phone_number ?? string.Empty,
SecondPHone = x.second_phone_number ?? string.Empty,
IsRefrigirated = x.location_refrigerated_medication,
LocationAdress = x.location_address ?? string.Empty,
LocationAreaName = x.location_general_area ?? string.Empty,
WhatsappNumber = x.location_whatsapp ?? string.Empty,
Logo = x.location_logo ?? string.Empty,
Id = x.Id,
}).ToList()
.ToList();
}

Related

Unable to pass parameters from view to controller in MVC5

I am trying to use an ActionLink to pass an instance of a ViewModel from my view to a controller. However, the ViewModel is always null when it reaches the controller.
ActionLink:
#Html.ActionLink("Begin Test", "TakeTest", new { vm = Model }, new { #class = "btn btn-default" })
Controller:
public ActionResult TakeTest(QuizViewModel vm) {
ViewBag.Title = vm.vmTest.TestName;
string userId = User.Identity.GetUserId();
vm.Student = db.Users.SingleOrDefault(s => s.Id == userId);
vm.Attempt = db.Attempts.SingleOrDefault(a => a.Student == vm.Student && a.Test == vm.vmTest);
if (vm.vmTest.AttemptsAllowed > 0 && vm.Attempt.Count >= vm.vmTest.AttemptsAllowed) {
return View();
}
vm.Attempt.Count++;
if (vm.QuestionList == null) {
vm.QuestionList = db.Questions.Where(q => q.TID == vm.vmTest.ID).ToList();
}
Random r = new Random();
int randQid = r.Next(0, vm.QuestionList.Count - 1);
vm.ShowQuestion = vm.QuestionList[randQid];
vm.QuestionList.Remove(vm.ShowQuestion);
vm.Asets = db.AnswerSets.Where(a => a.Question == vm.ShowQuestion).ToList();
return View(vm);
}

It is possible to refresh ViewBag value in the view?

I'm trying to do a dynamic dropdownlist :
I get the options of the dropdownlist from a database and put them in an objects list. In accordance with a checkbox value i remove objects from the list and set this list as a ViewBag value.
public ActionResult ThematicManagement(string Id, string IsAdult, string flagAdult)
{
.....
ViewBag.DDL = null;
var response = VodCatalogBUS.GetParentThematics();
List<oboThematic> list = new List<oboThematic>();
list = response.Data;
if (IsAdult == null || IsAdult == "false")
list.RemoveAll(x => x.IsAdult == true && x.Id != 1007);
else
list.RemoveAll(x => x.IsAdult == false && x.Id != 1007);
ViewBag.DDL = new SelectList(list, "Id", "Name");
....
Then in my view i fill the dropdownlist like that :
#Html.DropDownList("ParentThematic", (SelectList)ViewBag.DDL, new { #class="dropdown" })
<label><input type="checkbox" value="" id="ChkIsAdult" name="ChkIsAdult">Adulte</label>
There is no problems here, i obtain the dropdown list with 4 options after the RemoveAll in the controller. Then if i click the checkbox, i must obtain 3 other options.
So I use an ajax call to return into the controller in the aim to update Viewbag's value :
$('#ChkIsAdult').change(function () {
var IsAdult = $('#ChkIsAdult').is(':checked');
var url = dev + "/Legacy/ThematicManagement";
$.ajax({
url: url,
cache: false,
type: 'POST',
data: {
IsAdult: IsAdult,
flagAdult : 'true',
},
success: function () {
alert('test');
}
});
})
It works i return into the controller, but i think that the view isn't refresh so i retreive the old values (the 4 options) of the dropdownlist after clicking the checkbox.
I also try with ViewData and TempData to replace ViewBag but i've always the same proprem !
According to you, it is the good solution ? Can it works ?
Here is the response :
Controller
var response = VodCatalogBUS.GetParentThematics();
List<oboThematic> list = new List<oboThematic>();
list = response.Data;
list.RemoveAll(x => x.IsAdult == true && x.Id != 1007);
var responseAdult = VodCatalogBUS.GetParentThematics();
List<oboThematic> listAdult = new List<oboThematic>();
listAdult = responseAdult.Data;
listAdult.RemoveAll(y => y.IsAdult == false && y.Id != 1007);
ViewBag.DDL = new SelectList(list, "Id", "Name");
ViewBag.DDLAdult = new SelectList(listAdult, "Id", "Name");
View :
#Html.DropDownList("ParentThematic", (SelectList)ViewBag.DDL, new { #class="dropdown" })
#Html.DropDownList("ParentThematicAdult", (SelectList)ViewBag.DDLAdult, new { #class="dropdown" , #style="display:none"})
JS :
$('#ChkIsAdult').change(function () {
if ($('#ChkIsAdult').is(':checked')) {
$('#ParentThematic').hide();
$('#ParentThematicAdult').show();
var value = $('#ParentThematicAdult').val();
var IsAdult = $('#ChkIsAdult').is(':checked');
var url = dev + "/Legacy/ThematicManagement";
$.ajax({
url: url,
cache: false,
type: 'POST',
data: {
Id: value,
IsAdult: IsAdult
},
success: function (data) {
$('#result').empty().append($(data).find('table'))
}
});
}
else
{
$('#ParentThematic').show();
$('#ParentThematicAdult').hide();
var value = $('#ParentThematic').val();
var IsAdult = $('#ChkIsAdult').is(':checked');
var url = dev + "/Legacy/ThematicManagement";
$.ajax({
url: url,
cache: false,
type: 'POST',
data: {
Id: value,
IsAdult: IsAdult
},
success: function (data) {
$('#result').empty().append($(data).find('table'))
}
});
}
})

Ajax call not reach to server side methods?

When i click on button it will call JavaScript method after that on Ajax call if i debug it on Firefox browser than it calls server side method setMandate() but not directly on button click, i don't know what is happening?
<div>
<button id="GetMandateBtn" onclick="SetMandate()" disabled>Get Mandate</button>
</div>
function SetMandate() {
var clients = new Array();
var queryNo = 0;
$("#DivMandateClients input:checked").each(function () {
clients.push($(this).attr('value'));
});
if (clients == "")
clients.push(0);
var contacts = new Array();
$("#DivMandateClientsContact input:checked").each(function () {
contacts.push($(this).attr('value'));
var value = $(this).val();
});
if (contacts == "")
contacts.push(0);
var candidateStatus = new Array();
$("#candidateStatus input:checked").each(function () {
candidateStatus.push($(this).attr('value'));
});
if (candidateStatus == "") {
candidateStatus.push(0);
queryNo = 0;
}
var mandateRegion = new Array();
$("#MandateRegion input:checked").each(function () {
mandateRegion.push($(this).attr('value'));
});
if (mandateRegion == "") {
mandateRegion.push(0);
queryNo = 0;
}
var mandateCountry = new Array();
$("#MandateCountry input:checked").each(function () {
mandateCountry.push($(this).attr('value'));
});
if (mandateCountry == "") {
mandateCountry.push(0);
queryNo = 0;
}
var researchers = new Array();
$("#Researcher input:checked").each(function () {
researchers.push($(this).attr('value'));
});
if (researchers == "") {
researchers.push(0);
queryNo = 0;
}
if (StartDateTxt.value.trim() != "" && EndDateTxt.value.trim() != "") {
$.ajax({
url: "/WebService/GetMandate",
data: "{ 'startDate' : '" + StartDateTxt.value + "','endDate' : '" + EndDateTxt.value + "','clients' : '" + clients + "','contacts' : '" + contacts + "','candidateStatus' : '" + candidateStatus + "','mandateRegion' : '" + mandateRegion + "','mandateCountry' : '" + mandateCountry + "','researchers' : '" + researchers + "','queryNo' : '" + queryNo + "'}",
dataType: "json",
type: "POST",
dataFilter: function (data) { return data; },
success: function (data) {
var mandate = $("#Mandate");
mandate.html("");
if (data != null) {
if (data != "")
mandate.append($("<input type='checkbox' id='chklstMandate-2' name='Mandate' value='-2'/> <label style='display:inline;' id='lblMandate-2'>Select All</label><hr/>"));
$.each(data, function (index, value) {
mandate.append($("<input type='checkbox' id='chklstMandate" + data[index].ResearcherId + "' name='Mandate' value='" + data[index].ResearcherId + "'/> <label style='display:inline;' id='lblMandate" + data[index].ResearcherId + "'>" + data[index].MandaName + "</label><br />"));
});
$("#chklstMandate-2").click(function (event) {
if ($("#chklstMandate-2").is(":checked"))
$("#Mandate").each(function () {
$("input[type=checkbox][name='Mandate']").attr("checked", true);
});
else if ($("#chklstMandate-2").not(":checked"))
$("#Mandate").each(function () {
$("input[type=checkbox][name='Mandate']").attr("checked", false);
});
});
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("Error on Loading Mandate" + errorThrown);
}
});
}
};
public ActionResult GetMandate()
{
// InputStream contains the JSON object you've sent
String jsonString = new StreamReader(this.Request.InputStream).ReadToEnd();
// Deserialize it to a dictionary
var dic = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<String, string>>(jsonString);
var startDate = Convert.ToDateTime(dic["startDate"]);//DateTime.Parse(dic["startDate"]);
var endDate = DateTime.Parse(dic["endDate"]);
string[] clients = dic["clients"].Split(',');
string[] contacts = dic["contacts"].Split(',');
string[] candidateStatus = dic["candidateStatus"].Split(',');
string[] mandateRegion = dic["mandateRegion"].Split(',');
string[] mandateCountry = dic["mandateCountry"].Split(',');
string[] researchers = dic["researchers"].Split(',');
int queryNo = int.Parse(dic["queryNo"]);
//bool isClientIdSelected = true;
List<int> clientIds = new List<int>();
foreach (var clnt in clients)
{
if (clnt != "-2" && clnt != "0")
clientIds.Add(int.Parse(clnt));
}
List<int> contactIds = new List<int>();
foreach (var conts in contacts)
{
if (conts != "-2" && conts != "0")
contactIds.Add(int.Parse(conts));
}
List<int> candidateStatusIds = new List<int>();
foreach (var status in candidateStatus)
{
if (status != "-2" && status != "0")
candidateStatusIds.Add(int.Parse(status));
}
List<int> mandateRegionIds = new List<int>();
foreach (var region in mandateRegion)
{
if (region != "-2" && region != "0")
mandateRegionIds.Add(int.Parse(region));
}
List<int> mandateCountryIds = new List<int>();
foreach (var country in mandateCountry)
{
if (country != "-2" && country != "0")
mandateCountryIds.Add(int.Parse(country));
}
List<int> researcherIds = new List<int>();
foreach (var researcher in researchers)
{
if (researcher != "-2" && researcher != "0")
researcherIds.Add(int.Parse(researcher));
}
if (queryNo == 0)
{
var mandaetFromDB = (from mc in dbContext.MandateCandidates
join m in dbContext.Mandates on mc.MandateId equals m.MandateId
join mr in dbContext.MandateResearchers on mc.MandateId equals mr.MandateId
where m.StartDate >= startDate
&& m.EndDate <= endDate
&& clientIds.Contains(m.ClientId)
&& contactIds.Contains(m.ContactId)
&& candidateStatusIds.Contains(mc.CandidateStatusId ?? 0)
select new { MandateId = m.MandateId, MandaName = m.Name, ResearcherId = mr.ResearcherId, ClientId = m.ClientId }).ToList();
return Json(mandaetFromDB, JsonRequestBehavior.AllowGet);
}
else
{
var mandaetFromDB = (from mc in dbContext.MandateCandidates
join m in dbContext.Mandates on mc.MandateId equals m.MandateId
join mr in dbContext.MandateResearchers on mc.MandateId equals mr.MandateId
where m.StartDate >= startDate
&& m.EndDate <= endDate
&& clientIds.Contains(m.ClientId)
&& contactIds.Contains(m.ContactId)
&& candidateStatusIds.Contains(mc.CandidateStatusId ?? 0)
&& mandateRegionIds.Contains(m.RegionId ?? 0)
&& mandateCountryIds.Contains(m.MandateCountryId ?? 0)
&& researcherIds.Contains(mr.ResearcherId ?? 0)
select new { MandateId = m.MandateId, MandaName = m.Name, ResearcherId = mr.ResearcherId, ClientId = m.ClientId }).ToList();
return Json(mandaetFromDB, JsonRequestBehavior.AllowGet);
}
//return Json(mandaetFromDB, JsonRequestBehavior.AllowGet);
}

Linq: When object is null an exception is thrown

I am having difficulty with a query.
string userId = User.Identity.GetUserId();
var houseViewModel = this.Data.Houses.All()
.Where(u => u.UserId == userId && u.Name == houseName)
.Select(h => new HouseViewModel
{
Id = h.Id,
Name = h.Name,
ImageUrl = h.ImageUrl,
FloorsViewModel = h.Floоrs.Where(f=>f.Id>0)
.Select(f => new FloorViewModel
{
Name = f.Name,
RoomViewModel = f.Rooms.Where(r => r.Id > 0)
.Select(r => new RoomViewModel
{
Id = r.Id,
Name = r.Name,
SensorViewModel = new SensorViewModel
{
Id = r.Sensor.Id,
CurrentTemp = r.Sensor.CurrentTemp,
},
})
})
})
.SingleOrDefault();
When he came to the room in which no sensor throws exception because Id for SensorViewModel is a non-nullable property.
SensorViewModel = new SensorViewModel
{
Id = r.Sensor.Id,
SensorViewModel = r.Sensor == null ? new SensorViewModel() : new SensorViewModel
{
Id = r.Sensor.Id,
CurrentTemp = r.Sensor.CurrentTemp,
},
next try. Simple select only rooms with sensor.
RoomViewModel = f.Rooms.Where(r => r.Id > 0 && r.Sensor != null)
.Select(r => new RoomViewModel
{
Id = r.Id,
Name = r.Name,
SensorViewModel = new SensorViewModel
{
Id = r.Sensor.Id,
CurrentTemp = r.Sensor.CurrentTemp,
},
})
last attempt, select data from EF into list and then make viewmodel
var house = this.Data.Houses.All()
.Where(u => u.UserId == userId && u.Name == houseName).ToList();
var houseViewModel = house.Select(h => new HouseViewModel
{
Id = h.Id,
Name = h.Name,
ImageUrl = h.ImageUrl,
FloorsViewModel = h.Floоrs.Where(f=>f.Id>0)
.Select(f => new FloorViewModel
{
Name = f.Name,
RoomViewModel = f.Rooms.Where(r => r.Id > 0)
.Select(r => new RoomViewModel
{
Id = r.Id,
Name = r.Name,
SensorViewModel =r.Sensor == null ? null : new SensorViewModel
{
Id = r.Sensor.Id,
CurrentTemp = r.Sensor.CurrentTemp,
},
})
})
})
.SingleOrDefault();

PagedList loses search filter on second page

I'm implementing a simple paged list Index using the example at http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application
My problem is that the search string is 'lost' when I page to the second page, so instead of a filtered set of results, I'm shown all the records.
My index.cshtml:
#using (Html.BeginForm("Index", "", FormMethod.Get))
{
<p>
#Html.TextBox("searchString", ViewBag.currentFilter as string, new { #placeholder = "Search by title or author" })
<input type="submit" value="Search" />
</p>
}
#if (Model.PageCount > 1)
{
#Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )
}
My controller:
public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.TitleSortParm = sortOrder == "Title" ? "Title desc" : "Title";
ViewBag.AuthorSortParm = sortOrder == "Author" ? "Author desc" : "Author";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.currentFilter = searchString;
var Articles = from a in db.Articles
select a;
if (!String.IsNullOrEmpty(searchString))
{
//page = 1;
Insights = Articles.Where(s => s.Title.ToUpper().Contains(searchString.ToUpper())
|| s.Author.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "Author":
Insights = Articles.OrderBy(s => s.Author);
break;
case "Author desc":
Insights = Articles.OrderByDescending(s => s.Author);
break;
case "Title":
Insights = Articles.OrderBy(s => s.Title);
break;
case "Title desc":
Insights = Articles.OrderByDescending(s => s.Title);
break;
case "Date":
Insights = Articles.OrderBy(s => s.DatePublished);
break;
default:
Insights = Articles.OrderByDescending(s => s.DatePublished);
break;
}
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(Articles.ToPagedList(pageNumber, pageSize));
}
When I go to Page 2 as an example, all my variables, sortOrder, currentFilter and searchString are all null.
Robbie
The problem is your PagedList entry doesn't include your sort order nor your current filter.
In addition to adding ViewBag.CurrentSort as suggested by Vasanth, you also need to change your PagedListPager to:
#Html.PagedListPager( Model, page => Url.Action("Index", new { page, currentFilter=ViewBag.CurrentFilter, sortOrder = ViewBag.sortOrder}) )
Hello I figured this out, Use a Tempdata to hold the search parameters. When the search method is called with some values, store the values in a tempdata. When the page list calls the method for page 2, collect the Search parameters from the TempData.
See this:
if (SearchParameter != null)
{
TempData["HoldSearch"] = SearchParameter;
TempData.Keep();
}
else
{
SearchParameter = (CastBacktoType)TempData["HoldSearch"];
TempData.Keep();
}
Have tried this, it works well
If you have a complex search/filtering section with more than one field, you might need to use something like :
<div class="pagedList">
#Html.PagedListPager(Model, page => Url.Action("Index", new {
page, sortOrder = ViewBag.CurrentSort,
currentFilter = ViewBag.CurrentFilter,
filter2= Request.QueryString["filter2"],
filter3= Request.QueryString["filter3"],
filter4= Request.QueryString["filter4"],
filter5= Request.QueryString["filter5"] }))
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
</div>
This worked for me and now I can use complex filtering and view the results on multiple pages.
To filter the data by applying multiple filters we can use ViewBag like this in View.
For example if we want to apply filter for three fields(i.e EmpFirstName, EmpLastName, EmpLocation).
#Html.PagedListPager(Model, page => Url.Action("Index", new {
page,
sortOrder = ViewBag.sortOrder,
currentFilter1 =ViewBag.CurrentFilterForEmpFirstName,
currentFilter2 =ViewBag.CurrentFilterForEmpLastName,
currentFilter3 =ViewBag.CurrentFilterForEmpLocation}))
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
In controller i wroted code like this:
public ActionResult Index( int ?page, string currentFilter1, string currentFilter2, string currentFilter3,
string searchEmpFirstName , string searchEmpLastName, string searchEmpLocation)
int pageSize = 10;
int pageNumber = (page??1);
var emp_master = db.Emp_Master.Include(l => l.Emp_Location);
if (searchEmpFirstName != null || searchEmpLastName != null || searchEmpLocation != null)
{
page = 1;
}
else
{
searchEmpFirstName = currentFilter1;
searchEmpLastName = currentFilter2;
searchEmpLocation = currentFilter3;
}
ViewBag.CurrentFilterForEmpFirstName = searchEmpFirstName;
ViewBag.CurrentFilterForEmpLastName = searchEmpLastName;
ViewBag.CurrentFilterForEmpLocation = searchEmpLocation;
if(!String.IsNullOrEmpty(searchEmpFirstName))
{
emp = emp.Where(s => s.ModelName == searchEmpFirstName)
}
if(!String.IsNullOrEmpty(searchEmpLastName))
{
emp = emp.Where(s => s.ModelName == searchEmpLastName)
}
if(!String.IsNullOrEmpty(searchEmpLocation))
{
emp = emp.Where(s => s.ModelName == searchEmpLocation)
}

Categories

Resources