Add web server
This commit is contained in:
		
							parent
							
								
									655a9e34df
								
							
						
					
					
						commit
						1241a9b44d
					
				
							
								
								
									
										43
									
								
								server.go
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								server.go
									
									
									
									
									
								
							@ -2,13 +2,30 @@ package secondly
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GeertJohan/go.rice"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func startServer(addr string) {
 | 
					func startServer(addr string) {
 | 
				
			||||||
 | 
						staticHandler := http.FileServer(rice.MustFindBox("static").HTTPBox())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mux := http.NewServeMux()
 | 
						mux := http.NewServeMux()
 | 
				
			||||||
	mux.HandleFunc("/fields.json", fieldsHandler)
 | 
						mux.HandleFunc("/fields.json", fieldsHandler)
 | 
				
			||||||
 | 
						mux.HandleFunc("/save", saveHandler)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Static
 | 
				
			||||||
 | 
						mux.Handle("/app.js", staticHandler)
 | 
				
			||||||
 | 
						mux.Handle("/app.css", staticHandler)
 | 
				
			||||||
 | 
						mux.Handle("/config.html", staticHandler)
 | 
				
			||||||
 | 
						// Redirect from root to a static file. Ugly yet effective.
 | 
				
			||||||
 | 
						mux.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
 | 
							if req.RequestURI == "/" {
 | 
				
			||||||
 | 
								http.Redirect(rw, req, "/config.html", http.StatusMovedPermanently)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log.Println("Starting configuration server on", addr)
 | 
						log.Println("Starting configuration server on", addr)
 | 
				
			||||||
	go http.ListenAndServe(addr, mux)
 | 
						go http.ListenAndServe(addr, mux)
 | 
				
			||||||
@ -16,6 +33,30 @@ func startServer(addr string) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func fieldsHandler(rw http.ResponseWriter, req *http.Request) {
 | 
					func fieldsHandler(rw http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
	fields := extractFields(config, "")
 | 
						fields := extractFields(config, "")
 | 
				
			||||||
	body, _ := json.Marshal(fields)
 | 
						body, err := json.Marshal(fields)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rw.Write(body)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func saveHandler(rw http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
 | 
						cbody, err := ioutil.ReadAll(req.Body)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						updateConfig(cbody)
 | 
				
			||||||
 | 
						writeConfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resp := struct {
 | 
				
			||||||
 | 
							Success bool   `json:"success"`
 | 
				
			||||||
 | 
							Msg     string `json:"msg"`
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							Success: true,
 | 
				
			||||||
 | 
							Msg:     "Config successfully updated",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						body, _ := json.Marshal(resp)
 | 
				
			||||||
	rw.Write(body)
 | 
						rw.Write(body)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										67
									
								
								static/app.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								static/app.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					body {
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					* {
 | 
				
			||||||
 | 
					    line-height: 40px;
 | 
				
			||||||
 | 
					    font-size: 16px;
 | 
				
			||||||
 | 
					    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.container {
 | 
				
			||||||
 | 
					    margin: 50px 0 0 50px;
 | 
				
			||||||
 | 
					    font-weight: 400;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					h1 {
 | 
				
			||||||
 | 
					    font-size: 32px;
 | 
				
			||||||
 | 
					    font-weight: 400;
 | 
				
			||||||
 | 
					    line-height: 32px;
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					h2 {
 | 
				
			||||||
 | 
					    line-height: 40px;
 | 
				
			||||||
 | 
					    font-size: 18px;
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					    font-weight: 600;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					h3 {
 | 
				
			||||||
 | 
					    font-size: 18px;
 | 
				
			||||||
 | 
					    font-weight: 400;
 | 
				
			||||||
 | 
					    line-height: 30px;
 | 
				
			||||||
 | 
					    margin: 0 0 30px;
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					    color: #aaa;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					label {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    width: 100px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					input {
 | 
				
			||||||
 | 
					    font-size: 16px;
 | 
				
			||||||
 | 
					    padding: 0 5px;
 | 
				
			||||||
 | 
					    width: 250px;
 | 
				
			||||||
 | 
					    line-height: 26px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					button {
 | 
				
			||||||
 | 
					    float: left;
 | 
				
			||||||
 | 
					    margin: 20px 0;
 | 
				
			||||||
 | 
					    padding: 0 15px;
 | 
				
			||||||
 | 
					    line-height: 30px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.padding {
 | 
				
			||||||
 | 
					    float: left;
 | 
				
			||||||
 | 
					    width: 5px;
 | 
				
			||||||
 | 
					    height: 40px;
 | 
				
			||||||
 | 
					    margin: 0 15px 0 0;
 | 
				
			||||||
 | 
					    background-color: #ade;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#notice {
 | 
				
			||||||
 | 
					    margin: 15px 0 0 100px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.success {
 | 
				
			||||||
 | 
					    color: #0a0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.error {
 | 
				
			||||||
 | 
					    color: #a00;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										293
									
								
								static/app.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										293
									
								
								static/app.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,293 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Secondly: Configuration manager for Go language apps
 | 
				
			||||||
 | 
					 * Copyright (c) 2015 Gregory Eremin
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Source: https://github.com/localhots/secondly
 | 
				
			||||||
 | 
					 * Licence: https://github.com/localhots/secondly/blob/master/LICENSE
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function loadFields(callback) {
 | 
				
			||||||
 | 
					    var xhr = new XMLHttpRequest();
 | 
				
			||||||
 | 
					    xhr.open("GET", "/fields.json", true);
 | 
				
			||||||
 | 
					    xhr.onreadystatechange = function() {
 | 
				
			||||||
 | 
					        if (xhr.readyState === 4) {
 | 
				
			||||||
 | 
					            if (xhr.status === 200) {
 | 
				
			||||||
 | 
					                var fields = JSON.parse(xhr.responseText);
 | 
				
			||||||
 | 
					                callback(fields);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    xhr.send(null);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function saveFields(payload, callback) {
 | 
				
			||||||
 | 
					    var xhr = new XMLHttpRequest();
 | 
				
			||||||
 | 
					    xhr.open("POST", "/save", true);
 | 
				
			||||||
 | 
					    xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
 | 
				
			||||||
 | 
					    xhr.onreadystatechange = function() {
 | 
				
			||||||
 | 
					        if (xhr.readyState === 4) {
 | 
				
			||||||
 | 
					            if (xhr.status === 200) {
 | 
				
			||||||
 | 
					                callback(JSON.parse(xhr.responseText));
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                callback({"success": false, "msg": "Failed to save config"})
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    xhr.send(JSON.stringify(payload));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function drawForm(fields) {
 | 
				
			||||||
 | 
					    var elems = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var curLevel = 0;
 | 
				
			||||||
 | 
					    var titlesPrinted = {};
 | 
				
			||||||
 | 
					    for (var i = 0; i < fields.length; i++) {
 | 
				
			||||||
 | 
					        var field = fields[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var tokens = field.path.split(".");
 | 
				
			||||||
 | 
					        var section = tokens.slice(0, -1).join(".");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (section != "" && !titlesPrinted[section]) {
 | 
				
			||||||
 | 
					            titlesPrinted[section] = 1;
 | 
				
			||||||
 | 
					            elems.push({
 | 
				
			||||||
 | 
					                level: tokens.length - 1,
 | 
				
			||||||
 | 
					                nodes: [makeSectionNode("/"+ section)],
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elems.push({
 | 
				
			||||||
 | 
					            level: tokens.length - 1,
 | 
				
			||||||
 | 
					            nodes: makeFieldNode(field),
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render(elems);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function render(elems) {
 | 
				
			||||||
 | 
					    var fields = document.getElementById("fields");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (var i = 0; i < elems.length; i++) {
 | 
				
			||||||
 | 
					        var row = elems[i];
 | 
				
			||||||
 | 
					        var nodes = row.nodes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (var j = 0; j < row.level; j++) {
 | 
				
			||||||
 | 
					            nodes.unshift(makePaddingNode())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fields.appendChild(makeRow(nodes));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function makePaddingNode() {
 | 
				
			||||||
 | 
					    var div = document.createElement("div");
 | 
				
			||||||
 | 
					    div.setAttribute("class", "padding");
 | 
				
			||||||
 | 
					    return div;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function makeRow(nodes) {
 | 
				
			||||||
 | 
					    var div = document.createElement("div");
 | 
				
			||||||
 | 
					    div.setAttribute("class", "row");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (var i = 0; i < nodes.length; i++) {
 | 
				
			||||||
 | 
					        div.appendChild(nodes[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return div;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function makeFieldNode(field) {
 | 
				
			||||||
 | 
					    var formGroup = [],
 | 
				
			||||||
 | 
					        label = makeLabelNode(field.path, field.name),
 | 
				
			||||||
 | 
					        input = document.createElement("input");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    input.setAttribute("id", field.path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (field.kind !== "bool") {
 | 
				
			||||||
 | 
					        input.value = field.value;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        if (field.value) {
 | 
				
			||||||
 | 
					            input.setAttribute("checked", "checked");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    input.setAttribute("data-type", field.kind);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (field.kind) {
 | 
				
			||||||
 | 
					    case "string":
 | 
				
			||||||
 | 
					        input.setAttribute("type", "text");
 | 
				
			||||||
 | 
					        formGroup.push(label);
 | 
				
			||||||
 | 
					        formGroup.push(input);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "bool":
 | 
				
			||||||
 | 
					        input.setAttribute("type", "checkbox");
 | 
				
			||||||
 | 
					        label.innerHTML = "";
 | 
				
			||||||
 | 
					        label.appendChild(document.createTextNode(field.name));
 | 
				
			||||||
 | 
					        formGroup.push(label);
 | 
				
			||||||
 | 
					        formGroup.push(input);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "int":
 | 
				
			||||||
 | 
					    case "int8":
 | 
				
			||||||
 | 
					    case "int16":
 | 
				
			||||||
 | 
					    case "int32":
 | 
				
			||||||
 | 
					    case "int64":
 | 
				
			||||||
 | 
					    case "uint":
 | 
				
			||||||
 | 
					    case "uint8":
 | 
				
			||||||
 | 
					    case "uint16":
 | 
				
			||||||
 | 
					    case "uint32":
 | 
				
			||||||
 | 
					    case "uint64":
 | 
				
			||||||
 | 
					    case "float32":
 | 
				
			||||||
 | 
					    case "float64":
 | 
				
			||||||
 | 
					        input.setAttribute("type", "number");
 | 
				
			||||||
 | 
					        switch (field.kind) {
 | 
				
			||||||
 | 
					        case "int8":
 | 
				
			||||||
 | 
					            input.setAttribute("min", "-128");
 | 
				
			||||||
 | 
					            input.setAttribute("max", "127");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "int16":
 | 
				
			||||||
 | 
					            input.setAttribute("min", "-32768");
 | 
				
			||||||
 | 
					            input.setAttribute("max", "32767");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "int32":
 | 
				
			||||||
 | 
					            input.setAttribute("min", "-2147483648");
 | 
				
			||||||
 | 
					            input.setAttribute("max", "2147483647");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "int": // Assuming x86-64 architecture
 | 
				
			||||||
 | 
					        case "int64":
 | 
				
			||||||
 | 
					            input.setAttribute("min", "-9223372036854775808");
 | 
				
			||||||
 | 
					            input.setAttribute("max", "9223372036854775807");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "uint8":
 | 
				
			||||||
 | 
					            input.setAttribute("min", "0");
 | 
				
			||||||
 | 
					            input.setAttribute("max", "255");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "uint16":
 | 
				
			||||||
 | 
					            input.setAttribute("min", "0");
 | 
				
			||||||
 | 
					            input.setAttribute("max", "65535");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "uint32":
 | 
				
			||||||
 | 
					            input.setAttribute("min", "0");
 | 
				
			||||||
 | 
					            input.setAttribute("max", "4294967295");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "uint": // Assuming x86-64 architecture
 | 
				
			||||||
 | 
					        case "uint64":
 | 
				
			||||||
 | 
					            input.setAttribute("min", "0");
 | 
				
			||||||
 | 
					            input.setAttribute("max", "18446744073709551615");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "float32":
 | 
				
			||||||
 | 
					        case "float64":
 | 
				
			||||||
 | 
					            input.setAttribute("step", "any");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        formGroup.push(label);
 | 
				
			||||||
 | 
					        formGroup.push(input);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        console.log("Invalid field type: "+ field.kind, field.path)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return formGroup;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function makeSectionNode(section) {
 | 
				
			||||||
 | 
					    var h2 = document.createElement("h2"),
 | 
				
			||||||
 | 
					        contents = document.createTextNode(section);
 | 
				
			||||||
 | 
					    h2.appendChild(contents);
 | 
				
			||||||
 | 
					    return h2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function makeDivNode(classes) {
 | 
				
			||||||
 | 
					    var div = document.createElement("div");
 | 
				
			||||||
 | 
					    div.setAttribute("class", classes);
 | 
				
			||||||
 | 
					    return div;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function makeLabelNode(forId, text) {
 | 
				
			||||||
 | 
					    var label = document.createElement("label"),
 | 
				
			||||||
 | 
					        contents = document.createTextNode(text);
 | 
				
			||||||
 | 
					    label.setAttribute("for", forId);
 | 
				
			||||||
 | 
					    label.appendChild(contents);
 | 
				
			||||||
 | 
					    return label;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function makePayload(elems) {
 | 
				
			||||||
 | 
					    var payload = {};
 | 
				
			||||||
 | 
					    for (path in elems) {
 | 
				
			||||||
 | 
					        var value = elems[path],
 | 
				
			||||||
 | 
					            tokens = path.split('.'),
 | 
				
			||||||
 | 
					            parents = tokens.slice(0, -1),
 | 
				
			||||||
 | 
					            key = tokens.slice(-1)[0],
 | 
				
			||||||
 | 
					            parent = payload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (var i = 0; i < parents.length; i++) {
 | 
				
			||||||
 | 
					            var pkey = parents[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!parent[pkey]) {
 | 
				
			||||||
 | 
					                parent[pkey] = {}
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            parent = parent[pkey];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parent[key] = value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return payload;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					document.getElementById("config").addEventListener("submit", function(e){
 | 
				
			||||||
 | 
					    e.preventDefault();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var elems = {},
 | 
				
			||||||
 | 
					        inputs = document.getElementsByTagName("input");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (var i = 0; i < inputs.length; i++) {
 | 
				
			||||||
 | 
					        var input = inputs[i],
 | 
				
			||||||
 | 
					            type = input.getAttribute("data-type"),
 | 
				
			||||||
 | 
					            path = input.getAttribute("id"),
 | 
				
			||||||
 | 
					            value = input.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (type) {
 | 
				
			||||||
 | 
					        case "string":
 | 
				
			||||||
 | 
					            elems[path] = value;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "bool":
 | 
				
			||||||
 | 
					            elems[path] = input.checked;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "int":
 | 
				
			||||||
 | 
					        case "int8":
 | 
				
			||||||
 | 
					        case "int16":
 | 
				
			||||||
 | 
					        case "int32":
 | 
				
			||||||
 | 
					        case "int64":
 | 
				
			||||||
 | 
					        case "uint":
 | 
				
			||||||
 | 
					        case "uint8":
 | 
				
			||||||
 | 
					        case "uint16":
 | 
				
			||||||
 | 
					        case "uint32":
 | 
				
			||||||
 | 
					        case "uint64":
 | 
				
			||||||
 | 
					            elems[path] = parseInt(value, 10);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "float32":
 | 
				
			||||||
 | 
					        case "float64":
 | 
				
			||||||
 | 
					            elems[path] = parseFloat(value);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    saveFields(makePayload(elems), function(resp){
 | 
				
			||||||
 | 
					        var notice = document.getElementById("notice");
 | 
				
			||||||
 | 
					        notice.innerHTML = resp.msg;
 | 
				
			||||||
 | 
					        if (resp.success) {
 | 
				
			||||||
 | 
					            notice.setAttribute("class", "success");
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            notice.setAttribute("class", "error");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        notice.style.display = "block";
 | 
				
			||||||
 | 
					        window.setTimeout(function() {
 | 
				
			||||||
 | 
					            notice.style.display = "none";
 | 
				
			||||||
 | 
					        }, 2000);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					loadFields(drawForm);
 | 
				
			||||||
							
								
								
									
										25
									
								
								static/config.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								static/config.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="utf-8">
 | 
				
			||||||
 | 
					    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
				
			||||||
 | 
					    <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
				
			||||||
 | 
					    <title>Application Configuration</title>
 | 
				
			||||||
 | 
					    <link rel="stylesheet" href="/app.css">
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					    <h1>Secondly<h1>
 | 
				
			||||||
 | 
					    <h3>Application Configuration</h3>
 | 
				
			||||||
 | 
					    <form id="config">
 | 
				
			||||||
 | 
					        <div id="fields"></div>
 | 
				
			||||||
 | 
					        <button type="submit" class="btn btn-default">Save</button>
 | 
				
			||||||
 | 
					        <div id="notice"></div>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script src="/app.js"></script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user