My partialview didnot load, i'm using AjaxActionLink
here is my view where i call my partialview
#foreach (var p in Model.Rooms)
{
<div class="room">
<h3>#p.RoomTitle</h3>
<img src="#p.PhotoRoom" alt="room"/>
<h4>#p.TitlePrice</h4>
<blockquote>#p.Description</blockquote>
#Ajax.ActionLink("Order room", "PartialDetail", new { #p.RoomID }, new AjaxOptions { UpdateTargetId = "results", LoadingElementId = "loading",HttpMethod = "POST",InsertionMode = InsertionMode.InsertAfter})
</div>
}
Here is my controller
public PartialViewResult PartialDetail(int roomid)
{
Room rooms =
repository.Room.FirstOrDefault(p => p.RoomID == roomid);
var viewModel = new RoomEditViewModel
{
RoomID = rooms.RoomID,
RoomTitle = rooms.RoomTitle,
Description = rooms.Description,
PhotoRoom = rooms.PhotoRoom
};
ViewBag.room = roomid;
return PartialView(viewModel);
}
fixed your ajax action link
What you set
#Ajax.ActionLink("Order room", "PartialDetail", new { #p.RoomID }
Should be
#Ajax.ActionLink("Order room", "PartialDetail", new { roomid = #p.RoomID }
As a recommendation set the aceepted protocols in your action
[HttpPost]
public PartialViewResult PartialDetail(int roomid)
Related
I have dropdownlst which i have filled from database. Now i need to get the selected value in Controller do some manipulation. But null data will get. Code which i have tried.
##View##
#using (Html.BeginForm()) {
#Html.DropDownList("SupplierId", ViewBag.PurSupName as SelectList, new {#class = "form-control",style = "width: 200px;",id="supId"})
}
## Controller ##
public ActionResult ItemPurchased()
{
POS_DBEntities2 db = new POS_DBEntities2();
var query = from i in db.TBL_Account
where i.Type == "supplier"
select i;
ViewBag.PurSupName = new SelectList(query, "AccountId", "AccountName");
return PartialView("ItemPurchased", new List<PurchasedItem>());
}
##Controller##
public ActionResult GetPurchasedItem()
{
var optionsValue = this.Request.Form.Get("SupplierId");
return View();
}
You can try with below changes.
#using (Html.BeginForm("GetPurchasedItem","YourController")) {
#Html.DropDownList("SupplierId", ViewBag.PurSupName as SelectList, new {#class = "form-control",style = "width: 200px;",id="supId"})
<input type="submit" value="OK" />
}
Controller will be
[HttpPost]
public ActionResult GetPurchasedItem(string SupplierId)
{
var optionsValue = SupplierId;
//..............
return View();
}
It should work normally..
Im using Grid.MVC in my MVC web application
When test it in a blank page with index controller it works successfully with pagination and filtration.
The Problem accrue when i put it in my project
the steps that i do that i make ajax request (because i don't need to reload the page) to method and return a partial view that contains the result of the search by the Grid.Mvc the result and number of pages return successfully but when i press to next page or filter it doesn't work.
Code:
View:
#using (Ajax.BeginForm("Search", "Home",
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "SearchResult"
})){
#Html.DropDownList("Province", "Province")
#Html.DropDownList("Cities", "Cities")
<span>price from :</span> <input type="text" name="Pricefrom" />
<span>to :</span> <input type="text" name="Priceto" />
<input type="submit" value="Search" /> }
Search Controller :
[HttpPost]
public ActionResult Search(int? page , int Province = 0, int Cities = 0, int Pricefrom = 0, int Priceto = 0)
{
var ads = db.Ad.Where(a => (Cities == 0 || a.CityId == Cities) &&
(Province == 0 || a.Cities.ProvinceId == Province)&&
(Pricefrom == 0 || a.Price >= Pricefrom)&&
(Priceto == 0 || a.Price <= Priceto)).OrderBy(a => a.AdDate).ToList();
return PartialView("_Search", ads);
}
PartialView:
#using GridMvc.Html
#model IEnumerable<Semsark.Areas.Backend.Models.Ad>
<div>
#Html.Grid(Model).Columns(columns =>
{
columns.Add(c => c.Id).Titled("ID");
columns.Add(c => c.AdTitle).Titled("title");
columns.Add(c => c.AdBody).Titled("body");
}).WithPaging(2).Sortable(true)
</div>
scripts and styles in the View index.cshtml :
<head>
<meta name="viewport" content="width=device-width" />
<link href="#Url.Content("~/Content/Gridmvc.css")" rel="stylesheet" />
<script src="#Url.Content("~/Scripts/gridmvc.min.js")"></script>
<script src="~/Scripts/gridmvc.lang.ru.js"></script>
<title>Index</title>
Thanks in advance for any help,
#*Webgrid using Paging in mvc 4.
View Page **.cshtml** *#
#model MvcPopup.Models.PagedEmployeeModel
#{
//ViewBag.Title = "SearchEmployee";
Layout = null;
}
#{
WebGrid grid = new WebGrid(rowsPerPage: Model.PageSize);
grid.Bind(Model.Employee,
autoSortAndPage: false,
rowCount: Model.TotalRows
);
}
#grid.GetHtml(
fillEmptyRows: false,
alternatingRowStyle: "alternate-row",
headerStyle: "grid-header",
footerStyle: "grid-footer",
mode: WebGridPagerModes.All,
firstText: "<< First",
previousText: "< Prev",
nextText: "Next >",
lastText: "Last >>",
columns: new[] {
grid.Column("Name",
header: "Name",
format: #<text>
#Html.ActionLink((string)item.Name, "ViewEmployeeDetail", new { id = item.id }, new { #class = "viewDialog" })</text>
),
grid.Column("Department"),
grid.Column("City"),
grid.Column("State"),
grid.Column("Country",
header: "Country"
),
grid.Column("Mobile"),
grid.Column("",
header: "Actions",
format: #<text>
#Html.ActionLink("Edit", "EditEmployee", new { id = item.id }, new { #class = "editDialog" })
|
#Html.ActionLink("Delete", "Delete", new { id = item.id }, new { #class = "confirmDialog"})
</text>
)
})
#*-----------------------------------
Model folder under modelservices.cs file
=================================*#
public IEnumerable<Employee> GetEmployeePage(int pageNumber, int pageSize, string searchCriteria)
{
if (pageNumber < 1)
pageNumber = 1;
return db.Employees
.OrderBy(m =>m.Name)
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToList();
}
public int CountAllEmployee()
{
return db.Employees.Count();
}
public class PagedEmployeeModel
{
public int TotalRows { get; set; }
public IEnumerable<Employee> Employee { get; set; }
public int PageSize { get; set; }
}
#*Controller folder under create file like employeecontroller.cs *#
using MvcPopup.Models;
using System.Globalization;
using System.Text;
namespace MvcPopup.Controllers
{
public class EmployeeController : Controller
{
//
// GET: /Employee/
ModelServices mobjModel = new ModelServices();
public ActionResult Index()
{
return View();
}
public ActionResult SearchEmployee(int page = 1, string sort = "name", string sortDir = "ASC")
{
const int pageSize = 5;
var totalRows = mobjModel.CountAllEmployee();
sortDir = sortDir.Equals("desc", StringComparison.CurrentCultureIgnoreCase) ? sortDir : "asc";
var validColumns = new[] { "id", "name", "department", "country" };
if (!validColumns.Any(c => c.Equals(sort, StringComparison.CurrentCultureIgnoreCase)))
sort = "id";
var employee = mobjModel.GetEmployeePage(page, pageSize, "it." + sort + " " + sortDir);
var data = new PagedEmployeeModel()
{
TotalRows = totalRows,
PageSize = pageSize,
Employee = employee
};
return View(data);
}
------------------------
Have you tried to pass through an IQueryable list instead of an IEnumerable? According to the documentation, Gridmvc.Html requires an IQueryable for paging. There are some subtle differences between IQueryable and IEnumerable that might make a difference here.
These scripts are needed for paging:
"~/Scripts/GridMvc/URI.js"
"~/Scripts/GridMvc/gridmvc.min.js"
"~/Scripts/GridMvc/gridmvc-ext.js"
I am using MVC 3, in my project i have 2 view, i want to open 2nd view in 1st View popup
My 1st View is by that i want to Open 2nd View in PopUp,
#model CustomerAddressListModel
#using Nop.Web.Models.Customer;
#{
Layout = "~/Views/Shared/_ColumnsTwo.cshtml";
//title
Html.AddTitleParts(T("PageTitle.Account").Text);
}
<script type="text/javascript">
$(function () {
$('a.dialog').click(function () {
var url = $(this).attr('href');
var dialog = $('<div style="display:none"></div>').appendTo('body');
dialog.load(url, {}, function (responseText, textStatus, XMLHttpRequest) {
dialog.dialog({
close: function (event, ui) {
dialog.remove();
}
});
});
return false;
});
});
</script>
<div class="add-btn-cntrnr left" style="width:400px;">
#Html.ActionLink("AddLink", "AddressAdd", "Customer", new { #class = "dialog" })
</div>
and this is my second view which i want to open in PopUp:
#model CustomerAddressEditModel
#using Nop.Web.Models.Customer;
#{
Layout = null;
}
#using Nop.Web.Framework;
#using (Html.BeginForm())
{
<div class="emai_head">
<span class="emai_head_text">Add Address</span>
#{
var dataDictAddress = new ViewDataDictionary();
//Merge ModelState (required for validation)
dataDictAddress.ModelState.Merge(ViewData.ModelState);
dataDictAddress.TemplateInfo.HtmlFieldPrefix = "Address";
#Html.Partial("_CreateOrUpdateAddress", Model.Address, dataDictAddress)
}
<input type="submit" class="acc_btnn" value=" " />
</div>
}
This is my controller for PopUp view :
[NopHttpsRequirement(SslRequirement.Yes)]
public ActionResult AddressAdd()
{
if (!IsCurrentUserRegistered())
return new HttpUnauthorizedResult();
var customer = _workContext.CurrentCustomer;
var model = new CustomerAddressEditModel();
model.NavigationModel = GetCustomerNavigationModel(customer);
model.NavigationModel.SelectedTab = CustomerNavigationEnum.Addresses;
model.Address = new AddressModel();
//countries
model.Address.AvailableCountries.Add(new SelectListItem() { Text = _localizationService.GetResource("Address.SelectCountry"), Value = "0" });
foreach (var c in _countryService.GetAllCountries())
model.Address.AvailableCountries.Add(new SelectListItem() { Text = c.GetLocalized(x => x.Name), Value = c.Id.ToString() });
model.Address.AvailableStates.Add(new SelectListItem() { Text = _localizationService.GetResource("Address.OtherNonUS"), Value = "0" });
return View(model);
}
[HttpPost]
public ActionResult AddressAdd(CustomerAddressEditModel model)
{
if (!IsCurrentUserRegistered())
return new HttpUnauthorizedResult();
var customer = _workContext.CurrentCustomer;
model.NavigationModel = GetCustomerNavigationModel(customer);
model.NavigationModel.SelectedTab = CustomerNavigationEnum.Addresses;
if (ModelState.IsValid)
{
var address = model.Address.ToEntity();
address.CreatedOnUtc = DateTime.UtcNow;
//some validation
if (address.CountryId == 0)
address.CountryId = null;
if (address.StateProvinceId == 0)
address.StateProvinceId = null;
customer.Addresses.Add(address);
_customerService.UpdateCustomer(customer);
// return RedirectToRoute("CustomerAddresses");
}
//If we got this far, something failed, redisplay form
//countries
model.Address.AvailableCountries.Add(new SelectListItem() { Text = _localizationService.GetResource("Address.SelectCountry"), Value = "0" });
foreach (var c in _countryService.GetAllCountries())
model.Address.AvailableCountries.Add(new SelectListItem() { Text = c.GetLocalized(x => x.Name), Value = c.Id.ToString(), Selected = (c.Id == model.Address.CountryId) });
//states
var states = model.Address.CountryId.HasValue ? _stateProvinceService.GetStateProvincesByCountryId(model.Address.CountryId.Value).ToList() : new List<StateProvince>();
if (states.Count > 0)
{
foreach (var s in states)
model.Address.AvailableStates.Add(new SelectListItem() { Text = s.GetLocalized(x => x.Name), Value = s.Id.ToString(), Selected = (s.Id == model.Address.StateProvinceId) });
}
else
model.Address.AvailableStates.Add(new SelectListItem() { Text = _localizationService.GetResource("Address.OtherNonUS"), Value = "0" });
return View(model);
}
I have no idea what am i doing wrong.
Well i have this form, it's part of complex view.
#{
var filtersAjaxOptions = new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "clientList-body",
OnBegin = "clientList.filterRequestStart()",
OnComplete = "clientList.filterRequestComplete()",
OnSuccess = "clientList.filterRequestSuccess()"
};
}
<span class="clientFilters-filterValue inlineBlock">
#using (Ajax.BeginForm(
"Index",
"ClientList",
new {
ProductId = Model.ClientListViewModel.Filters.ProductId,
ClientFilter = Model.ClientListViewModel.Filters.ClientFilter,
BillFilter = Model.ClientListViewModel.Filters.BillFilter,
DateSortType = Model.ClientListViewModel.Filters.DateSortType,
SortDirection = Model.ClientListViewModel.Filters.SortDirection
},
filtersAjaxOptions,
new
{
id = "clientListDateFilter-form"
}
))
{
#Html.TextBoxFor(
m => m.ClientListViewModel.Filters.BeginDateRange,
new
{
#class = "dp-input textInput inlineBlock",
id = "dp-billDateFilterStart",
}
)
#Html.TextBoxFor(
m => m.ClientListViewModel.Filters.EndDateRange,
new
{
#class = "dp-input textInput inlineBlock",
id = "dp-billDateFilterEnd",
}
)
}
</span>
Here's the filters model
public class FilterModel
{
public FilterModel()
{
ClientFilter = ClientsEnum.All;
BillFilter = ClientBillsEnum.All;
}
public string ProductId { get; set; }
public ClientsEnum ClientFilter { get; set; }
public ClientBillsEnum BillFilter { get; set; }
public DateTime? BeginDateRange { get; set; }
public DateTime? EndDateRange { get; set; }
public DateSortType? DateSortType { get; set; }
public SortDirection? SortDirection { get; set; }
}
This part is ClientListController method Index:
public ActionResult Index(FilterModel filters)
{
var clientListViewModel = GetClientListViewModel(filters, 1, 1, PageSize);
if (ControllerContext.HttpContext.Request.IsAjaxRequest())
return PartialView("Partial/ClientListBody", clientListViewModel);
return View(clientListViewModel);
}
Whenever i submit the form above, it turns to me that fields "BeginDateRange" and "EndDateRange" are null and other fields are set properly. Although, when i insert Request.Form in Watch, i can see the whole data.
UPDATE 1
So i set the <globalisation> in Web.config as this:
<globalisation responseHeaderEncoding="utf-8" culture="en-US">
and yet it doesn't work. Very same result as before.
UPDATE 2
Also when i tried to put all the routevalues data into #Html.HiddenFor, controller saw only nulls. And again, Request.Form is filled prprly.
So the question is: how can i bind form data to incoming model?
TY
The default model binder uses the current culture datetime format when binding datetimes. This means that you have to enter the date into the proper format in your textboxes. On the other hand if you need a fixed format you could use a fixed culture in your web.config (<globalization> element) or write a custom model binder: https://stackoverflow.com/a/7836093/29407
UPDATE:
You need to specify the correct binding prefix because your input fields are named like ClientListViewModel.Filters.BeginDateRange but your controller action takes a FilterModel as parameter instead of the root view model:
public ActionResult Index([Bind(Prefix = "ClientListViewModel.Filters")] FilterModel filters)
{
...
}
But now this will break the other values, so you need to adjust your view as well:
#using (Ajax.BeginForm(
"Index",
"ClientList",
null,
filtersAjaxOptions,
new
{
id = "clientListDateFilter-form"
}
))
{
#Html.HiddenFor(x => x.ClientListViewModel.Filters.ProductId)
#Html.HiddenFor(x => x.ClientListViewModel.Filters.ClientFilter)
#Html.HiddenFor(x => x.ClientListViewModel.Filters.BillFilter)
#Html.HiddenFor(x => x.ClientListViewModel.Filters.DateSortType)
#Html.HiddenFor(x => x.ClientListViewModel.Filters.SortDirection)
#Html.TextBoxFor(
m => m.ClientListViewModel.Filters.BeginDateRange,
new
{
#class = "dp-input textInput inlineBlock",
id = "dp-billDateFilterStart",
}
)
#Html.TextBoxFor(
m => m.ClientListViewModel.Filters.EndDateRange,
new
{
#class = "dp-input textInput inlineBlock",
id = "dp-billDateFilterEnd",
}
)
}
or if you want to send them as part of the form url instead if using hidden fields:
#using (Ajax.BeginForm(
"Index",
"ClientList",
new RouteValueDictionary
{
{ "ClientListViewModel.Filters.ProductId", Model.ClientListViewModel.Filters.ProductId },
{ "ClientListViewModel.Filters.ClientFilter", Model.ClientListViewModel.Filters.ClientFilter },
{ "ClientListViewModel.Filters.BillFilter", Model.ClientListViewModel.Filters.BillFilter },
{ "ClientListViewModel.Filters.DateSortType", Model.ClientListViewModel.Filters.DateSortType },
{ "ClientListViewModel.Filters.SortDirection", Model.ClientListViewModel.Filters.SortDirection },
},
filtersAjaxOptions,
new RouteValueDictionary
{
{ "id", "clientListDateFilter-form" }
}
))
{
#Html.TextBoxFor(
m => m.ClientListViewModel.Filters.BeginDateRange,
new
{
#class = "dp-input textInput inlineBlock",
id = "dp-billDateFilterStart",
}
)
#Html.TextBoxFor(
m => m.ClientListViewModel.Filters.EndDateRange,
new
{
#class = "dp-input textInput inlineBlock",
id = "dp-billDateFilterEnd",
}
)
}
Try this:
public ActionResult Index(FilterModel filters, FormCollection collection)
{
UpdateModel(filters, "ClientListViewModel");
var clientListViewModel = GetClientListViewModel(filters, 1, 1, PageSize);
if (ControllerContext.HttpContext.Request.IsAjaxRequest())
return PartialView("Partial/ClientListBody", clientListViewModel);
return View(clientListViewModel);
}
And in view:
#Html.TextBoxFor(
m => m.ClientListViewModel.FilterModel.EndDateRange,
new
{
#class = "dp-input textInput inlineBlock",
id = "dp-billDateFilterEnd",
}
)
You have strange naming. Also it would be better to use hidden fields then passing values through routevalues.
I have a list of objects which uses paging in my home > index.cshtml. When a user clicks through each page of objects I only want to refresh that portion of the page and nothing else. How would I accomplish this?
Ideally I want to use Async Methods and ControllerActions...
Controllers > HomeController.cs
public ViewResult Index(int page = 1) {
ProductsListViewModel viewModel = new ProductsListViewModel {
Products = repository.Products
.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize),
PagingInfo = new PagingInfo {
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = repository.Products.Count()
}
};
return View(viewModel);
}
Home > Index.cshtml:
#model SportsStore.WebUI.Models.ProductsListViewModel
#{
ViewBag.Title = "Products";
}
#foreach (var p in Model.Products) {
<div class="item">
<h3>#p.Name</h3>
#p.Description
<h4>#p.Price.ToString("c")</h4>
</div>
}
<div class="pager">
#Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x}))
</div>
HtmlHelper > PagingHelper.cs
namespace SportsStore.WebUI.HtmlHelpers {
public static class PagingHelpers {
public static MvcHtmlString PageLinks(this HtmlHelper html,
PagingInfo pagingInfo,
Func<int, string> pageUrl) {
StringBuilder result = new StringBuilder();
for (int i = 1; i <= pagingInfo.TotalPages; i++) {
TagBuilder tag = new TagBuilder("a"); // Construct an <a> tag
tag.MergeAttribute("href", pageUrl(i));
tag.InnerHtml = i.ToString();
if (i == pagingInfo.CurrentPage)
tag.AddCssClass("selected");
result.Append(tag.ToString());
}
return MvcHtmlString.Create(result.ToString());
}
}
}
You could use AJAX. The first step is to put the contents that you want to be refreshed into a partial and into its own div:
#model SportsStore.WebUI.Models.ProductsListViewModel
#{
ViewBag.Title = "Products";
}
<div id="products">
#Html.Partial("_products", Model.Products)
</div>
<div class="pager">
#Html.PageLinks(Model.PagingInfo, x => Url.Action("Index", new { page = x }))
</div>
and then of course you will have the corresponding _Products.cshtml partial:
#model IEnumerable<SportsStore.WebUI.Models.ProductViewModel>
#foreach (var p in Model.Products) {
<div class="item">
<h3>#p.Name</h3>
#p.Description
<h4>#p.Price.ToString("c")</h4>
</div>
}
and then adapt your controller action so that it is capable of responding to AJAX requests:
public ActionResult Index(int page = 1)
{
var viewModel = new ProductsListViewModel
{
Products = repository.Products
.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = repository.Products.Count()
}
};
if (Request.IsAjaxRequest())
{
return PartialView("_Products", viewModel);
}
return View(viewModel);
}
and now all that's left is to AJAXify your pagination anchors. Could be done in a separate javascript file where you could use jQuery to subscribe to the .click() event of them and replace the default action with an AJAX request:
$(function() {
$('.pager a').click(function() {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
success: function(products) {
$('#products').html(products);
}
});
// prevent the default redirect
return false;
});
});