How to set focus on controls inside TabPage in DevExpress MVC tabpage? - tabpage

I am using DevExpress MVC for my application.In that I am using three TabPages.The content of the Tab Pages are in different Partial Views.My Question is How to set focus on controls in each tab page when the tab page is clicked?

You can try it with Html.RenderAction. For example:
#Html.DevExpress().PageControl(
settings =>
{
settings.Name = "myTabs";
settings.CallbackRouteValues = new { Controller = "Tabs", Action = "CallbackTabs" };
settings.TabPages.Add("Tab1").SetContent(() =>
{
ViewContext.Writer.Write("<div class='tab1Content'>");
Html.RenderAction("GetTab1", "Tabs");
ViewContext.Writer.Write("</div>");
});
settings.TabPages.Add("Tab2").SetContent(() =>
{
ViewContext.Writer.Write("<div class='tab1Content'>");
Html.RenderAction("GetTab2", "Tabs");
ViewContext.Writer.Write("</div>");
});
}
And controller actions:
public ActionResult GetTab1()
{
return PartialView("_Tab1", result);
}
public ActionResult GetTab2()
{
return PartialView("_Tab2", result);
}

Related

Command with navigation to another page

i need to redirect to another page in ViewModel after performing some action. I have button and set my command, however if i load the page fort the first time then i get an error "Please use navigation page" application fails and i start it again and try to load the page and it works, but if i delete the app from emulator and try all over again i have the same process.
public ICommand FilterItemsCommand { get; private set; }
public FilterArticlesForPurchaseViewModel()
: base()
{
Task.Run(async () => await LoadAllDataForArticlesAndCategories()).Wait();
FilterItemsCommand = new Command(async () => await FilterItems());
}
private async Task FilterItems()
{
await Application.Current.MainPage.Navigation.PushAsync(new ArticlesForPurchaseFiltered());
}
App
MainPage = new NavigationPage(GetMainPage());
I have also tried this
Application.Current.MainPage = new NavigationPage(new ArticlesForPurchaseFiltered());
But then i cant go back to previous page and if i use android back button the application fails
BTW i am using master detail
You can add INavigation navigation to your ViewModel's constructor like following code.
public ItemsViewModel(INavigation navigation)
{
Title = "Browse";
Items = new ObservableCollection<Item>();
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
FilterItemsCommand = new Command(() => { navigation.PushModalAsync(new Page1()); });
MessagingCenter.Subscribe<NewItemPage, Item>(this, "AddItem", async (obj, item) =>
{
var newItem = item as Item;
Items.Add(newItem);
await DataStore.AddItemAsync(newItem);
});
}
When you binding the viewmodel, you can add the attribute like following code.
public ItemsPage()
{
InitializeComponent();
BindingContext = viewModel = new ItemsViewModel(Navigation);
}
If you want to achieve the navigation in the viewModel, you can use
// this way you need add `MainPage =new NavigationPage( new MainPage());` in app.xaml.cs
navigation.PushAsync(new Page1());
// this way you do not need `MainPage =new NavigationPage( new MainPage());` in //app.xaml.cs, just used it directly
navigation.PushModalAsync(new Page1());

FreshMVVM - best way to open a page from a child ContentView that doesn't inherit from FreshBasePageModel

The following code shows 2 examples of an OpenPage Command. The one in MainPageModel works since it derives directly from FreshBasePageModel. However, the second OpenPage call in the ChildPageModel won't work (or compile). I don't want to pass the parent model all around. So how, using FreshMVVM, do I open a new page from the ChildPageModel (and have the back button work, etc)?
public class MainPageModel : FreshBasePageModel
{
public Command OpenPage
{
get
{
return new Command(() =>
{
CoreMethods.PushPageModel<NewPageModel>();
});
}
}
public ChildPageModel ChildPageModel { get; set; }
}
public class ChildPageModel
{
public Command OpenPage
{
get
{
return new Command(() =>
{
// ??????
CoreMethods.PushPageModel<NewPageModel>();
});
}
}
}
You should also make the ChildPageModel inherit from FreshBasePageModel. All PageModels should inherit from FreshBasePageModel
I make a simple example with three pages (MainPage, SecondPage, ThirdPage). You could download the source file of FreshMVVMDemo folder from HitHub.
https://github.com/WendyZang/Test.git
If you want to open a new page, you could add command in the child page.
#region Commands
public Command GotoPageCommand
{
get
{
return new Command(async () =>
{
await CoreMethods.PushPageModel<ThirdPageModel>(); //replace the ThirdPageModel with the page you want to open
});
}
}
#endregion
If you want to go back, add the command like below.
#region Commands
public Command GoBackSecondCommand
{
get
{
return new Command(async () =>
{
//await CoreMethods.PopPageModel(); //go back to main page
await CoreMethods.PushPageModel<SecondPageModel>(); //Go back to third page
});
}
}
#endregion
The following code will accomplish this...
var page = FreshPageModelResolver.ResolvePageModel<MainPageModel>();
var model = page.GetModel() as MainPageModel;
var navService = FreshMvvm.FreshIOC.Container.Resolve<IFreshNavigationService>();
await navService.PushPage(page, null);

Paging on Partial View

I have a main view with a partial view.
The partial view allows paging, I am using Bootstrap.
Controller:
public ActionResult Main()
{
return View();
}
//[ChildActionOnly]
public ActionResult _Partial(int page)
{
Model = //returns records for requested page
return View(Model);
}
View:
<ul class="pagination">
#for (int i = 1; i <= model.TotalPages; i++)
{
<li>#Html.ActionLink(i.ToString(), "_Partial", new { page = i, })</li> }
}
</ul>
My problem is, although the paging works, selecting a page is calling the _Partial Action directly ( after I removed [ChildActionOnly]
So on paging it loads the Partial View only without the Main View which it forms part of...therefor it is missing the 'frame' provided by the Main View or any formatting.
Should I be following a different approach or is there a way to call a Partial Action and it’s Main Action?
I guess I would have liked to do something like…
<li>#Html.ActionLink(i.ToString(), "Main + _Partial", new { page = i, })</li>
Or how can I get Bootstrap Paging (I don't want to go the Ajax route) to work on a Partial View?
If you don't want to use ajax, then you have to return the whole page. Here an example for your case:
Controller:
public ActionResult Main()
{
return View();
}
public ActionResult SomeAction(int page) //Name this as your like
{
// I use viewbag here for convenience,
//you should consider to create new view model if necessary.
ViewBag.PageNum = page;
return View();
}
//[ChildActionOnly]
public ActionResult _Partial(int page)
{
Model = //returns records for requested page
return View(Model);
}
View "SomeAction.cshtml":
#*Put your Main page content here*#
#Html.Action("SomeAction", "YourControllerName", new { page = ViewBag.PageNum })
#*Put your Main page content here*#
And Your pagination should change to:
<ul class="pagination">
#for (int i = 1; i <= model.TotalPages; i++)
{
<li>#Html.ActionLink(i.ToString(), "SomeAction", new { page = i, })</li> }
}
</ul>
Keep in mind that I created the "SomeAction" only because I don't know what exactly does your "Main" action do. If the "Main" is simply the 1st page, then you should merge the "SomeAction" and "Main" into one:
public ActionResult Main(int page = 1)
{
ViewBag.PageNum = page;
return View();
}

ajax paging asp.net mvc

I know how to hook up ajax paging to a grid or a webgrid in asp.net mvc. But how can I accomplish ajax paging, using custom paging for large data sets for another format outside of a table grid.
Is that even possible using an mvc helper or mvc.pagedlist?
I used to be a webforms guys and it was so easy to hook up a listview where you could use divs to create whatever layout you want for individual items, you could then hook up a datapage and wrap it all in an update panel.
Basically I want a list of items that I can page through via ajax but with having large data sets I can just pull down all the items and page via jquery, I need to do custom paging on the server side and only return the items for a specific page.
By reusing a partial view and some ajax, this is very easily done in MVC.
Add this model as a property to your page's ViewModel to handle the pagination:
namespace Models.ViewModels
{
[Serializable()]
public class PagingInfoViewModel
{
public int TotalItems { get; set; }
public int ResultsPerPage { get; set; }
public int CurrentPage { get; set; }
public int TotalPages {
get { return Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(this.TotalItems) / this.ResultsPerPage)); }
}
public string LinkTextShowMore { get; set; }
public string LinkTextShowingAll { get; set; }
/// <summary>
/// Paging url used by the jQuery Ajax function
/// </summary>
public string UrlGetMore { get; set; }
public PagingInfoViewModel(string linkTextShowMore, string linkTextShowingAll, int resultsPerPage)
{
this.LinkTextShowMore = linkTextShowMore;
this.LinkTextShowingAll = linkTextShowingAll;
this.ResultsPerPage = resultsPerPage;
}
}
}
Add the following code to your partial view to handle the pagination:
//Start Pagination
//determine the value for the X for "Showing X of Y"
{
int currentTotal = 0;
if ((Model.PagingInfo.CurrentPage * Model.PagingInfo.ResultsPerPage) < Model.PagingInfo.TotalItems) {
//the current max item we are displaying is less than the total number of policies
//display the current max item index\
currentTotal = Model.PagingInfo.CurrentPage * Model.PagingInfo.ResultsPerPage;
} else {
//the current is greater than the total number of policies
//display the total number of policies
currentTotal = Model.PagingInfo.TotalItems;
}
if (Model.PagingInfo.TotalPages == 0 || Model.PagingInfo.CurrentPage == Model.PagingInfo.TotalPages)
{
#<li>
<h3>#Model.PagingInfo.LinkTextShowingAll</h3>
<p><strong>Showing #currentTotal Of #Model.PagingInfo.TotalItems</strong></p>
</li>
} else {
#<li id="GetMore">
<a href="#" id="lnkGetMore">
<h3>#Model.PagingInfo.LinkTextShowMore</h3>
<p><strong>Showing #(currentTotal) Of #Model.PagingInfo.TotalItems</strong></p>
</a>
</li>
#<script type="text/javascript" lang="javascript">
$('#lnkGetMore').click(function () {
$.ajax({
url: "#Model.PagingInfo.UrlGetMore",
success: function (data) {
$('#ProducerList li:last').remove();
$('#ProducerList').append(data);
$('#ProducerList').listview('refresh');
}
});
return false;
});
</script>
}
}
Now, the javascript at the end is specifically for a UI that uses ul's and li's, but can easily be customized for your needs.
The UrlGetMore property is set on the back end when the model is passed to the view. I am sure there is a more elegant way of doing this. Here is the code I used:
//build paging url used by the jQuery Ajax function
view.PagingInfo.UrlGetMore == Url.RouteUrl("RouteItemList", new { page = view.PagingInfo.CurrentPage + 1 })
And finally, here is the action that handles both the initial View and the subsequent Partial View (ajax call)
public ActionResult List(UserModel user, ViewModel view, int page = 1)
{
IQueryable<model> models = this.RetrieveModels(user, view);
if ((models != null) && models.Count > 0) {
view.PagingInfo.CurrentPage = page;
view.PagingInfo.ResultsPerPage = user.Preferences.ResultsPerPage;
view.PagingInfo.TotalItems = models.Count;
view.items = models.Skip((page - 1) * user.Preferences.ResultsPerPage).Take(user.Preferences.ResultsPerPage).ToList();
//build paging url used by the jQuery Ajax function
view.PagingInfo.UrlGetMore = Url.RouteUrl("RouteList", new { page = view.PagingInfo.CurrentPage + 1 });
}
if (page == 1) {
return View(view);
} else {
return PartialView("ListPartial", view);
}
}
HTH.
You could create simple HtmlHelper simillar to this:
public static class HtmlPaginHelper
{
public static MvcHtmlString PagerNoLastPage(this AjaxHelper ajaxHelper,
int page,
int pageSize,
bool isLastPage,
Func<int, string> pageUrl,
Func<int, AjaxOptions> pageAjaxOptions)
{
var result = new StringBuilder();
var firstPageAnchor = new TagBuilder("a");
firstPageAnchor.SetInnerText("<<");
var prevPageAnchor = new TagBuilder("a");
prevPageAnchor.SetInnerText("<");
var nextPageAnchor = new TagBuilder("a");
nextPageAnchor.SetInnerText(">");
var currentPageText = new TagBuilder("span");
currentPageText.SetInnerText(string.Format("Page: {0}", page));
if (page > 1)
{
firstPageAnchor.MergeAttribute("href", pageUrl(1));
firstPageAnchor.MergeAttributes(pageAjaxOptions(1).ToUnobtrusiveHtmlAttributes());
prevPageAnchor.MergeAttribute("href", pageUrl(page - 1));
prevPageAnchor.MergeAttributes(pageAjaxOptions(page - 1).ToUnobtrusiveHtmlAttributes());
}
if (!isLastPage)
{
nextPageAnchor.MergeAttribute("href", pageUrl(page + 1));
nextPageAnchor.MergeAttributes(pageAjaxOptions(page + 1).ToUnobtrusiveHtmlAttributes());
}
result.Append(firstPageAnchor);
result.Append(prevPageAnchor);
result.Append(currentPageText);
result.Append(nextPageAnchor);
return MvcHtmlString.Create(result.ToString());
}
}
... and then use it in your Razor view:
grid results go here...
#Ajax.PagerNoLastPage(Model.Query.Page,
Model.Query.PageSize,
Model.Data.IsLastPage,
i => Url.Action("Index", RouteValues(i)),
i => new AjaxOptions
{
UpdateTargetId = "content",
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
Url = Url.Action("Grid", RouteValues(i))
})
where RouteValues(i) is defined for example like this:
#functions {
private object PageRouteValues(int i)
{
return new
{
payId = Model.Query.PayId,
clientCode = Model.Query.ClientCode,
fromDate = Model.Query.FromDate,
tillDate = Model.Query.TillDate,
payNum = Model.Query.PayId,
checkNum = Model.Query.CheckNum,
payType = Model.Query.PayType,
payStatus = Model.Query.PayStatus,
page = i,
pageSize = Model.Query.PageSize
};
}
}
Is that even possible using an mvc helper or mvc.pagedlist?
Yes, but of course you have to coordinate the client-side requests with server-side actions to handle the actual data paging. In that sense, it's not as simple as as WebForms, but it's still possible.
Here's an example of using PagedList to render each returned item in its own table, separated by horizontal rules. You should easily be able to modify the HTML in the example to produce any rendering you want.

Making Partial View Reusable

Say I have a partial view that renders a dropdown list of Applications. When selecting an item in the dropdown it renders another partial view.
This dropdown list exists in a few places in the application but on each page a different partial view needs to be rendered when selecting an application. Is there an easy way to make the dropdown reusable? ie I need to set a different data_url depending on which page the partial view is rendered.
Partial View:
<script type="text/javascript">
$(function () {
$('#ApplicationsDropdownList').change(function () {
var url = $(this).data('url');
var applicationId = $(this).val();
$('#RolesForApplication').load(url, { applicationId: applicationId})
});
});
</script>
<div>
<label for='ApplicationsDropdownList'>Application:</label>
#Html.DropDownListFor(
x => x.SelectedApplicationId,
new SelectList(Model.Applications, "Value", "Text"),
"-- Select Application --",
new
{
id = "ApplicationsDropdownList",
data_url = Url.Action("ViewRolesTableForApplication", "Index")
}
)
</div>
Controller:
public ActionResult ViewRolesTableForApplication(string applicationId)
{
...
return View("_RolesTableForApplicationPartial");
}
You could add a string property containing the data_url to the model that you use for your partial view.
So in addition to the Model containing Applications it will have public string DataUrl { get; set; } as well.

Resources