Controlling the activation of the default transition in viewmodels - javascript

My question is quite simple and needs no special explanation.
In Durandal, is it possible to control whether or not to use transition when switching from/to a viewmodel?
The reason why I want to be able to deactivate the animation is as follows:
I have a search form module quicksearch.js in my shell/masterpage that is accessible from anywhere. What it does is validate the input and then simply redirect to the results page results.js passing the search parameters in an URL after hash. The results.js takes care of querying the server.
When the quicksearch.js module is used while on a page other than results.js, the animation is triggered and it's desired behavior. However, when on results.js and using quicksearch.js, the only thing that changes in URL is the parameter string (module name right after the hash is left unchanged). Still, this goes through all the lifecycle of activating results.js again, with animating from results.js to results.js and that looks pretty bad.
So, is there any way to, under a condition, prevent Durandal from animating the content and just compose and bind the view?

I haven't found a way to control the transition process from my viewmodel, I doubt there is a way to do it.
Yet, the reason I asked was that I wanted to prevent Durandal from animating when navigating to the current page with different hash query string (changing this query string does trigger the navigation). The solution was to create a custom transition and to check whether the target view id is or isn't the same as the current view id. rely relied on
context.activeView.dataset.view === context.child.dataset.view;
where context.activeView is the currently attached view and context.child is the view that is about to be bound. Then, if these ids are different, I trigger the animation and if not, I simply hide context.activeView and show the other.
That's it for this case

Related

Reliable way of knowing when BigCommerce checkout form has loaded

I'm trying to listen for when the form is loaded on the BigCommerce checkout page.
We need to add address validation to the page (+ disable all except first address field so it's auto populated by the address validation service we're using).
The address validation service's JavaScript is firing before the form elements exist because the BigCommerce checkout page works by dynamically adding HTML to the page with JavaScript links which then load the form.
I was thinking of using one of
Polling, setTimeout repeatedly at say 200 millis until some known element exist
Using MutationObserver which seems to do what I want https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver - I can control the div inside which the form is loaded so use mutation ovbserver to listen for "subtree" events but reading the MDN docs it was clear what subtree really means and/or when it fires
Any suggestions?
If you are on Optimized One Page Checkout, you will definitely want to go with the Mutation Listener.
This Blog Post by the BC team includes some really handy Mutation Listener code that I've leveraged on multiple checkout customizations:
https://medium.com/bigcommerce-developer-blog/the-complete-guide-to-checkout-customization-on-bigcommerce-6b566bc36fa9
Word of warning - the OPC checkout is an external application - not included in the base Cornerstone Repo source code at all. I believe it's a React App. If you are familiar with how React and other frameworks handle conditional rendering, they will often un-mount and re-mount components/HTML elements in response to their internal state.
For example, when you move from the "Shipping Details" step to the "Billing Details" step on checkout, the shipping details DOM nodes are completely un-mounted from the page.
This means that anything you've attached to them via JS/JQuery, such as event listeners, will be gone. You'll need to configure the mutation listener to listen for mounting of every single section that you need to do work on, not just the entire checkout app. This makes checkout customizations fairly tricky to handle.
Another issue - if you want to over-write the input field values, you're going to be fighting with the React app, once again. As I've mentioned, React contains an internal state which controls the values of the address inputs. You can try to use JS to change the value of those inputs, but the internal state within the React app corresponding to those fields will not update. You will need to either use the checkout storefrontAPI to update those values,or you will need to use a hacky solution to manually trigger React's internal synthetic event emitter after updating the values with your JS code, I've used this library to some success:
It's not an ideal solution at all.
https://github.com/vitalyq/react-trigger-change
Preferably, if you need tight control over checkout, you can develop a customized checkout solution using the checkout-sdk that BC provides, but this is not a light task, as it's more a set of building blocks for building custom checkout flows rather than something you can drop in and start customizing right away.

Angularjs, IONIC; Hide DOM element on state changed instead of removing it

The default behavior or angularjs/ionic is to remove the DOM element when the route changed/left the page and replace it with the new DOM elm/run the controller again if you navigate back to the previous page.
Is there a way to hide the DOM elm associated to the route instead of removing it completely?
My use case is: my IONIC app landing page/index takes some time to compute/render and when the user navigate to detailed view and come back to the index page it build it again from scratch, because the DOM was removed and it needs to build again, which is a waist of time so rather than removing the DOM elm when the route changed hide it instead and if the user come back to the previous route, show it. this will definitely improve the app performance.
Looking forward to your response.
Thanks in advance
Abod
Use tabs in your project: http://ionicframework.com/docs/api/directive/ionNavView/
There is a lot of stuff to understand but this feature works great.
Basicly it allows you to change view without removing DOM (it stores it in memory). When you come back to previous DOM it's just loaded from memory.

How to perform navigation in Windows Store App using Blank App Template

I'm making a game using JavaScript, currently I'm using window.location = "somepage.html" to perform navigation but I'm not sure if that is the correct way to do it. As I said in the title I've choosed Blank App Template so I do not have any navigator.js or something like.
Can you guys tell me the best way to do it?
Although you can use window.location to perform navigation, I'm sure you've already noticed a few of the downsides:
The transition between pages goes through a black screen, which is an artifact of how the underlying HTML rendering engine works.
You lose your script context between pages, e.g. you don't have any shared variables or namespaces, unless you use HTML5 session storage (or WinRT app data).
It's hard to wire up back buttons, e.g. you have to make sure each destination page knows what page navigated to it, and then maintain a back stack in session storage.
It's for these reasons that WinJS + navigator.js created a way to do "pages" via DOM replacement, which is the same strategy used by "single page web apps." That is, you have a div in default.html within which you load an unload DOM fragments to give the appearance of page navigation, while you don't actually ever leave the original script context of default.html. As a result, all of your in-memory variables persist across all page navigations.
The mechanics work like this: WinJS.Navigation provides an API to manage navigation and a backstack. By itself, however, all it really does is manage a backstack array and fire navigation-related events. To do the DOM replacement, something has to be listening to those events.
Those listeners are what navigator.js implements, so that's a piece of code that you can pull into any project for this purpose. Navigator.js also implements a custom control called the PageControlNavigator (usually Application.PageControlNavigator) is what implements the listeners.
That leave the mechanics of how you define your "pages." This is what the WinJS.UI.Pages API is for, and navigator.js assumes that you've defined your pages in this way. (Technically speaking, you can define your own page mechanisms for this, perhaps using the low-level WinJS.UI.Fragments API or even implementing your own from scratch. But WinJS.UI.Pages came about because everyone who approached this problem basically came up with the same solution, so the WinJS team provided one implementation that everyone can use.)
Put together then:
You define each page as an instance of WinJS.UI.Pages.PageControl, where each page is identified by its HTML file (which can load its own JS and CSS files). The JS file contains implementations of a page's methods like ready, in which you can do initialization work. You can then build out any other object structure you want.
In default.html, define a single div for the "host container" for the page rendering. This is an instance of the PageControlNavigator class that's defined in navigator.js. In its data-win-options you specify "{home: }" for the initial page that's loaded.
Whenever you want to switch to another page, call WinJS.Navigation.navigate with the identifier for the target page (namely the path to its .html file). In response, it will fire some navigating events.
In response, the PageControlNavigator's handlers for those events will load the target page's HTML into the DOM, within its div in default.html. It will then unload the previous page's DOM. When all of this gets rendered, you see a page transition--and a smooth one because we can animate the content in and out rather than go through a black screen.
In this process, the previous page control's unload method is called, and the init/load/processed/ready methods of the new page control are called.
It's not too hard to convert a blank app template into a nav template project--move your default.html/.css/.js content into a page control structure, add navigator.js to default.html (and your project), and put a PageControlNavigator into default.html. I suggest that you create a project from the nav app template for reference. Given the explanation above, you should be able to understand the structure.
For more details, refer to Chapter 3 of my free ebook, Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition, where I talk about app anatomy and page navigation with plenty of code examples.

How to better organize multi-views in a web single page app?

Assume I have a lot of views in my single page app. It means, I put some view inside a div and show this or that view depending on user's actions. So, I usually show on view at a time. For example, I have these views - dashboard, settings, entries, entry details.
Depending on current state of the app one of these views is visible and others aren't. When I go this way dashboard > entries > entry details, then edit some entry details and click save or back button, I want the app to go back to entries. But if I have a link on dashboard that, for example goes to the latest edited entry, I can go this way dashboard > entry details, and in this case I want to get back to the dashboard by clicking save or back button.
This case can become even more complex with deeper views paths. Right now I manage it like this - When a button responsible for views switching is clicked, the variable state is being changed to something like from_dashboard_to_entries. I listen for that variable to change, then do all the view switching from another function depending on the state variable value. This way I have to manually define all possible scenarios and test all the possible combinations of cases. Right now this approach works quite well, but I am worried about deeper, or longer views sequences.
My idea is to somehow create a history of views in an array or something but I am not clearly understand how to do it better.
Please share your thoughts how you would organize this.
Simply don't worry about the source view - you don't have to know it to change to the destination view. If you want a history, instead of manually storing it, consider using the HTML5 History API, preferably with a wrapper library (e.g. History.js).
Rather, We should be setting the view while changing the state of application. This may optimize the initial app launch time by not loading all the views at launch and will give a way for on-demand loading.

Javascript - best way to handle post-load generated content

I've been wondering how to efficiently and generically process content that is generated after any user action.
For instance, let's say my script processes all paragraphs of Facebook at page load in order to make them blink. What would be the most responsive way to make the text that is displayed later (because of infinite scroll e.g.) blink ?
Thanks in advance for your ideas,
Rolf
Personally, I define a function called dom_mods() that modifies the page in order to apply any special effects such as autocompletion, default value for <select>, auto-resizing textareas and so on. Whenever I add content to the document, I call dom_mods().
The only catch is to make sure you don't affect the same elements twice, or if you do it needs to not make a difference. For instance, there might be a class that defines a set of elements to affect, so the class should be removed by dom_mods() so it doesn't get the treatement twice.
You would add the blink function to the parent object that would encompass all the children.
In other words if you use jquery you would specify the event selector as (".parent .child") when registering the child blink event. This way, you don't need to register any additional jquery "dom_mods" function or call anything else which wastes memory and time.

Categories

Resources