";
+ for (var i = 0; i < 9; i++) {
+ const entry = control_macrolist[i];
+ content += control_build_macro_button(i, entry);
+ actions.push({ id: `control_macro_${i}`, type: "click", method: (event) => macro_command(entry.target, entry.filename) });
+ }
+ id("Macro_list").innerHTML = content;
+ actions.forEach((action) => {
+ id(action.id).addEventListener(action.type, (event) => action.method);
+ });
}
function macro_command(target, filename) {
- var cmd = ""
- if (target == "ESP") {
- cmd = "$LocalFS/Run=" + filename;
- } else if (target == "SD") {
- files_print_filename(filename);
- } else if (target == "URI") {
- window.open(filename);
- } else return;
- //console.log(cmd);
- SendPrinterCommand(cmd);
+ switch (target) {
+ case "ESP": SendPrinterCommand(`$LocalFS/Run=${filename}`); break;
+ case "SD": files_print_filename(filename); break;
+ case "URI": window.open(filename); break;
+ default: break; // do nothing
+ }
}
diff --git a/www/js/grblpanel.js b/www/js/grblpanel.js
index 252ece0c..65b1fe1b 100644
--- a/www/js/grblpanel.js
+++ b/www/js/grblpanel.js
@@ -30,8 +30,8 @@ const grblpanel = () => {
id("grblpanel_flood").addEventListener("click", (event) => SendRealtimeCmd(0xa0));
id("grblpanel_mist").addEventListener("click", (event) => SendRealtimeCmd(0xa1));
- id("grblspindle_fwd").addEventListener("click", (event) => SendPrinterCommand(`M3 S${common.spindleTabSpindleSpeed}`, false, null, null, 1, 1,));
- id("grblspindle_rew").addEventListener("click", (event) => SendPrinterCommand(`M4 S${common.spindleTabSpindleSpeed}`, false, null, null, 1, 1,));
+ id("grblspindle_fwd").addEventListener("click", (event) => SendPrinterCommand(`M3 S${spindleTabSpindleSpeed}`, false, null, null, 1, 1,));
+ id("grblspindle_rew").addEventListener("click", (event) => SendPrinterCommand(`M4 S${spindleTabSpindleSpeed}`, false, null, null, 1, 1,));
id("grblspindle_off").addEventListener("click", (event) => SendPrinterCommand("M5 S0", false, null, null, 1, 1));
id("grblspindle_rpm").addEventListener("change", (event) => setSpindleSpeed(event.value));
id("grblspindle_rpm").addEventListener("keyup", (event) => setSpindleSpeed(event.value));
diff --git a/www/js/http.js b/www/js/http.js
index a982839c..410bb898 100644
--- a/www/js/http.js
+++ b/www/js/http.js
@@ -80,8 +80,7 @@ function AddCmd(cmd_fn, id) {
http_errorfn(999, translate_text_item("Server not responding"));
return;
}
- var cmd_id = 0;
- if (typeof id != 'undefined') cmd_id = id;
+ const cmd_id = (typeof id !== 'undefined') ? id : 0;
//console.log("adding command");
var cmd = {
cmd: cmd_fn,
diff --git a/www/js/preferencesdlg.js b/www/js/preferencesdlg.js
index b7487fd9..cfd56166 100644
--- a/www/js/preferencesdlg.js
+++ b/www/js/preferencesdlg.js
@@ -289,13 +289,13 @@ function applypreferenceslist() {
}
id('preferences_pos_Interval_check').value = Number.parseInt(preferenceslist[0].interval_positions);
- id('preferences_control_xy_velocity').value = Number.parseInt(preferenceslist[0].xy_feedrate);
- id('preferences_control_z_velocity').value = Number.parseInt(preferenceslist[0].z_feedrate);
+ id('preferences_control_xy_velocity').value = Number.parseFloat(preferenceslist[0].xy_feedrate);
+ id('preferences_control_z_velocity').value = Number.parseFloat(preferenceslist[0].z_feedrate);
- if (grblaxis > 2) axis_Z_feedrate = Number.parseInt(preferenceslist[0].z_feedrate);
- if (grblaxis > 3) axis_A_feedrate = Number.parseInt(preferenceslist[0].a_feedrate);
- if (grblaxis > 4) axis_B_feedrate = Number.parseInt(preferenceslist[0].b_feedrate);
- if (grblaxis > 5) axis_C_feedrate = Number.parseInt(preferenceslist[0].c_feedrate);
+ if (grblaxis > 2) axis_Z_feedrate = Number.parseFloat(preferenceslist[0].z_feedrate);
+ if (grblaxis > 3) axis_A_feedrate = Number.parseFloat(preferenceslist[0].a_feedrate);
+ if (grblaxis > 4) axis_B_feedrate = Number.parseFloat(preferenceslist[0].b_feedrate);
+ if (grblaxis > 5) axis_C_feedrate = Number.parseFloat(preferenceslist[0].c_feedrate);
if (grblaxis > 3) {
const letter = id('control_select_axis').value;
@@ -316,7 +316,7 @@ function applypreferenceslist() {
}
id('preferences_probemaxtravel').value = Number.parseFloat(preferenceslist[0].probemaxtravel);
- id('preferences_probefeedrate').value = Number.parseInt(preferenceslist[0].probefeedrate);
+ id('preferences_probefeedrate').value = Number.parseFloat(preferenceslist[0].probefeedrate);
id('preferences_proberetract').value = Number.parseFloat(preferenceslist[0].proberetract);
id('preferences_probetouchplatethickness').value = Number.parseFloat(preferenceslist[0].probetouchplatethickness);
build_file_filter_list(preferenceslist[0].f_filters);
@@ -405,31 +405,31 @@ function build_dlg_preferences_list() {
} else id('preferences_status_Interval_check').value = Number.parseInt(default_preferenceslist[0].interval_status);
//xy feedrate
if (typeof (preferenceslist[0].xy_feedrate) !== 'undefined') {
- id('preferences_control_xy_velocity').value = Number.parseInt(preferenceslist[0].xy_feedrate);
- } else id('preferences_control_xy_velocity').value = Number.parseInt(default_preferenceslist[0].xy_feedrate);
+ id('preferences_control_xy_velocity').value = Number.parseFloat(preferenceslist[0].xy_feedrate);
+ } else id('preferences_control_xy_velocity').value = Number.parseFloat(default_preferenceslist[0].xy_feedrate);
if (grblaxis > 2) {
//z feedrate
if (typeof (preferenceslist[0].z_feedrate) !== 'undefined') {
- id('preferences_control_z_velocity').value = Number.parseInt(preferenceslist[0].z_feedrate);
- } else id('preferences_control_z_velocity').value = Number.parseInt(default_preferenceslist[0].z_feedrate);
+ id('preferences_control_z_velocity').value = Number.parseFloat(preferenceslist[0].z_feedrate);
+ } else id('preferences_control_z_velocity').value = Number.parseFloat(default_preferenceslist[0].z_feedrate);
}
if (grblaxis > 3) {
//a feedrate
if (typeof (preferenceslist[0].a_feedrate) !== 'undefined') {
- id('preferences_control_a_velocity').value = Number.parseInt(preferenceslist[0].a_feedrate);
- } else id('preferences_control_a_velocity').value = Number.parseInt(default_preferenceslist[0].a_feedrate);
+ id('preferences_control_a_velocity').value = Number.parseFloat(preferenceslist[0].a_feedrate);
+ } else id('preferences_control_a_velocity').value = Number.parseFloat(default_preferenceslist[0].a_feedrate);
}
if (grblaxis > 4) {
//b feedrate
if (typeof (preferenceslist[0].b_feedrate) !== 'undefined') {
- id('preferences_control_b_velocity').value = Number.parseInt(preferenceslist[0].b_feedrate);
- } else id('preferences_control_b_velocity').value = Number.parseInt(default_preferenceslist[0].b_feedrate);
+ id('preferences_control_b_velocity').value = Number.parseFloat(preferenceslist[0].b_feedrate);
+ } else id('preferences_control_b_velocity').value = Number.parseFloat(default_preferenceslist[0].b_feedrate);
}
if (grblaxis > 5) {
//c feedrate
if (typeof (preferenceslist[0].c_feedrate) !== 'undefined') {
- id('preferences_control_c_velocity').value = Number.parseInt(preferenceslist[0].c_feedrate);
- } else id('preferences_control_c_velocity').value = Number.parseInt(default_preferenceslist[0].c_feedrate);
+ id('preferences_control_c_velocity').value = Number.parseFloat(preferenceslist[0].c_feedrate);
+ } else id('preferences_control_c_velocity').value = Number.parseFloat(default_preferenceslist[0].c_feedrate);
}
//probemaxtravel
@@ -440,8 +440,8 @@ function build_dlg_preferences_list() {
}
//probefeedrate
if ((typeof (preferenceslist[0].probefeedrate) !== 'undefined') && (preferenceslist[0].probefeedrate.length !== 0)) {
- id('preferences_probefeedrate').value = Number.parseInt(preferenceslist[0].probefeedrate);
- } else id('preferences_probefeedrate').value = Number.parseInt(default_preferenceslist[0].probefeedrate);
+ id('preferences_probefeedrate').value = Number.parseFloat(preferenceslist[0].probefeedrate);
+ } else id('preferences_probefeedrate').value = Number.parseFloat(default_preferenceslist[0].probefeedrate);
//proberetract
if ((typeof (preferenceslist[0].proberetract) !== 'undefined') && (preferenceslist[0].proberetract.length !== 0)) {
id('preferences_proberetract').value = Number.parseFloat(preferenceslist[0].proberetract);
@@ -544,22 +544,22 @@ function closePreferencesDialog() {
//interval status
if (id('preferences_status_Interval_check').value !== Number.parseInt(preferenceslist[0].interval_status)) modified = true;
//xy feedrate
- if (id('preferences_control_xy_velocity').value !== Number.parseInt(preferenceslist[0].xy_feedrate)) modified = true;
+ if (id('preferences_control_xy_velocity').value !== Number.parseFloat(preferenceslist[0].xy_feedrate)) modified = true;
if (grblaxis > 2) {
//z feedrate
- if (id('preferences_control_z_velocity').value !== Number.parseInt(preferenceslist[0].z_feedrate)) modified = true;
+ if (id('preferences_control_z_velocity').value !== Number.parseFloat(preferenceslist[0].z_feedrate)) modified = true;
}
if (grblaxis > 3) {
//a feedrate
- if (id('preferences_control_a_velocity').value !== Number.parseInt(preferenceslist[0].a_feedrate)) modified = true;
+ if (id('preferences_control_a_velocity').value !== Number.parseFloat(preferenceslist[0].a_feedrate)) modified = true;
}
if (grblaxis > 4) {
//b feedrate
- if (id('preferences_control_b_velocity').value !== Number.parseInt(preferenceslist[0].b_feedrate)) modified = true;
+ if (id('preferences_control_b_velocity').value !== Number.parseFloat(preferenceslist[0].b_feedrate)) modified = true;
}
if (grblaxis > 5) {
//c feedrate
- if (id('preferences_control_c_velocity').value !== Number.parseInt(preferenceslist[0].c_feedrate)) modified = true;
+ if (id('preferences_control_c_velocity').value !== Number.parseFloat(preferenceslist[0].c_feedrate)) modified = true;
}
}
//autoscroll
@@ -571,7 +571,7 @@ function closePreferencesDialog() {
//probemaxtravel
if (id('preferences_probemaxtravel').value !== Number.parseFloat(preferenceslist[0].probemaxtravel)) modified = true;
//probefeedrate
- if (id('preferences_probefeedrate').value !== Number.parseInt(preferenceslist[0].probefeedrate)) modified = true;
+ if (id('preferences_probefeedrate').value !== Number.parseFloat(preferenceslist[0].probefeedrate)) modified = true;
//proberetract
if (id('preferences_proberetract').value !== Number.parseFloat(preferenceslist[0].proberetract)) modified = true;
//probetouchplatethickness
@@ -725,51 +725,51 @@ function Checkvalues(id_2_check) {
}
break;
case "preferences_control_xy_velocity":
- value = Number.parseInt(id(id_2_check).value);
- if (!(!Number.isNaN(value) && value >= 1)) {
- error_message = translate_text_item("XY Feedrate value must be at least 1 mm/min!");
+ value = Number.parseFloat(id(id_2_check).value);
+ if (!(!Number.isNaN(value) && value >= 0.00001)) {
+ error_message = translate_text_item("XY Feedrate value must be at least 0.00001 mm/min!");
status = false;
}
break;
case "preferences_control_z_velocity":
- value = Number.parseInt(id(id_2_check).value);
- if (!(!Number.isNaN(value) && value >= 1)) {
- error_message = translate_text_item("Z Feedrate value must be at least 1 mm/min!");
+ value = Number.parseFloat(id(id_2_check).value);
+ if (!(!Number.isNaN(value) && value >= 0.00001)) {
+ error_message = translate_text_item("Z Feedrate value must be at least 0.00001 mm/min!");
status = false;
}
break;
case "preferences_control_a_velocity":
case "preferences_control_b_velocity":
case "preferences_control_c_velocity":
- value = Number.parseInt(id(id_2_check).value);
- if (!(!Number.isNaN(value) && value >= 1)) {
- error_message = translate_text_item("Axis Feedrate value must be at least 1 mm/min!");
+ value = Number.parseFloat(id(id_2_check).value);
+ if (!(!Number.isNaN(value) && value >= 0.00001)) {
+ error_message = translate_text_item("Axis Feedrate value must be at least 0.00001 mm/min!");
status = false;
}
break;
case "preferences_probefeedrate":
- value = Number.parseInt(id(id_2_check).value);
- if (!(!Number.isNaN(value) && value >= 1 && value <= 9999)) {
- error_message = translate_text_item("Value of probe feedrate must be between 1 mm/min and 9999 mm/min !");
+ value = Number.parseFloat(id(id_2_check).value);
+ if (!(!Number.isNaN(value) && value >= 0.00001 && value <= 9999)) {
+ error_message = translate_text_item("Value of probe feedrate must be between 0.00001 mm/min and 9999 mm/min !");
status = false;
}
break;
case "preferences_probemaxtravel":
- value = Number.parseInt(id(id_2_check).value);
- if (!(!Number.isNaN(value) && value >= 1 && value <= 9999)) {
- error_message = translate_text_item("Value of maximum probe travel must be between 1 mm and 9999 mm !");
+ value = Number.parseFloat(id(id_2_check).value);
+ if (!(!Number.isNaN(value) && value >= 0.00001 && value <= 9999)) {
+ error_message = translate_text_item("Value of maximum probe travel must be between 0.00001 mm and 9999 mm !");
status = false;
}
break;
case "preferences_proberetract":
- value = Number.parseInt(id(id_2_check).value);
+ value = Number.parseFloat(id(id_2_check).value);
if (!(!Number.isNaN(value) && value >= 0 && value <= 9999)) {
error_message = translate_text_item("Value of probe retract must be between 0 mm and 9999 mm !");
status = false;
}
break;
case "preferences_probetouchplatethickness":
- value = Number.parseInt(id(id_2_check).value);
+ value = Number.parseFloat(id(id_2_check).value);
if (!(!Number.isNaN(value) && value >= 0 && value <= 9999)) {
error_message = translate_text_item("Value of probe touch plate thickness must be between 0 mm and 9999 mm !");
status = false;
diff --git a/www/js/scanwifidlg.js b/www/js/scanwifidlg.js
index aacdd869..3e832717 100644
--- a/www/js/scanwifidlg.js
+++ b/www/js/scanwifidlg.js
@@ -83,9 +83,9 @@ function process_scanWifi_answer(response_text) {
}
setHTML("AP_scan_data", content);
- for(const action in actions) {
+ actions.forEach((action) => {
id(action.id).addEventListener(action.type, (event) => action.method);
- };
+ });
return result;
}
diff --git a/www/js/utilValidation.js b/www/js/utilValidation.js
new file mode 100644
index 00000000..95123a4e
--- /dev/null
+++ b/www/js/utilValidation.js
@@ -0,0 +1,110 @@
+// For all of the following `valueDef` is the following structure
+/*
+{
+ "defValue" - (optional) the default value
+ "valueType" - (required) the value type, one of "int", "float", "bool", "text", "enctext", "select", "panel"
+ "units" - (optinal) a very short name/description of the relevant units for the value
+ "label" - (required) The correct name/title/label of the value
+ "inpClass" - (optional) A boostrap class for the values presentation
+ "min" - (optional) A minimum (inclusive) for the value
+ "max" - (optional) A maximum (inclusive) for the value
+},
+*/
+
+/** Test the supplied numeric value against any defined `min` test (inclusive),
+ * success is an empty string,
+ * failure is an error message */
+const valueMinTest = (value, valueDef) => {
+ return "min" in valueDef && value < valueDef.min
+ ? `'${valueDef.label}' ${translate_text_item("must be greater than or equal to")} ${valueDef.min}`
+ : "";
+};
+
+/** Test the supplied numeric value against any defined `max` test (inclusive),
+ * success is an empty string,
+ * failure is an error message */
+const valueMaxTest = (value, valueDef) => {
+ return "max" in valueDef && value > valueDef.max
+ ? `'${valueDef.label}' ${translate_text_item("must be less than or equal to")} ${valueDef.max}`
+ : "";
+};
+
+/** Test whether a value is an integer, and optionally within a certain range,
+ * success is an empty array,
+ * failure is an array of one or more error messages */
+const valueIsInt = (value, valueDef) => {
+ const errorList = [];
+ const vInt = Number.parseInt(value);
+ if (Number.isNaN(vInt)) {
+ errorList.push(`'${valueDef.label}' ${translate_text_item("must be an integer")}`);
+ } else {
+ errorList.push(valueMinTest(vInt, valueDef));
+ errorList.push(valueMaxTest(vInt, valueDef));
+ }
+ return errorList.filter((err) => err);
+}
+
+/** Test whether a value is an float, and optionally within a certain range,
+ * success is an empty array,
+ * failure is an array of one or more error messages */
+const valueIsFloat = (value, valueDef) => {
+ const errorList = [];
+ const vFloat = Number.parseFloat(value);
+ if (Number.isNaN(vFloat)) {
+ errorList.push(`'${valueDef.label}' ${translate_text_item("must be a float")}`);
+ } else {
+ errorList.push(valueMinTest(vFloat, valueDef));
+ errorList.push(valueMaxTest(vFloat, valueDef));
+ }
+ return errorList.filter((err) => err);
+}
+
+/** Test whether a value is a boolean, or text that says 'true' or 'false',
+ * NOTE: This does NOT specifically test if a value is truthy or falsey
+ * success is an empty array,
+ * failure is an array of one error messages */
+const valueIsBool = (value, valueDef) => {
+ return (typeof value === "boolean" || (typeof value === "string" && ["true", "false"].includes(value.toLocaleLowerCase())))
+ ? []
+ : `'${valueDef.label}' ${translate_text_item("must be a boolean, or 'true' or 'false'")}`;
+}
+
+/** Test whether a value is text,
+ * success is an empty array,
+ * failure is an array of one error messages */
+const valueIsText = (value, valueDef) => {
+ return (typeof value === "string")
+ ? []
+ : `'${valueDef.label}' ${translate_text_item("must be a string")}`;
+}
+
+/** Checks a supplied value against the supplied valueDef,
+ * success is an empty array,
+ * failure is an array of one or more error messages */
+const checkValue = (value, valueDef, errorList = []) => {
+ switch (valueDef.valueType) {
+ case "int": errorList.push(valueIsInt(value, valueDef)); break;
+ case "float": errorList.push(valueIsFloat(value, valueDef)); break;
+ case "panel":
+ case "bool":
+ // These are both boolean values
+ errorList.push(valueIsBool(value, valueDef));
+ break;
+ case "enctext":
+ case "text":
+ // These are both text string
+ errorList.push(valueIsText(value, valueDef));
+ break;
+ case "select":
+ // This is effectively an enum - no specific test for this yet
+ break;
+ default:
+ const valueDefError = `'${valueDef.label}' ${translate_text_item("is an unknown value type")} '${valueDef.valueType}'`;
+ console.error(`${valueDefError}: ${JSON.stringify(value)}`);
+ errorList.push(valueDefError);
+ break;
+ }
+ return errorList.filter((err) => err);
+}
+
+// export { checkValue, valueIsFloat };
diff --git a/www/sub/controlspanel.html b/www/sub/controlspanel.html
index 528bee5f..643176af 100644
--- a/www/sub/controlspanel.html
+++ b/www/sub/controlspanel.html
@@ -12,8 +12,7 @@