[Solved] JavaScript POST Button

Hello everyone,

To start, I am more of a hardware person, but have recently taken a large interest in the software side of things, so please forgive the n00b question that follows. At the moment, my current Core project is in home automation — proximity light switches, door controls, motion sensors, etc. I have the code written and uploaded to each of my Cores for their respective tasks and it works as expected. I’ve been able to use the terminal to POST to each of the Cores, but am now trying to create a web interface where I can click a button to turn on the lights, open a door, etc. My question is how do I write a JavaScript button to perform a POST request to a Core?

I’ve searched for examples to do this, but after trying to implement it, nothing happens when the button is clicked. Can anyone provide a pseudo-code example of such a button?

Thank you very much for your help with my n00bish question!

If you want to use a post but don’t want to actually post the Web form back. Use XMLHttpRequest (or if you’ve got jQuery available use their Ajax.post method as it takes all the legwork out of XMLHttpRequest and provides a promise with nice error handling ).

I can’t provide code samples right now as I’m on mobile but check out

http://api.jquery.com/jQuery.ajax/

@turkeywelder Thanks! I’ll check it out this afternoon.

@turkeywelder I am working on something similar as @gaudsend, am have been researching how to use the Spark API. However, I am having trouble understanding were to add the Spark API calls to my the JavaScipt buttons.

I read you post and I saw that you may have an example of how to incorporate the Spark API. If so, it would be greatly appreciated if yo could post an it.

I think my simple Remote Starter app will be helpful to you guys:

Also check out the justGauge Demo in the repo for some extra fanciness.

Thanks, @BDub! That is very informative. I am still a little stuck. Here is the button code I am working with:

    <script type="text/javascript">
    function send(led, pulse){
	var coreID = "1234567890...";
	var accessToken = "abcdefghijklmnopqrstuvwxyz";
	var url = "https://api.spark.io/v1/devices/" + coreID + "/led";
	
        $.ajax({
          type: "POST",
          url: url,
          data: {
            access_token: accessToken,
            args: "pulse"
          },
	    });
  }
</script>

From my understanding of the app you posted, in the url line, I would replace the “method” with the appropriate funcKey…in this case “led”. Similarly, the “data” would be replaced with what I want to POST e.g. “pulse”. I’m probably missing something as when I click the button, nothing happens on the hardware side (the LEDs should pulse). My button is simply:

<button onclick="send(led, pulse)">Lights!</button>

Also, this is the portion of the Core sketch to which the POST will be made:

int ledControl(String command){
    if(command.substring(0,5) == "pulse"){
    pulse();
    }}

Thank you very much for the help!

Lots of ways to debug this... step one would be put something in that function that runs no matter what argument you get, like turning on the D7 led

int ledControl(String command){
    pinMode(D7, OUTPUT);
    digitalWrite(D7, HIGH);
    if(command.substring(0,5) == "pulse"){
     pulse();
    }
    return 200;
}

I also added a return 200; statement. This will help on the Client (sending) side of your app. If you can monitor the returned value, you can tell if it's entering with the LED and exiting your function. Alternatively you can declare pinMode() in your setup() and define a boolean variable for your D7 output state that you toggle every time through the function (recommended).

Also if you monitor from the Client side, you can add console.log("TEST 1"); console.log("TEST 2");,etc.. to various parts of your code to see if that code is executing. On Chrome and Firefox you press F12 to bring up the Web Developer tools. Then click Console to monitor the test statements. Or Network to monitor the sent and returned HTTP requests.

Other than that the code looks like it should work to me, even the indexs of the command.substring looks right.

Thanks for the help, @BDub! I’ll check out those suggestions when I get home, and report back this evening.

Marking this as [SOLVED]. The issue was apparently conflicting arguments in the button declaration and in the send() function. That is, the button was coded as:

<button onclick="send(led, pulse)">Lights!</button>

and the function itself was:

function send(led, pulse) { 
 //some code here
}

I removed the “led” and “pulse” arguments from both lines and implemented the debugging suggestions from @BDub. The button now operates as intended!

Thanks for the help.

1 Like

Awexome! Glad you got it working, now you can play!

1 Like

Hello gaudsend -
I wonder if I could ask you to post the full page of your HTML/javascript code for the button (obviously minus your ID and a access code). I am also a javascript Noob and when I tried just copying the code in this thread, I get an error (Uncaught ReferenceError: $ is not defined ) so I am missing something obvious - perhaps about initialization.
My code works fine when using curl from the terminal - I just can’t figure out how to format the URL so I can use it inside a button via a web page.
Thanks.

@longarc sure! The full page has several commented-out sections as I’m still working on finalizing that code, but the buttons and functions all work.

<body>
	<span id="lights"></span><br />
	<span id="tstamp"></span>

	<br /><br />
	<button id="Button-1" onclick="start()">Button 1</button>
	<br /><br />
	<button id="Button-2" onclick="send()">Button 2</button>
    

	<script type="text/javascript">
	//begin{Editable User Data}-----------------------------------------------------------------------------
	var appHeading = "Led Control";
	
	//Core & API Information
	var core1ID = "123412341324134";
	var core2ID = "123412341341234";
	var accessToken = "asdfasdfadsfadsf123412341324";
	var baseURL = "https://api.spark.io/v1/devices/";
		
	var btn1Label = "Connect";
	var btn2Label1 = "Turn lights on!";
	var btn2Label2 = "Turn lights off.";
	var btn2Label3 = "Toggle lights!";
	
	//Timing
	var pageLoad = new Boolean(true);
	var refreshTimer = setTimeout(function(){refreshCheck()},2250);
	var refreshOK = new Boolean(false);
	//var variableRefresh = setInterval(function(){getVariable()},2250);
	
	
	function start() {
		document.getElementById("lights").innerHTML = "Waiting for data...";
		var eventSource = new EventSource(baseURL + core1ID + "/events/?access_token=" + accessToken);
	
			eventSource.addEventListener('open', function(e) {console.log("Opened!"); }, false);
			eventSource.addEventListener('error', function(e) {console.log("Errored!"); }, false);
			eventSource.addEventListener('Lights', function(e) {
				var parsedData = JSON.parse(e.data);
				var tempSpan = document.getElementById("lights");
				var tsSpan = document.getElementById("tstamp");
				tempSpan.innerHTML = "Core: " + parsedData.coreid + " lights: " + parsedData.data;
					tempSpan.style.fontSize = "28px";
					tsSpan.innerHTML = "at timestamp " + parsedData.published_at;
					tsSpan.style.fontSize = "9px";
			}, false);
	}

	function send(){
		if(pageLoad == true || refreshOK.valueOf()==true){
			var POSTurl = baseURL + core1ID + "/led";
	
      		$.ajax({
        		type: "POST",
        		url: POSTurl,
        		data: {
          		access_token: accessToken,
          		args: "pulse"
        		},
	  		});
			refreshOK = Boolean(false);
			clearTimeout(refreshTimer);
			refreshTimer = setTimeout(function(){refreshCheck()},2250);	
		}
	}
	//end{Editable User Data}---------------------------------------------------------------------------------
	
	function refreshCheck(){
		pageLoad = Boolean(false);
		refreshOK = Boolean(true);
	}
	
	function getVariable(LED_D7){
		var GETurl = baseURL + core1ID + "/LED_D7?access_token=" + accessToken;
      	$.ajax({
        	url: GETurl,
			dataType: "json",
			success: function(data){
				console.log(data);
				//buttonLabelChange(data)
			}
		});
	}
	
	/*function buttonLabelChange(obj){
		if(obj == 0){
			$("#Button-2").html(btn2Label1);
		}
		else{
			$("#Button-2").html(btn2Label2);
		};
	}*/
	
	$("#app-heading").html(appHeading);
	
	(btn1Label) ? $("#Button-1").html(btn1Label) : $("#Button-1").hide();
    (btn2Label3) ? $("#Button-2").html(btn2Label3) : $("#Button-2").hide();
	</script>
    
</body>

That’s the main . The head is pretty standard with only a few changes to format based on device screen size. the ‘send()’ function is the POST request implementation. The ‘getVariable()’ function is the GET request which I’ll eventually be implementing to determine the initial button labels i.e. “turn lights on/off” based on the current lighting state on the Core side.

I hope this helps, and please feel free to ask if you have any questions!

1 Like

@gaudsend - Thanks for the quick reply. Got the same error so I poked around and realized I hadn’t installed jQuery. Duh.

1 Like

Might be old and not of great use but I put up a small lib on GitHub called sparkjs. It’s just enough javascript to pull variables and make function calls from your browser to the cores. Check it out, let me know if it’s useful.

https://github.com/uchobby/sparkjs

2 Likes

I just moved the GitHub for this and renamed it to sparkio-client to avoid confusion with the existing sparkjs lib meant for server side nodejs use.

1 Like