-
Notifications
You must be signed in to change notification settings - Fork 1
Dynamic Navigation Controls
AppBar and other native UI controls are a great way to make a website feel more like an app.
The simplest way to add them in is to hardcode the buttons and hardcode the routes those buttons map to. This approach (while brittle) will usually be ok as website navigation doesn't change frequently.
However you might decide that you want to future proof the app or perhaps the website is localised into many different languages and you want to make sure the users in those regions get the correct language strings.
While this approach will vary for each website, the following is the general approach:
If the website is written using a modern framework (ie: Backbone.js), you might be able to pull this information from one of the JS model objects available to you at runtime. If not, you'll need to process the DOM. This sample will focus on processing the DOM.
In app.js
define the following function:
app.readMenu = function() {
var structure = [];
var menuItems = document.querySelectorAll('.menu-item a');
for (var i = 0; i < menuItems.length; i++) {
var anchorItem = menuItems.item(i);
var navItem = {};
navItem.title = anchorItem.innerText;
navItem.href = anchorItem.href;
structure.push(navItem);
}
var msg = {};
msg.type = 'menu';
msg.payload = JSON.stringify(structure);
framework.scriptNotify(JSON.stringify(msg));
}
Note: This function is designed to retrieve the menu from the standard Wordpress TwentyFourteen theme. Other websites will require a derivative of the above.
Assuming you're using the HybridWebView Control, place the following in the MessageReceived event handler:
private async void WebHost_MessageReceived(HybridWebView sender, ScriptMessage msg)
{
switch (msg.Type)
{
case KnownMessageTypes.Menu:
{
//generate a navbar based on this
var navItems = await Task.Factory.StartNew(() => JsonConvert.DeserializeObject<IList<NavItem>>(msg.Payload));
foreach (var item in navItems)
{
var button = new Button
{
Content = item.Title,
};
button.Click += (s, a) => { WebHost.Navigate(new Uri(item.Href)); };
AppBarItemsHost.Children.Add(button);
}
break;
}
}
}
Handle the Ready event and add a "run-once" mapping that invokes the readMenu script created in the first script.
private void WebHost_Ready(object sender, EventArgs e)
{
WebHost.WebRoute.Map("/", async (uri, success, errorCode) =>
{
await WebHost.Interpreter.EvalAsync("app.readMenu();");
}, true);
}
In app.css
add the following style:
#masthead {
display: none;
}
See the Universal Apps sample in the repository.