Navigation not working as expected in WinJS - windows-8

Ello!
I have an app bar icon and on the click event - I added a function which has the following code:
function homePage() {
WinJS.Navigation.navigate("/home/homePage.html");
}
Now I have two files - homePage.html which is inside /home/ and the js file for the same.
There's a simple button on html of id NextPage.
While in the homePage.js file, I have:
function () {
"use strict";
WinJS.UI.Pages.define("/home/homePage.html", {
ready: function (element, options) {
var button = document.getElementById("NextPage");
button.addEventListener("click", GoToNextPage);
}
});
function GoToNextPage() {
WinJS.Navigation.navigate("/default.html");
}
})();
But when I click the app bar icon - nothing happens :(
So what I plan to accomplish is that when someone clicks an appbar icon on default.html - the user switches to homePage.html (and then when I click the homePage button - it goes back) - but not even the initial page transfer is taking place.
This is embarrassing to ask but I can't just fold my hands and wait for something magical to happen. I have been working on this for an hour - read videos and samples but it's not working at all.
Would appreciate help - I can't figure out what's going wrong. Thanks!

The WinJS.Navigation namespace provides state and history management, but it doesn't actually do the navigation itself. To move from one page to another, you need to define a handler function for one of the events in the WinJS.Navigation namespace - this lets you respond to call to the WinJS.Navigation.navigate method in a way which makes sense for your app.
As a demonstration, here is a homePage.html file which has a NavBar containing a command that will be the trigger for the navigation.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>NavProject</title>
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/homePage.js"></script>
</head>
<body>
<div id="contentTarget">
<h1>Select a page from the NavBar</h1>
</div>
<div id="navbar" data-win-control="WinJS.UI.AppBar"
data-win-options="{placement:'top'}">
<button data-win-control="WinJS.UI.AppBarCommand"
data-win-options="{id:'NextPage', label:'Next Page',
icon:'\u0031', section:'selection'}">
</button>
</div>
</body>
</html>
Along with the NavBar, I have defined the div element whose id is contentTarget. This is the place in my content where the new file will be loaded when the user clicks the NavBar command.
CLARIFICATION: All of the content that you want replaced needs to go into the contentTarget element. Otherwise you'll get a mix of old and new content displayed.
And here is the JavaScript file which wires it up (this is the homePage.js file which I added a script element for in the HTML file above):
(function () {
"use strict";
WinJS.Navigation.addEventListener("navigating", function (e) {
var elem = document.getElementById("contentTarget");
WinJS.UI.Animation.exitPage(elem.children).then(function () {
WinJS.Utilities.empty(elem);
WinJS.UI.Pages.render(e.detail.location, elem)
.then(function () {
return WinJS.UI.Animation.enterPage(elem.children)
});
});
});
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
app.onactivated = function (args) {
args.setPromise(WinJS.UI.processAll());
navbar.addEventListener("click", function (e) {
if (e.target.id == "NextPage") {
WinJS.Navigation.navigate("/nextPage.html");
}
}, true);
};
app.start();
})();
Notice how I have added a handler function for the WinJS.Navigation.navigating event. This event is triggered by a call to WinJS.Navigation.navigate and details of the navigation target are contained in the detail.location property of the event object.
In this example, I clear out any content in my target element and replace it with the contents of the target file and animate the transition from one to the other.
You only have to define one handler for the event. This means that if I have elements in nextPage.html that will lead to navigation, I just need to call WinJS.Navigation.navigate without needing to create a new event handler, like this:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
WinJS.UI.Pages.define("/nextPage.html", {
ready: function () {
back.addEventListener("click", function () {
WinJS.Navigation.navigate("/homePage.html");
});
}
});
</script>
</head>
<body>
This is next page.
<button id="back">Back</button>
</body>
</html>

Related

Google Publisher Tag Reward Ad reloads Mithril SPA unexpectedly

When I run this code in my localhost server and I click the Show Ad button in the #!/reward page, the reward ad shows but sends me back to the #!/ page. However, in this online code editor this SPA (single page app) works as intended: it plays the ad but leaves you on the reward page. Obviously this must have something to do with the fact that the application is running in an iframe on the editor, but why am I getting the "unexpected" behavior on my localhost and "expected" behavior in these online editors (I've also tested in jsbin and jsfiddle and same result).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script async src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"></script>
<script>
</script>
</head>
<body>
<div id="App"></div>
<script src="https://unpkg.com/mithril/mithril.min.js"></script>
<script>
window.googletag = window.googletag || {cmd: []};
googletag.cmd.push(() => {
googletag.enableServices();
googletag.pubads().addEventListener('rewardedSlotReady', event => event.makeRewardedVisible());
googletag.pubads().addEventListener('rewardedSlotClosed', event => googletag.destroySlots([event.slot]));
});
const Home = {
view: () => m('button', {
onclick: () => m.route.set('/reward')
}, 'Go to Reward Page >>>')
}
const Reward = {
view: () => [
m('button', {
onclick: () => m.route.set('/')
}, '<<< Return to Home Page'),
m('button', {
onclick: () => googletag.cmd.push(() => {
const rewardedSlot = googletag.defineOutOfPageSlot('/22639388115/rewarded_web_example', googletag.enums.OutOfPageFormat.REWARDED);
if(rewardedSlot)
{
rewardedSlot.addService(googletag.pubads());
googletag.display(rewardedSlot);
}
})
}, 'Show Ad')
],
}
m.route(document.getElementById('App'), '/', {
'/': Home,
'/reward': Reward
});
</script>
</body>
</html>
UPDATE (2022.08.03 11:16)
I can confirm that by placing this code into a subdirectory and then running it inside an iframe I get the expected behavior. I still need to understand why it doesn't work without the iframe. Here's a Glitch page that illustrates both scenarios. Click the View button on the preview pane to view it in its own window and note the difference.
The specific code for a rewarded ad appends #goog_rewarded to the end of the page's URL. This is what forces the unexpected behaviour to return to the default route of Mithril's router when using the default #! strategy. The added # triggers a hashchange event and Mithril cannot resolve the route. Setting the m.route.prefix to a different strategy (in my case m.route.prefix = '?') resolves the problem as it prevents the lookup from taking place.

how to stop page getting loaded from browser history

I am using
$(function(){
$("#header").load("header.html"
$("#footer").load("footer.html");
});
to load header and footer in all the pages of website. But ive a scriptfor menu bar in header.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#flip").click(function(){
$("#panel").slideToggle("very slow");
});
});
function myFunction(x) {
x.classList.toggle("change");
}
</script>
<script type="text/javascript">
window.onload = function() {
alert("sfdfsd");
document.getElementById('panel').style.display = 'none';
};
</script>
----------**************--------------
well the problem is when i load another page the header is not getting completely reloaded. rather than that its getting loaded from history and my menu bar style will be changed to value "block".
Someone pls help me loading header completely on each page.

How to disable button or change value after form submit

I have this code on my View
<h2>#ViewBag.FileContent</h2>
#using (Html.BeginForm("ShowWebSiteLinks", "Home"))
{
<label>WebSite URL:</label>
<input type="text" id="ft" name="fturl" value="http://localhost/search/?sr=100" style="width:350px"><br>
<label>Save to file:</label>
<input type="text" id="filename" name="links_filename" value="links.txt" style="width:200px"><br>
<input id="btnSubmit" type="submit" value="Start" />
}
After i click on submit button, controller call function fine, but submit button stays enabled. I want to prevent multiple clicks on button and want to disable it but not sure how. Ive tried with this javascript but it does not work.
$(document).ready(function () {
$('btnSubmit').click(function (e) {
$(this).attr('disabled', true);
});
});
Can someone help me with this?
Your javascript is almost correct, but the selector is wrong. Try this:
$(document).ready(function () {
$('#btnSubmit').click(function (e) {
$(this).prop('disabled', true);
});
});
Notice the "#" in the selector. This tells jQuery to find by element ID. If you don't put the "#" it will find by element name (i.e. "input", "div", etc...)
Edit:
Here's a good cheat sheet on selectors: http://refcardz.dzone.com/refcardz/jquery-selectors
Edit 2:
Update to use "$(this).prop(...)" rather than "$(this).attr(...)"
Edit 3:
I recommend you place your javascript code at the end of the page (not the head). Something like this:
<html>
<head>[...]</head>
<body>
[...]
<script type="text/javascript">
$(document).ready(function () {
$('#btnSubmit').click(function (e) {
$(this).prop('disabled', true);
});
});
</script>
</body>
</html>
The above answer isn't working for me. I've noticed that if you bind to the click event and immediately disable, you'll actually prevent the form submission from happening.
Instead, I do the following:
<script type="text/javascript">
$(document).ready(function () {
$('#btnSubmit').click(function (e) {
$(this).prop('hidden', true);
});
$('#myform').bind('invalid-form.validate', function () {
$('#btnSubmit').prop('hidden', false);
});
});
</script>
That hides your submit button when the action is clicked but still allows the action to go through. The second statement is there to re-show the button if validation fails. More details on that can be found here: ASP.net MVC Validation Hook

call parent javascript function from iframe

In node-webkit, call from iframe javascript to parent javascript doesnt work for me.
I am trying to launch a link in the iframe on the default browser as a result
I want to call a function in the parent window so as to call:
gui.Shell.openExternal("link");
Any help is appreciated. Thanks in advance.
What you want to do, is to intercept links in the internal frame.
Here we have an iframe where all links will open in the default browser, not in the Node WebKit context. I hope this helps.
Try this:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
window.gui = require('nw.gui');
handleLinks = function(event)
{
var href;
function checkLinks(element)
{
if (element.nodeName.toLowerCase() === 'a')
{
href = element.getAttribute('href');
if (href)
{
gui.Shell.openExternal(href);
// important, prevent the default event from happening!
event.preventDefault();
}
}
else if (element.parentElement)
{
checkLinks(element.parentElement);
}
}
checkLinks(event.target);
};
function isLoaded()
{
// let's see if the iframe has finished loading
var iframe = document.getElementById('myframe');
if (iframe && iframe.contentWindow && iframe.contentWindow.document &&
iframe.contentWindow.document.body &&
iframe.contentWindow.document.body.innerHTML)
{
//now deal with links
iframe.contentWindow.document.body.addEventListener('click', handleLinks, false);
}
else
{
// not yet, let's wait a bit and try again
setTimeout(isLoaded, 300);
}
};
</script>
</head>
<body>
<iframe id="myframe" src="http://www.google.com" onLoad="isLoaded();" style="width: 100%;" seamless="true" nwdisable nwfaketop></iframe>
<div>
Links in the normal browser should still work in the Node Webkit environment.
</div>
<footer>
Whaddayaknow
</footer>
</body>
</html>

Setting up Dojo Release 1.5.0

I donwloaded this release, and I'm trying to run an example from the docs.
After expanding the Dojo download, my dojo dir is:
js/dojo-release-1.5.0/dijit
js/dojo-release-1.5.0/dojo
js/dojo-release-1.5.0/dojox
The buttons show up, but hide button does not hide the div.
Do I need to add other Dojo libraries along with the reference to dojo.js?
<script type="text/javascript" language="JavaScript" src="/js/dojo-release-1.5.0/dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dijit.form.Button");
dojo.addOnLoad(function() {
var node = dojo.byId("findMe");
dojo.connect(dijit.byId("buttonOne"), "onClick", function() {
dojo.fadeOut({
node: node,
duration: 300
}).play();
});
dojo.connect(dijit.byId("buttonTwo"), "onClick", function() {
dojo.fadeIn({
node: node,
duration: 300
}).play();
})
});
HTML:
<button dojoType="dijit.form.Button" id="buttonOne">
Hide Me!
</button>
<button dojoType="dijit.form.Button" id="buttonTwo">
Show Me!
</button>
<div id="findMe">
Hiya!
</div>
There are a couple of things you may be missing. As Daniel says, adding parseOnLoad=true as a djConfig param will help. Alternatively you can add djConfig params as a global JS variable before your dojo.js script tag, i.e.
<script>
var djConfig = {
parseOnLoad: true
}
</script>
A final alternative is to manually call the parser yourself. To do this, modify your JS to:
dojo.require("dijit.form.Button");
// You need to manually require the parser if you're going to call it yourself
dojo.require("dojo.parser");
dojo.addOnLoad(function() {
var node = dojo.byId("findMe");
dojo.connect(dijit.byId("buttonOne"), "onClick", function() {
dojo.fadeOut({
node: node,
duration: 300
}).play();
});
dojo.connect(dijit.byId("buttonTwo"), "onClick", function() {
dojo.fadeIn({
node: node,
duration: 300
}).play();
})
// New line, parse the doc
dojo.parser.parse();
});
Additionally to parsing, you may need to add a theme (you've not mentioned if you've done this or not). The easiest way to do this is to add the class name to your body tag and import the css.
...
<link rel="stylesheet" type="text/css" href="/js/dojo-release-1.5.0/dijit/themes/claro/claro.css">
</head>
<body class="claro">
...
</body>
http://telliott.net/dojoExamples/dojo-buttonHelloWorld.html contains an example of this all working for you, feel free to go crib.
Reading http://dojotoolkit.org/reference-guide/djConfig.html#djconfig and http://dojotoolkit.org/reference-guide/dijit/info.html#dijit-info would probably be a good idea also.
HTH.
Tom
try adding djConfig="parseOnLoad:true" when add the dojo.js to the page.
ex:
<script type="text/javascript" language="JavaScript" src="/js/dojo-release-1.5.0/dojo/dojo.js" djConfig="parseOnLoad:true"></script>
//Daniel