WebServer: Call function on click without reloading page?

I am not a web monkey, but I have the WebServer library up and running on my Photon. I also have functions being called based on specific url_tails (i.e. ?runMe) but that causes the page to reload, which is very slow. Is it possible to perform the same action without the reload?

Edit: I should also mention that I have WebServer “commands” setup to call functions when accessed. (E.g. http://www.myPhoton.com/pressButton). I just can’t figure out how to activate that URL without opening a browser window/tab.

Hi , I think the way to do it is with JavaScript , which I’m learning again after a long rest from programming.
Look at this video .

Thanks! I was able to do it by combining that tutorial with a call to jQuery. I was even able to alias keyboard strokes to activate the buttons. Super cool!

@Jerware Would you be able to share how you have implemented the web server library on your photon? I would be interested to try out something similar. Thanks

Sure, let’s see if I can cull the stuff into a basic example sketch…

/* A very simple AJAX keypress demo */

#include "WebServer/WebServer.h"

/* This creates an instance of the webserver.  By specifying a prefix
 * of "", all pages will be at the root of the server. */
#define PREFIX ""
WebServer webserver(PREFIX, 80);

void setup()
{
  pinMode(D7, OUTPUT);
  WebServerLaunch();
}

void loop()
{
  processWebServer();
}

void onCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  // code you want executed when left arrow key pressed
  Serial.println("On!");
  digitalWrite(D7, HIGH);
}

void offCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  // code you want executed when right arrow key pressed
  Serial.println("Off!");
  digitalWrite(D7, LOW);
}

void helloCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  /* this line sends the standard "we're all OK" headers back to the
     browser */
  server.httpSuccess();

  /* if we're handling a GET or POST, we can output our data here.
     For a HEAD request, we just stop after outputting headers. */
  if (type == WebServer::HEAD)
    return;

  /* this defines some HTML text in read-only memory aka PROGMEM.
   * This is needed to avoid having the string copied to our limited
   * amount of RAM. */
  server.println("<html><head>\n");
  P(Page_start) = "<title>AJAX EXAMPLE</title>\n";
  server.printP(Page_start);
  server.println("<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>\n");
  server.println("</head><body>\n");

  server.println("<script>");
  server.print("function funky(cmd){ $.ajax('http://");
  server.print(WiFi.localIP());
  server.println("/' + cmd); }");
  server.println("</script>\n");

  server.println("<script>");
  server.println("$(window).keydown(function(e) {");
  server.println("switch (e.keyCode) {");
  server.println("case 37: // left arrow key");
  server.println("funky(\"on\");");
  server.println("return;");
  server.println("case 38: // up arrow key");
  server.println("return;");
  server.println("case 39: // right arrow key");
  server.println("funky(\"off\");");
  server.println("return;");
  server.println("case 40: // down arrow key");
  server.println("return;");
  server.println("}");
  server.println("});");
  server.println("</script>\n");

  server.printP("<H2><p>AJAX DEMO</p></H2>\n");

  server.println("<p>");
  server.println("Use the buttons below or left/right arrow keys to toggle the Photon LED");

  server.println("<table><tr>");
  server.println("<td><form><input type='button' value='ON' onclick='funky(\"on\")'></form></td>\n");
  server.println("<td><form><input type='button' value='OFF' onclick='funky(\"off\")'></form></td>\n");
  server.println("</tr></table>");

  server.println("<p>");
  server.println("SSID: ");
  server.println(WiFi.SSID());
  server.println("<br>");
  server.println("Local IP: ");
  server.println(WiFi.localIP());
  server.println("<br>");
  server.println("Subnet Mask: ");
  server.println(WiFi.subnetMask());
  server.println("<br>");
  server.println("Gateway IP: ");
  server.println(WiFi.gatewayIP());
  server.println("<br>");
  server.println("---");
  server.println("<br>");
  server.println("deviceID: ");
  String myID = System.deviceID();
  server.println(myID);
  server.println("<br>");
  server.printlnf("System version: %s", System.version().c_str());
  server.println("<br>");
  uint32_t freemem = System.freeMemory();
  server.print("free memory: ");
  server.println(freemem);
}

void WebServerLaunch()
{
  /* setup our default command that will be run when the user accesses
   * the root page on the server */
  webserver.setDefaultCommand(&helloCmd);

  /* run the same command if you try to load /index.html, a common
   * default page name */
   webserver.addCommand("index.html", &helloCmd);
   webserver.addCommand("off", &offCmd);
   webserver.addCommand("on", &onCmd);

  /* start the webserver */
  webserver.begin();
}

void processWebServer()
{
  char buff[64];
  int len = 64;

  /* process incoming connections one at a time forever */
  webserver.processConnection(buff, &len);
}
1 Like

@Jerware
Thanks for replying so quickly - I have been building prototype boards and now back to software. :grinning:

I have built and flashed your example successfully. Just want to check I am understanding this correctly. To access the photon web server from say my Mac browser I just need to enter the URL as http://#last_ip_address/ where a $ curl https://api.particle.io/v1/devices?access_token\ will give me the IP address? My ISP is not finding the URL. How did you register your device IP address as “myPhoton.com”? I am missing something??

Thanks

It’s just like any of the other WebServer examples. You need to know your Photon’s local IP address on your LAN. You can either print that to the console if you’re using Particle Dev or check your router for a list of local devices.

To make it accessible from the Internet you’d need to open up a port on your home network and forward that port to the IP address of your Photon.

Got it. Works beautifully. Thanks for sharing.

Are there any particular limitations to this webserver solution you have come across or can think of?

I am thinking of using it as the basis for an admin console. I am not a javascript expert either - just wondering if there is an easier way to create the web pages, also, any ideas about how to implement some security for this - user ID and passcode that would then protect the remaining pages from unwanted hacking by students? :fearful:

You want to consult web experts, but it’s my impression that this is not a modern web server by any stretch. If you will require multiple users or security of any kind, I would suggest considering a Raspberry Pi or dedicated server. This Photon WebServer is light and simple, but could have good single-user intranet applications.