ASP.NET MVC3 Maintain Navigation History - asp.net-mvc-3

Context
My System has numerous related entities such as Tenant -> Client -> Campaign -> etc...
Each entity has an "index" view which enables Search, Paging and links to Edit/Details/Delete. In the "detail" view for each entity i have tabs displaying the entity details (read only) plus a additional tabs for any child entity where the user can search, Page and has links to Edit/Details/Delete. This allows the user to navigate "down" the tree (so to speak).
Problem
Going down the tree works a treat its coming back up that I cannot figure out.
eg, Goto tentant -> Clients tab. Search for client by name then click on the "details" link for that client. Then goto client -> Campaigns, search for a campaign then click on "edit" for the campaign. make my changes and submit the form. I could have accessed this "edit" view by either the "Campaign/Index" or "Client/Details -> Campaign tab". So how do I maintain this navigation history? The system I am working on can go 6 levels deep and I need something that will work all the way down and back up again. If I can maintain details about the state of each calling page eg. search criteria, page number, active tab etc. that would be ideal but given the complexity of this I would be happy enough just getting back to the correct page and tab.
Worst case scenario is "User" which can be access via 4 different calling pages.

Could you not store URL's in an (server-side) array and push them in as you traverse down the tree. as you come back up you could just 'pop' them out of the array one by one. If the user presses the back button, you can cross check at the point of an action being made or pass the current URL to the server on a timed JavaScript AJAX call maybe which helps keep the array up to date.

Related

UX for Model with Children in Admin Panel

I would like everyones input on how to layout a CRUD for an admin panel. First, the 'basic' data layout:
- tblSchool (parent)
- tblCars
- tblContacts (eg: John/Mary/Joe)
- tblContactType (eg: Admin/Manager/Accounts)
- tblContactDetails (eg: 012-345-6789/john#place.com)
- tblContactDetailTypes (eg: Telephone/Facsimilie/Mobile/Email)
- pivotTblCars (connect tblSchool with tblCars)
- pivotTblContacts (connect tblSchool with tblContacts)
Firstly, pivot tables are there for referrential integrity and there are other (parents) which share the same details and hence the need for the pivot tables.
So standard CRUD would just be a separate page for each element type, each having its own index, create, edit, and possibly show page.
1) So one approach for example could be: 'School' index would have a grid of all the schools - then you would select a school and click a 'manage contacts' button to get taken to the 'Contacts' index page where you would manage all the contacts of the selected School. Then you would have to go 'back' to then either manage another schools contacts and/or its 'Cars'.
2) Another approach could be that when a School is selected, sub grids below the school grid could load the children (car/contacts) data. This seems disconnected and unintuitive though.
3) Another approach could be that you would 'view' a school to see its data and at the same time it would be the index/grids for the 'Cars' and 'Contacts' below its data?
How would you handle a more inclusive approach with less steps/better flow?
4) why not use a modal, on which the main page would have the grid of all school with its details, except that cars details and contacts details are just link in which upon clicking will pop a modal instead of redirecting to a new page.
main reason for this,
this will improve the request speed as you would just request for a data.
this is more user-friendly approach, and a better-experience for the end-user, as the page will not reload/redirect to another page.

How to load Ajax driven data after user clicks browser Back Button

We have a website product that allows users to search rental inventory, view results and then click through to a details page.
On the results page, we also allow users the option to refine their search via bedrooms, bathrooms, price, etc. When the form changes, we do not reload the page, we use Ajax to run a new search query and load the new results into the container.
For example, when the user first did a search, they got back 100 properties. Then they refine their search for 3 bed, 5 bathrooms, view = oceanfront and they get back 10 properties. Once the user finds a property they like, they typically click through to the details page. But, let's say they change their mind and click the browser 'back button'.
When that happens, all of our search params that were loaded via Ajax are now gone and our property count is back to 100 instead of 10.
So what I have realized is any data loaded via Ajax is not being cached in the browser so the original search is loaded not the refined search.
After doing some research, I think using history.pushState() and history.popstate() might be the solution but I'm having trouble wrapping my head around how to implement it for our problem.
Is there a better solution? If not, will history.pushState() work?

HowTo: stay on account view while opening a contact on a column

I am using a simple tree view on the left side for a company to see linked entities like opportunities, contacts, etc.,
When I click on a contact, my browser gets redirected to the contact, but I want to stay on the company view and load the contact details into the second or third column or just any sector on that company view.
Getting redirected to each record every time I click a link is annoying because I lose my track and sometimes I want to see the parent details while I see the details of a child record. In this case I want to keep the company view while I can load one contact on the same view without any page load or redirection.
Note: I am using a demo access to Dynamics CRM 2015 online and installed a plugin from a third party to get a tree view. The above is not dependent on my tree view. This can also be done for activities for example which is listed on right column by default. By clicking on an activity, I would like to see the activity details loaded in some panel on the middle column or anywhere I want, without being redirected.
You probably can make do with a Quick View.
Let's say you want to do this trick with Accounts and Contacts, to display info for contacts inside an Account. It goes like this:
Create a lookup inside Account, to Contact entity. Put it on the form (you can make it not visible, doesn't matter).
Create a "Quick View" form inside Contact. They are built similar to normal forms. Include all the info you want to display.
Go back to Account form, INSERT -> Quick View. Select the lookup you made in point 1, and the quick view you just created.
The quick view will display on the Account form, grabbing info from the Contact selected inside the lookup. If you left the new lookup visible, you can play with it and see how it works.
4b. You probably will now need to "link" the treeview with the lookup somehow (since it's third-party I'm unable to offer any insight about it). It will require a bit of javascript for sure.
For more details, as usual, refer to MSDN
Ps: If you want to try it out fast, skip #1 and pick "Primary contact" as field in #3 (it's standad, and most likely already on the form)

Update Drupal views argument via AJAX

I have a request concerning Drupal 6.x
I'd like to have this behaviour:
imagine to have 2 columns, on the left a list of nodes (only titles for example) and on the right a view showing just one of the contents on the left.
My idea would be to achieve this with an AJAX-fashion: clicking a link in the list on the left updates the view on the right with the actual node.
Which is the best way to handle this?
My idea is to use Panels, make 2 column panel with 2 views, one (left) filtered on content type, with no arguments, and one on the right which takes in as an argument the node id to be displayed.
But how to link the 2 views with AJAX?
(or, better, how to update the view on the right with an AJAX call?)
is this possible?
Any help or idea is really welcome
Thanks!
Cheers
Mauro
You also can do a quick hack, which is quite flexible, because it allows you to change your views without changing code.
I have had a similar task recently and for your task I would do the following:
for your right column, create a exposed filter (node id) and hide whole exposed filter form using CSS.
using jQuery, attach a click behavior to titles on your left column.
the click behavior takes the node id, finds the attached exposed filter at the right column, enters the node id into the input field and executes form's .submit().
the .submit() triggers the build-into-views well debugged ajax request which refreshes your right column.
this is certainly possible, and not very difficult to do.
Your task can be divided into two main parts:
Providing a 'callback' URL in the Backend that takes a node id (nid) and returns the markup to display the node in the right panel in a format that can be processed by javascript. This will be done in PHP within a normal Drupal module. The main point is not to return a full Drupal page as usual, but only the markup for the node.
Create logic for the Frontend that, when triggered by clicking a link in the left panel, retrieves the new node markup via the URL callback above and replaces the content of the right panel with it. This needs to be done in javascript, using the Drupal javascript API with jQuery.
You can find an introduction and example for AJAX in Drupal here. (This does almost exactly what you want to do, only with images)
You should also look at this more general entry point for JavaScript in Drupal.

Is it possible to persist (without reloading) AJAX page state across BACK button clicks?

I am familiar with several approaches to making the back button work in AJAX applications in various situations, but I have not found a solution that will work gracefully in my specific scenario.
The pages I am working with are the search interface for a site. You enter terms in a normal search box, click "go and wind up at a search results page. On the search results page there are a ton of UI controls for filtering/sorting the search results to find what you are looking for. Some of the operations triggered by these controls may take a (relatively) long time to complete (e.g. several seconds).
This latency is fine in case where the user is initially filtering/sorting their results... there's a nice AJAX spinner and so on... however when the user clicks on a search result and then clicks on the BACK button, I would like the page to instantly be restored to the state it was in when they clicked through.
I can restore the states using IFRAMEs/fragment identifiers as a dictionary of page history, but what ends up happening is that when the user first hits the back button the initial page is loaded, then it (re) makes the AJAX query to get the page state back, which triggers the AJAX spinner and another wait of possible several seconds.
Is there any approach that does not require this kind of two-stage load of the page when the user returns to the page via the BACK button?
Edited to add: I am partial to jquery but I'd be happy with solutions that depend on other libraries/toolkits or that are standalone/raw javascript.
Edited to add: I should've added that I'm trying to avoid cookies/sessions because this prevents people having multiple brower windows/tabs open and manipulating different sets of search results at the same time.
Edit: Matt, can you elaborate on your proposed solution (triggering a page change event via fragment identifer)? I see how this would help with BACK button clicks across the same page but not coming BACK to the search results page after clicking on a specific result.
Just use a cookie.
Have you investigated the YUI Browser History Manager?
Try to use localStorage object. Here is crossbrower libs jStorage and WEBSHIMS json-storage
Would it help to trigger a page change event using the "Add some info to the # at the end of the URL approach".
That way, clicking the back button shouldn't actually change the page, and you should be able to restore state without the first page load.
Use something persistent that is tied to the user's profile.
Cookies and sessions are good ideas, but you can also keep those stuff in the database. That gives you an added advantage of being able to save the user's filtering preferences accross different browsing session.(if, for exampple, he was looking for something in the office and then decided to continue searching when he is back at home).
It all depends on the complexity of the filters and weather or not it is something you think that the user will want to use accross diffrent browsing sessions..
Edited to add: I should've added that
I'm trying to avoid cookies/sessions
because this prevents people having
multiple brower windows/tabs open and
manipulating different sets of search
results at the same time.
You can create a random token and assign it to the fragment identifier.
on first page load create a token if no fragment identifier is set
before navigating out, store all the temporary ajax data in a cookie with that token as index.
when hitting back, if you have a fragment identifier set, load the data from the corresponding token in the cookie.
you can even add a "time" field to expire tokens, etc...
sample cookie (JSON):
{"ajaxcache":[{"token":<token>,"time":<time>,"data":<data>}, ... ]}

Resources