Instructing the mirror to show a picture

Write some code to show a picture on the mirror as instructed by the debug hub.

As for the next step of the project I need to make sure that the mirror can display an image when it is asked to do so.  We need to take a few steps in order to accomplish that.

As a first step I will extend the debug hub to mimic the Alexa behaviour of adding an “SHOW-PICTURE” command to the DynamoDB command queue table.

For this, I will be extending the already existing “messaging.html” file.

But first, for good measure I’ll add another javascript file to contain a function which I would potentially need on other places as well :

Schermafbeelding 2017-02-12 om 18.22.19.png

The content is fairly simple :

Schermafbeelding 2017-02-12 om 18.23.15.png

It’s very similar to what the lambda function is doing actually.  Instantiate an AWS object and configure it.  Put an item and a payload in the command queue.

Ok, so now to extend the messaging section of the debug hub with another text area.

Schermafbeelding 2017-02-12 om 18.24.43.png

I gave the 2 text area’s an Id : command & content, and the button as well : submit.

As for the code : a simple call to the function we just created.

Schermafbeelding 2017-02-12 om 18.25.57.png

Notice how the text area values are obtained using a jQuery command.

Let’s test this.

Schermafbeelding 2017-02-12 om 18.26.45.png

Click the send button, an there’s the result :

Schermafbeelding 2017-02-12 om 18.27.16.png

The next step is to extend the magic mirror module for the Alexa interface.  In an earlier post I showed you how I used a “handleCommands” function searches for the items in the DynamoDB table and reads them to pass them on using the “sendSocketNotification” function.  I’ve added a little bit of code here.

Schermafbeelding 2017-02-12 om 18.28.58.png

Notice how I construct a JSON object and add the command and the content to it.  This is the payload of the “sendSocketNotification“.  This way, the module knows the command, but also the content it needs to display.

In the mirror module itself, this type of command is now handled by this piece of code in the socketNotificationReceived function :

Schermafbeelding 2017-02-12 om 18.31.45.png

Essentially, this is also fairly simple.  All it does is construct its own payload from the payload it’s receiving.  This is passed to a notification with as type “INFO-DISPLAY“.  This notification is to be handled by another module that takes care of the display functionality.  Notice how I deliberately didn’t call it “show picture” or anything.  Theoretically this info could be something totally different from a picture, so I’ve made it a bit more generic.

As it happens, I don’t have this module yet, so I decided to create it.  Here it is :

Schermafbeelding 2017-02-12 om 18.34.26.png

Our next little module.  Its configuration is easy :

Schermafbeelding 2017-02-12 om 18.35.01.png

Just put it in the middle of the screen.  That’s it.  No fuss (for now).

The code is pretty straight forward.  The standard stuff for a basic mirror module, but the “notificationReceived” function looks like this :

Schermafbeelding 2017-02-12 om 18.35.54.png

Here I check if the notification is “INFO-DISPLAY”.  Notice how I don’t check for the “type” attribute of the payload yet. I’m just assuming that it’s some name of someone or something I’m getting passed a long, of which I need to show the picture.

The showing of the picture is setting the “src” attribute of an image, and setting it to visible.  I’m sorry if I’m violating some copyrights here by taking an online image, but that’s just the easiest way to test this.

The “this.imagepointer” is a variable that is created in the “getDom” function of the magic mirror module.  It looks like this :

Schermafbeelding 2017-02-12 om 18.38.37.png

Just create an “img” tag and append it to the wrapper.  Reset the “src” attribute, give it some dimensions and hide it.  From here on, the “this.imagepointer” can be used in the mirror module without a problem, and that’s just what happens in the “notificationReceived” function.

I’ve got a node helper for this one, but it doesn’t do anything for now.  That’s the next step: have it get a picture from the content that it has been passed, and pass it back to the mirror module to be shown.

But that’s for the next post.  Here is the result for now :

Schermafbeelding 2017-02-12 om 18.42.55.png

Cheers!

Creating the MMM-alexa-interface module

Creating my own module to act as a proxy for incoming alexa feedback.

So, for my next step I’ll be creating my own module, acting as the proxy for the Alexa feedback.  All it’s supposed to do is capture the commands and the content sent by Amazon, and act accordingly… based on some configuration of course.

So the first thing to do is create an extra folder, and create a .js file and a node helper.  You can find all the info about that in the Magic Mirror Builders section on creating your own module here.

The result in Atom looks like this :

Schermafbeelding 2017-01-27 om 18.54.48.png

So, below is the contents of my js file.  I’ve implemented a very simple start function.  Just updating the DOM every minute.

Schermafbeelding 2017-01-27 om 18.55.04.png

 

What’s more interesting is the socketNotificationReceived override.  This function receives all communications from the node helper of the function. The node helper is the file where you can specify your server side code.  You can communicate with the javascript file handling the front end story using sockets.  All I do in this function is handle all of the commands I’ve specified up until now.  You can se how the “hide-all-modules” and “show-default-modules” handle the showing and hiding of the modules using the MM variable.  Furthermore, I’ve implemented the “alexa-activated” and “alexa-deactivated” commands by sending a notification to the alert module I’ve installed on the mirror.  All it’s supposed to do is show an alert of type “notification”, and show a matching title and message.

Schermafbeelding 2017-01-27 om 18.55.11.png

The node helper code is fairly simple.  The start function override just starts a routing from the express framework, just like in our tests before.  All it does is send a socket notification to the front end where it is handled.

Schermafbeelding 2017-01-27 om 18.55.22.png

All we need to do now is add it to the configuration of the mirror like in the screenshot below. I’ve got no specific settings up until now, it’s also fairly simple.

Schermafbeelding 2017-01-27 om 18.54.29.png

Starting up the debug hub, and pressing the buttons.  Here’s the result.  Exactly what I was hoping for.

alexamirrorcomm.gif

Good luck!

 

 

An alternative using a module

Using a module to allow interaction between external applications and the mirror.

Ladies, and gentlemen.  It seems that I have gone too fast in my conclusions.  I was under the impression that the only way to allow external interaction to the mirror is by adjusting the core code.  That’s why I did some adjustments to the core code in this article.

Turns out I was wrong.  And i’m happy to admit it really.  The kind people at the magic mirror community pointed out to me that it might be better to create my own module to allow mirror commands.

Check out the forum for great support!

https://forum.magicmirror.builders

Someone pointed me to an existing mirror module, which you can find in the URL below.

https://github.com/paviro/MMM-syslog

Thank you very kindly for that!

Let’s check this out.  First get it from GitHub into my “modules” subfolder of the smart mirror root folder.

git clone https://github.com/paviro/MMM-syslog.git

I’ll be adjusting the mirror configuration.  Kick out the compliments module, and add the new one.  And restart the mirror.

Schermafbeelding 2017-01-22 om 10.54.54.png

The documentation of the module states that the only thing to do is send a message with the following syntax :

http://MIRROR_IP:MIRROR_PORT/syslog?type=INFO&message=YOUR_MESSAGE

Let’s try.  Start a browser and …

Schermafbeelding 2017-01-22 om 10.54.21.png

Yeeha.  A popup.

Schermafbeelding 2017-01-22 om 10.54.29.png

And a log in the middle of the screen.

Schermafbeelding 2017-01-22 om 10.54.34.png

How wonderfully easy is this.

Now to check out how this works, and how we can adjust it to make the same hide and show functionality as in the core adapting solution.

First, some reading in the Magic mirror module documentation.  I should have done this with some more attention earlier, but hey… sometimes I want to go too fast.

https://github.com/MichMich/MagicMirror/tree/master/modules

In here, the concept of node helpers is discussed. And it is what it is : a helper .js file where some node.js code can be created to support your module.

I found an example of hiding mirror elements in the following :

https://forum.magicmirror.builders/topic/778/mmm-voicehttps://github.com/fewieden/MMM-voice/blob/master/MMM-voice.js

By the way : this is a module allowing voice control!  Something to check out further, but as far as I can see it only takes a few mirror related commands.  The advantage of using Alexa is also there of course (you can ask here whatever you want).  It might be something to add 2 wake words like “alexa” and “mirror” or something, but there are pro’s and cons in here.  But I digress.

I’ll be adjusting the MMM-syslog code, in the place where a message is received, and is being display I’ll add my own temporary test code:

Schermafbeelding 2017-01-22 om 11.45.10.png

Just check for a different notification, and execute the code the hide the modules.

Next, adjust the node helper with another express routing as below :

Schermafbeelding 2017-01-22 om 11.45.44.png

It basically almost copies the existing code, but instead of sending a message in the notification, it sends the “hide” command.  And that’s it.  No core adjustments needed anymore.

Why is this working?  Well, the combination of the ability to access this.ExpressApp in the node helper, the MM availability in the module and the native notification features make everything possible that was possible using the core adapting solution.

 

Now, to hook things up again, so it can be used in conjunction with the debug hub.  I’ve commented away the app.get function in server.js.  Just to make sure there are no 2 handlers for the same routings.  And added this to the node helper of the MMM-syslog module :

Schermafbeelding 2017-01-22 om 12.59.56.png

Adding this to MMM-Syslog should do the trick.

Schermafbeelding 2017-01-22 om 13.00.15.png

And here’s the result.

show-hide-via-MM.gif

I will be moving forward with this approach, as I think it has more potential.  I won’t be demonstrating it in this article, but I’ll comment away the core code I added in this article.

Thanks again to the community to point this out.  Keep you posted!

 

 

 

Setting up the debug hub for external requests

Set up the debug hub with a new page allowing to start and stop a webserver taking requests from other applications.

In this article I’ll be setting up the debug hub to take external requests.  That’s necessary because I want to be sending messages to the debug hub just like I’m sending messages to the mirror.  I want the debug hub to act as a go-between between external applications like the AVS Java client and the mirror, just to control what’s happening.

In order to do so I have gave my Mac a fixed IP address.  That way I’ll be able to address the debug hub from over the network.

Next I’ll have to install the express framework in my debug hub project.  That’s easy :

sudo npm install express

Next up is some small changes to index.html of the debug hub.

Create an extra section in the sidebar.  I call the main section “Alexa”, and the subsection “Debug Server”.  Notice how I set the Id as well :

Schermafbeelding 2017-01-21 om 23.04.38.png

Use the id in a jQuery statement to switch the panes when clicked.

Schermafbeelding 2017-01-21 om 23.04.50.png

Make sure the correct file name is returned.

Schermafbeelding 2017-01-21 om 23.04.55.png

Eventually I need to create a new html file :

Schermafbeelding 2017-01-21 om 23.05.04.png

I basically copy pasted the home.html file but I made a few adjustments :

Schermafbeelding 2017-01-21 om 23.20.49.png

So what’s going on here?

First of all you can see at the bottom of the page, I changed the caption and the Id’s of the buttons on there.  I will use them to start and stop the web server.

Next, I have the jQuery statements in the $(document).ready event handler.  They link up the buttons to a callback function.  Whenever the start button is clicked it calls a function called startServer() and sets the contents of an <a> tab with id “Status” to a string indicating that the server is started.  When the stop button is clicked, the reverse happens.

The startServer and stopServer function are defined above.  The startServer function starts an express server by calling the app.listen method, stating it to start at port 3000.    The stopFunction closes the server, and pops up an alert.

Above that you can see the initialisation (requiring express, and getting the app object).  The server object is there to be referenced using the stopServer function after it has been assigned by the startFunction function.

Lastly there’s the app.get method that’s listening for request on the root (/) of the web server.  If a request comes, it will return “hello world”.

See the result in action :

start-server.gif

Let’s test it out.  Start the server and browse to the URL and port the server is started on :

Schermafbeelding 2017-01-21 om 23.23.29.png

and there we go: the result of the app.get function listening to the root of the URL.

Schermafbeelding 2017-01-21 om 23.04.15.png

Cheers!

Letting the Electron server speak to the mirror client

Setting up communication between the web server and client processes of electron, and controlling them using another application.

Important edit.  I’ve implemented another solution for the integration between the server and the client using a mirror module.  I’ll be moving forward with that solution. Check out this article.   For a solution using a change of the core code : please read on…


Allright, now things get a bit more complicated.  In the last article I showed you how I got my debug hub talking to the mirror.  That is, to the web server in the mirror.  There was nothing visible on the screen.   There was not actual visible interaction.

In this article I want to tackle this.

Electron applications are very powerful.  You can combine both server side scripting (such as NodeJS with client side scripting such as Javascript or CSS.  But with great power comes … a bit of complexity.  Complexity in that way that the webserver running in the background is a separate process from the front end client.  This front end client can be considered a browser window in fact.

The electron website explains this very well in its documentation.  In fact, there is a special framework foreseen (and it comes out of the box) to make communication from the client (also called the renderer process) to send to the server (the main process).  A main process (being the web server running in the background) listens to inputs from its renderer proces(ses) (there can be multiple in theory).

See the electron documentation here :

http://electron.atom.io/docs/api/ipc-main/

There is one big catch here.  This framework supports a message being sent from the renderer process to the main process… and that’s not what we want.  We want it the other way around.  Let me remind me of my ultimate goal : to be able to control the mirror with outside interaction.  Whether it be an application (such as the debug hub), an external proces or even Alexa Voice Service, all through a simple HTTP request.  Easy to integrate, easy to maintain, and very easy to deploy.

So here we go.  Let me start by saying there’s an important prerequisite here.  By default there is no support on the client for any server side scripting.  In other words, in the javascript files called by the client process you can’t “require” any nodeJS modules.  By default.  Of course there’s a way around this.  They only thing you have to do is adjust one of the electron settings.  In the screenshot below you can see that activate node integration by setting the setting in the webPreferences to true.

Schermafbeelding 2017-01-21 om 13.10.35.png

That’s it.  That wasn’t all that hard.

Now for the tricky part.  And the confusing part.  There are 2 sides to the IPC integration.  IPC stands for inter process communication in which there is a process that sends a message on a certain channel, and another process that listens for it.  The ipcMain object is responsible for receiving messages.  The ipcRenderer object is responsible for sending them.  It’s also important to know that the ipcRenderer is an object that cannot be used in the webserver process.  It will give you issues such as undefined objects or unknown attributes.  Trust me.  I learned it the hard way.  You should think there’s a problem here because we want the communication to go in the other direction, but it’s time to get creative.

This is where it gets confusing.  The ipcMain object can be used in the web server processes which is situated in the server.js file.  The ipcRenderer can be used in the client process, being the magic mirror module which is located in the main.js file.  That’s right.  Main.js.  What’s in a name… right?  There is no actual relation between the object called ipcMain and the source file called main.js.

Well, now that we’ve got that out of the way, it’s time to start adjusting the server.js file.

First I’ll be defining the ipcMain object on top by doing this :

Schermafbeelding 2017-01-21 om 12.59.09.png

Somewhere in the code of the server process I can now call the “on” function of ipcMain that lets you specify a channel (called asynchronous-message below) and a callback function, which is implemented with a console log and a reply in the screenshot below.

Schermafbeelding 2017-01-21 om 12.59.15.png

You might notice how I just copy pasted the code from the electron website, just to test if this would work.  Note that there are 2 ways to communicate : synchronous and asynchronous.  The first one would be done using the sync method, but it would mean that the client process would wait for a response of the server.  Which is not what we want.  So i’ll be implementing the asynchronous method.

Notice how the code sends a reply.  There’s the key to our solution!  This is a way to send a message back to the client process.

Time to adjust the code of the client process.  This is done in main.js where the MM object is defined.  I started with defining the ipcRenderer object here :

Schermafbeelding 2017-01-21 om 12.58.53.png

In Main.js, you can locate the function called modulesStarted.  It’s a callback function, executed when all mirror modules have stopped loading.  According to me, an ideal place to start testing some stuff.  I added the following lines of code to that function

Schermafbeelding 2017-01-21 om 12.58.44.png

First I send a message to the ipcMain object by using the send method.  The first parameter is the channel (the same one as the ipcRenderer is listening on), and the second parameter is the message i’m sending.

In the second statement I create a listener for a reply.  All it does is print the reply to the console.  Let’s test that out.  And what do you know.  Here you can see the output: On the one hand the console log of the dev tools in the mirror, and on the other hand the console log in the terminal of the web server.  Ping and Pong.

Schermafbeelding 2017-01-21 om 12.58.27.pngSchermafbeelding 2017-01-21 om 12.58.31.png

Now, we can get cracking with our own code.

Let’s start with making a method that will hide all of the mirror modules.  There’s a hideModule method already in the MM object, so I’ll just create one that loops through the modules, and hides them all.  Like so :

Schermafbeelding 2017-01-21 om 13.14.08.png

Next I’ll adjust the code in the modulesStarted callback a bit to kind of a loop.  I will use the standard setInterval function of javascript to continuously call a function every second.  That’s standard functionality.  All it does is call the onPoll function which I defined below it.

Schermafbeelding 2017-01-21 om 13.18.38.png

All it does is send a message, and wait for a reply.

Testing that out, it will give something like this : a lot of pings and a lot of pongs in the consoles.

Schermafbeelding 2017-01-21 om 13.17.54.pngSchermafbeelding 2017-01-21 om 13.18.01.png

Well… actually, the above screenshot is not 100% correct.  That is, it will work, but essentially I’m creating a new listener every time around.  That will create a memory leak, so I adjusted to code and customised it a bit like so :

Schermafbeelding 2017-01-21 om 13.30.25.png

The “mirror” channel is now used for communication.  There’s a listener on the channel “mirror-command”.

In the server.js file, I’ve adjusted the listener as well, to listen for the “mirror” channel.

Schermafbeelding 2017-01-21 om 13.21.35.png

So, summing it all up.  What’s happening?  Every second, the mirror sends the question the server : “what do I have to do?”.  In most cases it will get no response.  But if there is something to do, the server will send a reply with that command, at which time it is executed by the mirror.

The only thing we have to do, is make sure that a HTTP command coming into the webserver, somehow gets into that reply.  That isn’t very difficult.  We only have to create a simple queueing mechanism in which a command is queued up, and every time the question comes “what do I have to do?”, this queue is read and passed on.

Editing the code of server.js, I just define an empty array and call it command queue.

 

Schermafbeelding 2017-01-21 om 13.33.45.png

Next, I adjust the app.get method of the express framework to push a command onto the queue.

The listener for the command requests by the mirror just checks if there is a command in the queue, and removes it by using the shift method.  It then passes it on to the reply.  Easy peasy :

Schermafbeelding 2017-01-21 om 13.34.11.png

See how, in the above code I sent some console logs.  Let’s start this.

Press the button in the debug hub :

Schermafbeelding 2017-01-21 om 13.32.51.png

Here’s the log of the mirror :

Schermafbeelding 2017-01-21 om 13.32.56.png

… and the log of the server.

Schermafbeelding 2017-01-21 om 13.33.02.png

Cool, now just to hook it all up.  In the main.js process I will check for the “hide-all-modules” command, and if it comes, I will call my new function hideAllModules.

Schermafbeelding 2017-01-21 om 13.41.35.png

I added a console log to see if it works well.

Schermafbeelding 2017-01-21 om 13.41.09.png

And here we go : I pressed the button, and the modules disappear in the mirror.  Notice how the “hiding module” console log message appears it the bottom right corner :

Schermafbeelding 2017-01-21 om 13.40.19.png

 

I’ll add another function to show the modules again.  Very similar :

Schermafbeelding 2017-01-21 om 13.45.37.png

And extend the event handler to allow a second command :

Schermafbeelding 2017-01-21 om 13.45.22.png

If we run that I noticed that the server comes with a message that we’re using a deprecated function in the express framework.

Schermafbeelding 2017-01-21 om 13.49.05.png

Looking at the website of express js, that’s indeed true.  It has been replaced with another principal.  Check it out here :

https://expressjs.com/en/guide/routing.html

So i will adjust my code accordingly.  Notice how the parameter is now specified in the URL, and it can be addressed as an attribute of the params object.

Schermafbeelding 2017-01-21 om 14.03.04.png

I have to adjust the debug hub as well to pass along in the correct syntax :

Schermafbeelding 2017-01-21 om 14.03.35.png

And that’s it. We’ve hooked it all up.  I proudly present you the result below :

ezgif.com-video-to-gif.gif

Good luck!

 

 

Setting up the mirror communication

Linking the debug hub and the smart mirror software by sending and receiving http requests.

It’s time to connect the debug hub to the mirror.  But in order to do so, I need to add some code to the smart mirror software to be able to accept calls from an external application.

I’ll do that by opening the project in my atom editor, and browsing to the server.js file.  The smart mirror electron project uses a node js framework called “express” to do some simple routing tasks.  I suggest you read up on routing here.

The essence of routing is recognizing an incoming request, doing some stuff, and optionally send some data back.  Ok, that’s dumbing it down a bit, but that’s really all it does.

I will be sending a HTTP command to the magic mirror, but for this to work properly, I need to know the IP address and the port, the electron web server is running on.  The IP is easy (for now) it’s just the local host address 127.0.0.1.  The port is something that is passed on when the server is started.  You can see the code below (in server.js).

Schermafbeelding 2017-01-19 om 22.05.19.png

Notice how the port is configured.  If I look in the configuration file I see that it listens on port 8080.

Schermafbeelding 2017-01-19 om 22.05.39.png

OK, now to set up a simple routing in server.js.

By calling app.get, what really happens is, it adds a callback function to a specific path.  What code below is saying is : if some one comes to the webserver and appends “/comm” to the address, you have to call this function.  All the function does, is parse a parameter from the URL called “command” and stores it in a variable.  The variable is being output to the console, and a response is sent back to the application that did the request.

That’s it.  Really easy.

Schermafbeelding 2017-01-19 om 22.04.06.png

Let’s test this by starting up the mirror application, and opening a browser . The browser will be the calling application this time.  Just type the IPaddress followed by the port and the /comm request, just as it was configured.  You can pass parameters by adding a question mark and passing parameters in a “key=value” fashion.  In the example below I will be sending the parameter called “command” with the value “hide”.

Schermafbeelding 2017-01-19 om 22.03.53.png

And this is what shows up in the browser :

Schermafbeelding 2017-01-19 om 22.03.59.png

Excellent!

In order to connect the debug hub, I will have to change the code of the debug hub to do the same thing as the browser just did.  For this I’ll adjust home.html.

First I’ll add an Id to the 2 buttons.

Schermafbeelding 2017-01-19 om 22.14.11.png

In a script tag, just below the start of the body I will make a new function.  It accepts a command as a parameter.  It will create a new XMLHttpRequest object instance, and call the “open” method, which accepts “GET” or “POST” as the operation for the http request, followed by the exact URL.  The last Boolean indicates that the request needs to be asynchronous : the function does not need to wait for an answer.  Waiting for the answer happens through the use of a callback function.  Javascript is full of callback functions.  Get used to it!  This function is assigned to the “onreadystatechange” variable of the Http request.  It is called whenever a response is obtained from the web server.  When this is successful, it will display an alert with the response of the server.

The “ready” event handler of the document just links the click event of the buttons to the correct call of the sendNotification function.

Schermafbeelding 2017-01-19 om 22.13.23.png

Let’s test this.  Make sure both the mirror and the debug hub are running, and press the hide or show button.  This should happen :

Schermafbeelding 2017-01-19 om 22.13.01.png

Good luck!

Creating the sidebar logic

Create some logic behind the debug hub sidebar in order to show the correct contents.

 

Now that we’ve got a fancy sidebar going on the debug hub, I’ll have to create some code to see the matching controls on the right hand side pane whenever I click one of the options in the sidebar.

In order to do that, I will have to adjust the “index.html” file using some code to handle the click on the sidebar item, and the loading of the controls into the content pane.

But before doing so I’m going to do some practical stuff.  First of all, I find the size of the window that is being created too small.  I’ll enlarge it a bit for some more screen real-estate.  Primarily to be able to debug.  By default, there is no console visible, nor can I inspect the different elements inside the electron application.  To activate all this I need to call the openDevTools() function on the main window.  This takes up a lot of space of the main window, and that’s the main reason why I’m making it bigger right now.  The adjusted code in index.js can be found below.

Schermafbeelding 2017-01-19 om 20.00.25.png

In order to create the sidebar logic we’ll be using jQuery.  What is it?  Here I’m quoting their website :

jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript.

Sounds cool doesn’t it?  It is!

Let’s look at the essence of what I did to make this happen.

To keep things tidy, I decided to create separate HTML files for the content of the pane.  That way, the “index.html” file won’t get too big.  jQuery will be responsible for getting the contents of the other html files and displaying the in the content pane at the right hand side of the application.

I’ve created a new folder called “html” in my project.  In it I will create 2 new html files for now :

  • messaging.html
  • home.html

I’ll come back to the contents in a minute.

Below, you can see the code of what I added just below the body tag in index.html.

Schermafbeelding 2017-01-20 om 18.48.01.png

First, it starts by obtaining a .js file from an internet address.  This file contains all of the jQuery code, and we’re importing it into our html file just by adding this 1 line of code.

http://code.jquery.com/jquery-1.4.min.js

You might have noticed in my HTML code earlier that I added some Id’s to some tags.  In the first place to some nav group items & secondly, the content pane:

Schermafbeelding 2017-01-19 om 20.07.38.png

Schermafbeelding 2017-01-19 om 20.07.45.png

The reason I did this, is because I want to be identifying them in my code in order to manipulate them at runtime.

The code between the script tags does all the magic.  Let’s start with the code at the bottom.  jQuery can search for objects in your DOM (document object model) by using the $ sign prefix.  That’s what it does here : it selects the entire document by executing using $document  and implements the ready event handler.  This anonymous function essentially does 2 things

  • Selects the “Home” navigator item by default by calling the switchPane method of the ManagementFunctions object.
  • Assigns a Click event handler to the #Messaging and #Home navigator items.  All they do is switch the panes, by also calling the switchPane method.

The management function object variable is something I created myself.  It’s just a container for some methods I defined.  The most important method is called switchPane.  It does 4 things :

  • It gets the URL for a html file which is to be used as the content of the content pane.
  • It effectively sets the content pane content.
  • It switches the class of the current nav item to reflect a non-selected item.
  • It switches the class of the new nav item to reflect a selected item.

Lastly it sets the “currentPane” variable to be able to keep track of the pane that’s currently selected.

The getContentURL method is a helper function that only returns a URL depending on the pane identifier I give it.

As discussed before, I added 2 extra HTML files to the project : home.html & messaging.html.  They are the content of the different sections of the application.  For now, the contents is really simple.

For the home.html file I just added a logo and 2 extra buttons . Just like the sidebar they are configured using Photonkit with the btn-large and btn-primary classes.

 

Schermafbeelding 2017-01-19 om 20.11.09.png

The messaging.html file contains a group of a label and a text area that belong together and a submit button, with btn-form and btn-primary classes.

Schermafbeelding 2017-01-19 om 20.11.26.png

The code of these files will be added in a later phase.The screenshots below show what the end result looks like.

Schermafbeelding 2017-01-17 om 23.17.17.pngSchermafbeelding 2017-01-17 om 23.17.31.png