Search code examples
configurationwebserveresp8266

How to dynamic change <INPUT Value="...> in a web page on a client


I work on a web based configuration interface between a ESP8266 based sever and a client (firefox). The page is based on a encapsulated table with tags. An has an attribute value=" " which allows to give the name=" " attribute a predefined value. This value is displayed in a page and can be changed by the uses and send back to the server as config data upon a Summit. The page is stored in PROGMEM and I can not access the value=" " attributes in order to update them in case the new entered config data changes them.

== My question is: Is there and if so what is the method to GET this fixed in PROGMEM stored page to the client with updated config data.

== If there is no method to do this what is the best way to display an PROGMEM based web page with dynamic config data.

Config page with some predefined values

<FORM action="/" method="post" id="userform">
<table Class="TR1">			
<Caption Class="CAP"> 		Product characteristics	</Caption>
<thead class="TR1">			
<tr>			
	<Th class="TH1">	Group	</Th>
	<Th class="TH2">	Parameter	</Th>
	<Th class="TH3">	Value	</Th>
	<Th class="TH4">	Type	</Th>
	<Th class="TH5">	Subval	</Th>
	<Th class="TH5">		</Th>
	<Th class="TH5">		</Th>
</TR>						
</Thead>			
<tbody class="TR1">			
<tr class="TR1">			
	<Td class="TD1">	Network	</TD>
	<Td class="TD2">	SSID	</TD>
	<Td class="TD3">	<input type="text"  name="ssid" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Password	</TD>
	<Td class="TD3">	<input type="password"  name="password" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Encryption	</TD>
	<Td class="TD3">	<input list="encrypcion"  name="encrypcion" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Key nr	</TD>
	<Td class="TD3">	<input type="number" name="keynr" min="1" max="4" value="1" step="1" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	IPaddess	</TD>
	<Td class="TD3">	<input type="text"  name="IPaddess" value="192.168.1.xxx" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	DHCP	</TD>
	<Td class="TD3">	Yes: <INPUT type="radio" name="DHCP" value="1"> &nbsp &nbsp No: <INPUT type="radio" name="DHCP" value="0"> 	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>						
<tr class="TR1">			
	<Td class="TD1">	Serial	</TD>
	<Td class="TD2">	Port nr	</TD>
	<Td class="TD3">	<input type="number" name="sprt" min="1" max="4" value="1" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Baud rate	</TD>
	<Td class="TD3">	<input list="baudrate" name="baudrate">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Serial frame	</TD>
	<Td class="TD3">	<input list="sframe" name="sframe">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>						
<tr class="TR1">			
	<Td class="TD1">	Calendar	</TD>
	<Td class="TD2">	Time	</TD>
	<Td class="TD3">	<input type="text"  name="time" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Date	</TD>
	<Td class="TD3">	<input type="text"  name="date" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Alarm 1	</TD>
	<Td class="TD3">	<input type="text"  name="alarm1" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Alarm 2	</TD>
	<Td class="TD3">	<input type="text"  name="alarm2" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
			
<tr class="TR1">			
	<Td class="TD1">	MQTT	</TD>
	<Td class="TD2">	User	</TD>
	<Td class="TD3">	<input type="text"  name="user" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Pasword	</TD>
	<Td class="TD3">	<input type="password"  name="password" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Server	</TD>
	<Td class="TD3">	<input type="text"  name="server" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Port	</TD>
	<Td class="TD3">	<input type="number" name="mqttprt" min="1880" value="1883" step="1" placeholder=1883 onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Topic 1	</TD>
	<Td class="TD3">	<input type="text"  name="topic1" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">	Type	</TD>
	<Td class="TD5">	<input list="ttype" name="ttype">	</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Topic 2	</TD>
	<Td class="TD3">	<input type="text"  name="topic2" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">	Type	</TD>
	<Td class="TD5">	<input list="ttype" name="ttype">	</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Topic 3	</TD>
	<Td class="TD3">	<input type="text"  name="topic3" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">	Type	</TD>
	<Td class="TD5">	<input list="ttype" name="ttype">	</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
<tr class="TR1">			
	<Td class="TD1">		</TD>
	<Td class="TD2">	Topic 4	</TD>
	<Td class="TD3">	<input type="text"  name="topic4" onkeypress="if (event.keyCode == 13) { return false;}">	</TD>
	<Td class="TD4">	Type	</TD>
	<Td class="TD5">	<input list="ttype" name="ttype">	</TD>
	<Td class="TD5">		</TD>
	<Td class="TD5">		</TD>
</TR>			
			
</tbody>			
<tfoot>			
<tr class="FT1">			
	<td colspan="7">	EOT	</td>
</tr>			
</tfoot>			
</TABLE>			
<INPUT type="submit" value="Send"> <INPUT type="reset">
</FORM>
</body>
</html>


Solution

  • You could have your ESP8266 serve up an additional JavaScript file which simply set some global variables. This file would be re-created from the config values by the ESP8266 each time it is requested.

    So when the browser makes a request: GET /config.js HTTP/1.1

    The server responds with:

    window.config = {
      ssid: "my network ssid",
      password: "my network password",
      //... continue with other config values
    };
    

    Make sure you include a script tag in your html to make the browser fetch the JS file. In order to set the initial value of the <input> tags, you might use a bit more JS:

    <body>
      ...
      <!-- put this at the end of your HTML <body> -->
      <script src="/config.js"></script>
      <!-- now you can access your `window.config` in javascript -->
    
      <script>
      var inputs = document.getElementsByTagName('input');
    
      for (var i = 0; i < inputs.length; i++) {
        var input = inputs[i];
        // make sure names used in config.js match an input's `name` attribute
        input.value = window.config[input.name]; 
      }
      </script>
    </body>
    

    In summary, you serve a static (never changing) HTML document that is stored in PROGMEM.

    1. When the browser loads the page, and the <table> is rendered, but all the <input> elements initially have blank values.
    2. The browser sees <script src="/config.js"> and goes back to the server to get config.js.
    3. The ESP8266 constructs config.js and sends it to the browser.
    4. The browser runs config.js, which stores some values in window.config.
    5. The final runs and sets the values of the <input> elements.

    Feel free to comment if you get stuck. Hope this helps!