Tutorial 2
From NaviWiki
Contents |
Tutorial 2 - "Talking to the Page"
Basic Navi Navigation
Okay, if you just completed Tutorial 1, we have a Navi (helloNavi) displaying a static page, 'helloworld.html'. You can change the current page of a Navi by using 'Navi::navigateTo()':
helloNavi->navigateTo("local://coolpage.html");
Alrite, awesome, it's just like having a little browser window inside your application. In fact, we could go back/forward or even stop the page load, just like a real browser:
helloNavi->navigateBack(); helloNavi->naviGateForward(); helloNavi->navigateStop();
Updating the Page Contents
Wouldn't it be super cool if you could just directly alter the contents of the current page?
I asked myself the same question, and thus we have Navi::evaluateJS(). This incredibly powerful API call lets you execute/evaluate Javascript in the context of the page.
Let's make a new page called 'dynamicNavi.html', copy and paste the following into it:
<html> <head> <script type="text/javascript" src="Navi.js"></script> </head> <body> <div id="content"> <p>What is your name?:</p> <input type="text" id="myTextbox" /> </div> </body> </html>
Save this file in your 'NaviLocal' folder (or equivalent directory). If you don't have 'Navi.js' inside your 'NaviLocal' folder already, you can find Navi.js in the 'NaviLibrary/Navi/Javascript/' folder of the source release.
Here's what we want to make happen with this page:
- A user types in his or her name in the textbox.
- The user hits the key, 'F2', when they are done.
- Next, we log the value of the textbox to the Ogre Log Manager.
- Finally, we update the contents of the page to say "Hello <name>".
Here's how this might look like in code (using OIS):
bool MyApplication::keyPressed( const OIS::KeyEvent &arg )
{
if(arg.key == OIS::KC_F2)
{
std::string name = myNavi->evaluateJS("$('myTextbox').getValue()");
Ogre::LogManager::getSingleton().logMessage("User's name is: " + name);
myNavi->evaluateJS("$('content').setHTML('Hello ?')", Args(name));
return true;
}
return false;
}
Let's take a closer look at the Javascript we're executing/evaluating. The first bit you see is:
$('myTextbox').getValue()
Because 'dynamicNavi.html' also includes the MooTools JS Library, we can use all of their utility functions, the most basic of which is the dollar selector, $('elementID') which lets us quickly select page elements.
Check out their docs for 'Element.js' to see the full extent of what methods are available to you for manipulating page elements. If you're really serious about taking full advantage of this library, I highly recommend reading the MooTools Mootorial (it's fun to read and fun to learn!).
Getting Functional
For more complex applications, it makes better sense to create reusable functions (or MooTools Classes, if you're really smart) to handle common behaviors.
For example, say we wanted to make a simple Navi that displays chat messages. Here's how the page's code might look:
<html>
<head>
<script type="text/javascript" src="Navi.js"></script>
<script type="text/javascript">
function addChatMessage(nickname, message)
{
var chat = $('chatBox');
// Append "(nickname): message" to the chat box
chat.setHTML(chat.innerHTML + "<b>(" + nickname + ")</b>: " + message + "<br/>");
// Scroll to the bottom
chat.scrollTo(0, chat.getSize().scrollSize.y);
}
</script>
<style type="text/css">
#chatBox {
width: 350px;
height: 250px;
border: 2px solid grey;
padding: 10px;
font-family: sans-serif;
overflow: auto;
}
</style>
</head>
<body>
<div id="chatBox">
</div>
</body>
</html>
Now, whenever we have a new chat message we need to display, we just have to invoke the function application-side:
void MyApplication::displayChat(std::string nick, std::string message)
{
myChatNavi->evaluateJS("addChatMessage(?, ?)", Args(nick)(message));
}
Voila, now we're getting organized!
This tutorial is continued in: Tutorial 2 - Part II - In Soviet Russia, Page Talks to You!

