Using POST method to send information to a URL with refresh - html

I am trying to simply use the POST method without having the page refresh
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<P>Light Control:
<FORM METHOD="POST" ACTION="http://192.168.100.106:8080/api/device/Light2"; enctype="application/json">
<P>Light On: <input type=hidden name=command value="on">
<UL></UL>
<P><INPUT TYPE=SUBMIT> </FORM>

Got it work just the way I needed... The AJAX JS is below the HTML (Thanks Simone)
HTML Code:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<head>
<script src="js/ajaxsbmt.js" type="text/javascript"></script>
</head>
<title>HALnix</title>
<H1>HALnix - Test</H1>
<P>Light Control:
<table>
<tr>
<td>
<FORM name="Light14on" METHOD="POST" ACTION="http://192.168.100.106:8080/api/device/Light14"; enctype="application/json" onsubmit="xmlhttpPost('http://192.168.100.106:8080/api/device/Light14', '$
Master Bedroom Lamp<input type=hidden name=command value="on">
</td>
<td><INPUT TYPE=SUBMIT value="On"> </FORM>
</td>
<td>
<FORM name="Light14off" METHOD="POST" ACTION="http://192.168.100.106:8080/api/device/Light14"; enctype="application/json" onsubmit="xmlhttpPost('http://192.168.100.106:8080/api/device/Light14', $
<input type=hidden name=command value="off">
<INPUT TYPE=SUBMIT value="Off"> </FORM>
</td>
</tr>
</table>
AJAX JS Code (ajaxsbmt.js)
//##################################################################################
//## FORM SUBMIT WITH AJAX ##
//## #Author: Simone Rodriguez aka Pukos <http://www.SimoneRodriguez.com> ##
//## #Version: 1.2 ##
//## #Released: 28/08/2007 ##
//## #License: GNU/GPL v. 2 <http://www.gnu.org/copyleft/gpl.html> ##
//##################################################################################
function xmlhttpPost(strURL,formname,responsediv,responsemsg) {
var xmlHttpReq = false;
var self = this;
// Xhr per Mozilla/Safari/Ie7
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// per tutte le altre versioni di IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('POST', strURL, true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
// Quando pronta, visualizzo la risposta del form
updatepage(self.xmlHttpReq.responseText,responsediv);
}
else{
// In attesa della risposta del form visualizzo il msg di attesa
updatepage(responsemsg,responsediv);
}
}
self.xmlHttpReq.send(getquerystring(formname));
}
function getquerystring(formname) {
var form = document.forms[formname];
var qstr = "";
function GetElemValue(name, value) {
qstr += (qstr.length > 0 ? "&" : "")
+ escape(name).replace(/\+/g, "%2B") + "="
+ escape(value ? value : "").replace(/\+/g, "%2B");
//+ escape(value ? value : "").replace(/\n/g, "%0D");
}
var elemArray = form.elements;
for (var i = 0; i < elemArray.length; i++) {
var element = elemArray[i];
var elemType = element.type.toUpperCase();
var elemName = element.name;
if (elemName) {
if (elemType == "TEXT"
|| elemType == "TEXTAREA"
|| elemType == "PASSWORD"
|| elemType == "BUTTON"
|| elemType == "RESET"
|| elemType == "SUBMIT"
|| elemType == "FILE"
|| elemType == "IMAGE"
|| elemType == "HIDDEN")
GetElemValue(elemName, element.value);
else if (elemType == "CHECKBOX" && element.checked)
GetElemValue(elemName,
element.value ? element.value : "On");
else if (elemType == "RADIO" && element.checked)
GetElemValue(elemName, element.value);
else if (elemType.indexOf("SELECT") != -1)
for (var j = 0; j < element.options.length; j++) {
var option = element.options[j];
if (option.selected)
GetElemValue(elemName,
option.value ? option.value : option.text);
}
}
}
return qstr;
}
function updatepage(str,responsediv){
document.getElementById(responsediv).innerHTML = str;
}

Related

Django CreateView form can't submit

My views:
class AddSuiteView(CreateView):
model = TestSuite
form_class = TestSuiteForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
my_TestCase = TestCase.objects.all()
context['my_testcase'] = my_TestCase
return context
def get_success_url(self):
return reverse("integratedTest:testSuite")
My form.py:
class TestSuiteForm(forms.ModelForm):
class Meta:
model = TestSuite
fields = ( 'name', 'test_case_list', 'created_by' )
My model is:
class TestSuite(models.Model):
name = models.CharField(max_length=200)
test_case_list = models.CharField(max_length=200, validators=[validate_comma_separated_integer_list], default = "1")
created_by = models.CharField(max_length=200, default = "anyone")
create_datetime = models.DateTimeField("TestSuite created on", auto_now = True)
class TestCase(models.Model):
name = models.CharField(max_length=200)
.....
My html is a bit complex:
<form method="post">
{% csrf_token %}
<script src="https://code.jquery.com/jquery-3.5.0.min.js"></script>
<h1 class="addsuite">Create Test Suite:</h1>
<p>
<label for="id_name">Name:</label>
<input type="text" id="id_name" name="name" required><br><br>
</p>
<p>
<label for="id_test_case_list_select_l">test_case_list(double click to add):</label><br><br>
<select size=10 name="test_case_list_select_l" id="id_test_case_list_select_l" class="multiselect" multiple="multiple" >
{%for case in my_testcase %}
<option value="{{case.name}}" >{{case.name}}</option>
{%endfor %}
</select>
<br><br>
<label for="id_test_case_list_select_r" >test case selected(double click to remove):</label><br>
<select size=10 name="test_case_list_select_r" id="id_test_case_list_select_r" class="multiselect" multiple="multiple" >
</select>
<input type="hidden" id="id_test_case_list" name="test_case_list" value="">
</p>
<p>⇧
<input type="button" id="addTestcaseByOne" value="++" onclick="addTestcaseByOne">
</p>
<p>⇩
<input type="button" id="decreaseTestcaseByOne" value="--" onclick="decreaseTestcaseByOne">
</p>
<br><br>
<p>
<label for="id_created_by">created_by:</label>
<input type="text" id="id_created_by" name="created_by" "><br><br>
</p>
<input type="submit" value="Save">
</form>
<script>
$(document).ready(function() {
$("#id_test_case_list_select_l").dblclick(function() {
var selectedItem = $('#id_test_case_list_select_l').find(":selected").text()
$('#id_test_case_list_select_r').append
('<option value= ' + selectedItem + '"*1">'+selectedItem+'*1</option>')
var old_val = $('#id_test_case_list').val()
//alert("old_val" + old_val)
var new_val = ""
if (old_val.length == 0){
new_val = selectedItem + "*1"
}
else{
new_val = old_val + "," + selectedItem + "*1"
}
//alert("new_val:" + new_val)
$('#id_test_case_list').val(new_val)
});
});
$(document).ready(function() {
$("#id_test_case_list_select_r").dblclick(function() {
select_str = $('#id_test_case_list_select_r').find(":selected").text()
//alert("select_str:"+select_str)
var textArry = select_str.split("*")
if( textArry.length == 2 ){
var rep = parseInt(textArry[1])
//alert("rep:"+rep)
if( rep==1 ){
var old_val = $('#id_test_case_list').val()
//alert("old_val:" + old_val)
var indexSel = $("#id_test_case_list_select_r").prop('selectedIndex')
//alert("indexSel:"+indexSel)
var textArry_oldlist = old_val.split(",")
var new_val = ""
for( let i = 0; i < textArry_oldlist.length; i++ ){
if(i == indexSel){
continue
}
else{
if (new_val.length == 0){
new_val = textArry_oldlist[i]
}else{
new_val = new_val + "," + textArry_oldlist[i]
}
}
//alert("new_val:" + new_val)
}
//alert("new_val:" + new_val)
$('#id_test_case_list').val(new_val)
$('#id_test_case_list_select_r').find(":selected").remove()
}
}
});
});
$(document).ready(function() {
$("#addTestcaseByOne").click(function() {
var optionLength = $('#id_test_case_list_select_r').find('option').length
if(optionLength>=1){
select_str = $('#id_test_case_list_select_r').find(":selected").text()
var textArry = select_str.split("*")
if( textArry.length == 2 ){
var rep = parseInt(textArry[1]) + 1
var new_text = textArry[0] + "*" + rep
$('#id_test_case_list_select_r').find(":selected").text(new_text)
var new_val = textArry[0] + "*" + rep
$('#id_test_case_list_select_r').find(":selected").val(new_val)
var indexSel = $("#id_test_case_list_select_r").prop('selectedIndex')
//alert("indexSel:"+indexSel)
var old_val = $('#id_test_case_list').val()
//alert("old_val:" + old_val)
var textArry_oldlist = old_val.split(",")
var new_val_list = ""
for( let i = 0; i < textArry_oldlist.length; i++ ){
if(i == indexSel){
if (new_val_list.length == 0){
new_val_list = new_val
}else{
new_val_list = new_val_list + "," + new_val
}
}
else{
if (new_val_list.length == 0){
new_val_list = textArry_oldlist[i]
}else{
new_val_list = new_val_list + "," + textArry_oldlist[i]
}
}
}
//alert("new_val_list:" + new_val_list)
$('#id_test_case_list').val(new_val_list)
}
}
});
});
$(document).ready(function() {
$("#decreaseTestcaseByOne").click(function() {
var optionLength = $('#id_test_case_list_select_r').find('option').length
if(optionLength>=1){
select_str = $('#id_test_case_list_select_r').find(":selected").text()
var selectedTextSpls = select_str.split("*")
if( selectedTextSpls.length == 2 ){
var rep = parseInt(selectedTextSpls[1])
if( rep>1 ){
rep = rep - 1
var new_text = selectedTextSpls[0] + "*" + rep
$('#id_test_case_list_select_r').find(":selected").text(new_text)
var new_val = selectedTextSpls[0] + "*" + rep
$('#id_test_case_list_select_r').find(":selected").val(new_val)
var indexSel = $("#id_test_case_list_select_r").prop('selectedIndex')
//alert("indexSel:"+indexSel)
var old_hidden_val = $('#id_test_case_list').val()
//alert("old_hidden_val:" + old_hidden_val)
var textArry_oldlist = old_hidden_val.split(",")
var new_val_list = ""
for( let i = 0; i < textArry_oldlist.length; i++ ){
if(i == indexSel){
if (new_val_list.length == 0){
new_val_list = new_val
}else{
new_val_list = new_val_list + "," + new_val
}
}
else{
if (new_val_list.length == 0){
new_val_list = textArry_oldlist[i]
}else{
new_val_list = new_val_list + "," + textArry_oldlist[i]
}
}
}
//alert("new_val_list:" + new_val_list)
$('#id_test_case_list').val(new_val_list)
}else if( rep==1 ){
var indexSel = $("#id_test_case_list_select_r").prop('selectedIndex')
//alert("indexSel:"+indexSel)
var old_hidden_val = $('#id_test_case_list').val()
//alert("old_hidden_val:" + old_hidden_val)
var textArry_oldlist = old_hidden_val.split(",")
var new_val_list = ""
for( let i = 0; i < textArry_oldlist.length; i++ ){
if(i == indexSel){
continue
}
else{
if (new_val_list.length == 0){
new_val_list = textArry_oldlist[i]
}else{
new_val_list = new_val_list + "," + textArry_oldlist[i]
}
}
}
//alert("new_val_list:" + new_val_list)
$('#id_test_case_list').val(new_val_list)
$('#id_test_case_list_select_r').find(":selected").remove()
}
}
}
});
});
</script>
Details: Upper list selection(name="test_case_list_select_l") is a full list. Double clicking options in upper list can add a same named one to the lower list(name="test_case_list_select_r") and the hidden input(name="test_case_list") get a new value. Hopefully, the hidden input will update the field test_case_list
The code seems good to me, but unfortunately it can't save. After input everything and click save the button, the page never redirect and model TestSuite have no new record. The selected list becomes empty immediately instead.
P.S. My form.html is coming from the Django tutorial:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
I add an additional button to test the value to be submitted.
<input type="submit" value="test" onclick="testButton()">
script as:
function testButton(){
valu = $('#id_test_case_list').val()
alert("valu:" + valu)
}
After select some cases, the first click button shows valu is the correct strings as I expected. But the selected list is cleared immediately after the button click. The repeatedly clicking of testButton also displays valu as blank.
I resolved this issue after I modified the model from test_case_list = models.CharField(max_length=200, validators=[validate_comma_separated_integer_list], default = "1")
to
test_case_list = models.CharField(max_length=200, default = "1")
by which I deleted the validators=[validate_comma_separated_integer_list].
I forgot it's not comma_separated_integer_list but comma_separated_string_list, I didn't know if there's any comma_separated_string_list
action="/your-name/" is missing in your form tag.
<form action="/your-route" method="post">
.
.
.
<button type="submit">Submit</button>
</form>

set a timer between requests from html inputs by withSuccessHandler and onSuccess

I have the problem in html page.
User enters data in html inputs and clicks enter.
After this it must start checking by the function "keyPressFunction" throw withSuccessHandler(onSuccess) to the Google-apps script function "searchData" in 3 tables on spreadsheet and result must return to var "findData" with true/false. If it true, then focus goes to next input. After third input the data writes to table.
But answer from apps-script returns slowly, near 5 seconds, but the focus is already goes out, when the data is really uncorrect. Can you help me this timer between requests?
For understanding the test project is here https://docs.google.com/spreadsheets/d/1FqUmJcTipwKX9Q5m-4dlmXIChp5k1Z98xR2m42GpIT0/edit#gid=0
and last deployed link of web app is here https://script.google.com/a/fmlogistic.com/macros/s/AKfycbwAcfIVGrbcu24t_6OxtR2gvltG3ojbh1_pNxLed1O8/dev
<script>
const inputs = document.querySelector('.dws-input');
const formControl = document.querySelectorAll('.form-control');
let findData;
let curInpID;
let firstValid, secValid, thirdValid, allValid;
formControl[0].focus();
function keyPressFunction(ev) {
let userInfo = {};
userInfo.login = document.getElementById("tLogin").value;
userInfo.table = document.getElementById("tTable").value;
userInfo.order = document.getElementById("tOrder").value;
let inputData = ev.target.value
let btnReset = document.getElementById("del");
if (ev.code !== 'Enter') return;
if (ev.target.classList.contains("is-valid")) ev.target.classList.remove("is-valid");
if (ev.target.classList.contains("is-invalid")) ev.target.classList.remove("is-invalid");
curInpID = ev.target.id;
google.script.run.withSuccessHandler(onSuccess).searchData(inputData, curInpID);
//the true/false returns here in findData:
console.log(findData);
if (!findData) {
ev.target.classList.add("is-invalid");
ev.target.focus();
return;
} else {
ev.target.classList.add("is-valid");
};
btnReset.disabled = (!firstValid == true);
allValid = (firstValid == true && secValid == true && thirdValid == true) ? true : false;
for (const i of formControl) {
if (i.value === '') {
i.nextElementSibling.focus();
break;
}
}
if (allValid){
google.script.run.userClicked(userInfo);
document.getElementById("tTable").value = '';
document.getElementById("tOrder").value = '';
secValid = false;
thirdValid = false;
document.getElementById("tTable").focus();
}
}
function onSuccess(_findData) {
findData = _findData;
if (!firstValid) firstValid = (findData && curInpID == "tLogin") ? true : false;
if (!secValid) secValid = (findData && firstValid && curInpID == "tTable") ? true : false;
if (!thirdValid) thirdValid = (findData && firstValid && secValid && curInpID == "tOrder") ? true : false;
allValid = (firstValid && secValid && thirdValid) ? true : false;
}
inputs.addEventListener('keydown', keyPressFunction);
</script>
<!doctype html>
<html lang="en">
<head>
<title>CLR: PACKING</title>
<meta charset = "UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div class="conteiner">
<form novalidate>
<h6 class="title">PACKING</h6>
<div class="dws-input">
<div class="col-md-3"></div>
<div>
<div class="form-floating mb-3 mt-3">
<input type="text" class="form-control" novalidate id="tLogin" name= "username" placeholder= "Login:" autofocus >
<label for="tLogin">Login:</label>
</div>
<div class="form-floating mb-3 mt-3">
<input type="text" class="form-control" novalidate id="tTable" name= "text" placeholder= "Table:" >
<label for="tTable">Table:</label>
</div>
</div>
<div class="form-floating mb-3 mt-3">
<input type="text" novalidate class="form-control" id="tOrder" name= "text" placeholder= "Order:" >
<label for="tOrder">Order:</label>
</div>
</div>
</form>
</div>
<?!= include("index-js"); ?>
</body>
</html>
at Apps script I have next script:
const url = SpreadsheetApp.getActiveSpreadsheet().getUrl();
let ss = SpreadsheetApp.openByUrl(url);
let sheetTo = ss.getSheetByName("#sistem");
let sheetIn = ss.getSheetByName("#packing");
function doGet(e){
var htmlServ = HtmlService.createTemplateFromFile("index");
return htmlServ.evaluate();
}
function userClicked(userInfo){
sheetIn.appendRow([userInfo.login, userInfo.table, userInfo.order, new Date()]);
Logger.login(userInfo.name + "clicked the button");
}
function include(filename){
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function searchData(inputData, curInpID){
var result;
var lrLogins = sheetTo.getRange("A:A").getValues().filter(String).length;
var arrLogins = sheetTo.getRange(1, 1, lrLogins, 1).getValues().flat();
var lrTMPLORDS = sheetTo.getRange("K:K").getValues().filter(String).length;
var curTMPLORDS = sheetTo.getRange(1, 11, lrTMPLORDS, 1).getValues();
var lrTABLES = sheetTo.getRange("R:R").getValues().filter(String).length;
var curTABLES = sheetTo.getRange(1, 18, lrTABLES, 1).getValues().flat();
if (curInpID == "tLogin"){
result = (arrLogins.indexOf(inputData) !== -1) ? true : false;
}
else if (curInpID == "tTable"){
result = (curTABLES.indexOf(inputData) !== -1) ? true : false;
}
else if (curInpID == "tOrder"){
for (i = 0 ; i < curTMPLORDS.length; i ++){
var regexstring = curTMPLORDS[i];
var regexp = new RegExp(regexstring, "i");
var result = regexp.test(inputData);
if (result) break;
}
}
return result;
}
Issue:
If I understand you correctly, you want to avoid the keydown events to execute keyPressFunction while the server-side function searchData hasn't still returned the data.
Solution:
If that's the case, I'd suggest you to use removeEventListener at the start of the keyPressFunction (in order to avoid successive keydown event to trigger more executions of this function), and add it again via addEventListener when executing you success handler function (onSuccess).
It could be something along the following lines:
function keyPressFunction(ev) {
inputs.removeEventListener('keydown', keyPressFunction);
// ... REST OF YOUR FUNCTION
}
function onSuccess(_findData) {
// ... REST OF YOUR FUNCTION
inputs.addEventListener('keydown', keyPressFunction);
}
Update:
keyPressFunction finishes execution without calling the server-function searchData if the pressed key is not Enter. Since the event will only be reactivated after searchData returns and onSuccess runs, it will not be reactivated if the pressed key is not Enter. Because of this, keyPressFunction will only run once (if the pressed key is not Enter).
In order to avoid this, move the removeEventListener line to just before calling searchData:
function keyPressFunction(ev) {
// ... REST OF YOUR FUNCTION
inputs.removeEventListener('keydown', keyPressFunction);
google.script.run.withSuccessHandler(onSuccess).searchData(inputData, curInpID);
}
Sidenote: Please note that everything that is written in keyPressFunction after calling searchData will never be executed, since the execution will be moved to the failure or success handlers (onSuccess in your case). So move that on top of the mentioned line (starting with google.script.run) if you want it to run.
Reference:
removeEventListener

How to put "-" in an form html

I am working on a form to fill out my bank account number, so I want to put a tick. Automatically so that it can be viewed more easily
<input class="form-control" type="text" placeholder="" name="account_number">
Try this
$(document).ready(function () {
$("#txtPhoneNo").keyup(function (e) {
if($(this).val().length === 14) return;
if(e.keyCode === 8 || e.keyCode === 37 || e.keyCode === 39) return;
let newStr = '';
let groups = $(this).val().split('-');
for(let i in groups) {
if (groups[i].length % 4 === 0) {
newStr += groups[i] + "-"
} else {
newStr += groups[i];
}
}
$(this).val(newStr);
});
})
<input type='text' placeholder="please enter" id="txtPhoneNo" name='phone' maxlength='14'><BR>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Allow only numbers into a input text box

I have a number input text box and I want to allow the user to edit but do not want to allow the user to enter any other text except numbers. I want them only to be able to use the arrows on the number input box.
<input type = "number" min="0" max="10" step="0.5" input id="rating" name = "rating" class = "login-input" placeholder = "Rating 1-5:" value="0">
You can achieve this by pure JavaScript. Create this function that you can reuse in your script.
function allowNumbersOnly(e) {
var code = (e.which) ? e.which : e.keyCode;
if (code > 31 && (code < 48 || code > 57)) {
e.preventDefault();
}
}
You may preferably call this onkeypress event handler.
<input type="text" id="onlyNumbers" onkeypress="allowNumbersOnly(event)" />
function allowNumbersOnly(e) {
var code = (e.which) ? e.which : e.keyCode;
if (code > 31 && (code < 48 || code > 57)) {
e.preventDefault();
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
Try editing in me:
<input type="text" id="onlyNumbers" onkeypress="allowNumbersOnly(event)" />
</body>
</html>
However, I would recommend the unobtrusive style of writing JS using because it is good to keep the HTML semantic and away from pollution. You can execute the function on event handler that we would attach to this text box using vanilla JavaScript or jQuery.
function allowNumbersOnly(e) {
var code = (e.which) ? e.which : e.keyCode;
if (code > 31 && (code < 48 || code > 57)) {
e.preventDefault();
}
}
// using classic addEventListener method:
document.getElementById('onlyNumbers').addEventListener('keypress', function(e){ allowNumbersOnly(e);
}, false);
//using jQuery
$(function(){
$('#onlyNumbers2').keypress(function(e) {
allowNumbersOnly(e);
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
<div>
Using addEventListener: <input type="text" id="onlyNumbers" />
</div>
<div>
Using jQuery: <input type="text" id="onlyNumbers2" />
</div>
</body>
</html>
To restrict every character you can just simply use e.preventDefault().
Besides, you can also use return false instead but preventDefault() is better in this case and return false should be chosen wisely. It is good to know the difference between both of them.
document.getElementById('rating').onkeypress = function() { return false; }
This will prevent the default behavior of keypresses on that element i.e. text showing up.
HTML
<input type="text" class="IntOnly">
Javascript
let ele = document.getElementsByClassName('IntOnly');
for (const e of ele) {
//e.addEventListener('change', filterNonIntOut.bind(null, e));
//e.addEventListener('paste', filterNonIntOut.bind(null, e));
e.addEventListener('input', filterNonIntOut.bind(null, e));
}
function filterNonIntOut(theTextbox) {
//console.log(ele);
let startPos = theTextbox.selectionStart;
let endPos = theTextbox.selectionEnd;
let str = theTextbox.value;
str = str.trim();
if (str == '') {
theTextbox.value = '';
return;
}
let result = "";
for (var i = 0; i < str.length; i++) {
let ch = str.charAt(i);
//console.log(ch);
if (ch === '1'
|| ch === '2'
|| ch === '3'
|| ch === '4'
|| ch === '5'
|| ch === '6'
|| ch === '7'
|| ch === '8'
|| ch === '9'
|| ch === '0'
) {
result += ch;
}
else {
startPos -= 1;
endPos -= 1;
}
}
theTextbox.value = result;
theTextbox.focus();
theTextbox.setSelectionRange(startPos, endPos);
}

Codeception acceptance test error for save/reset

I am trying to perform acceptance tests for my website using Codeception, and I am experiencing a strange error due to a reset button on the form I am testing. Basically, my test for clicking on 'Save' works only if either the reset button on my form is AFTER the Save button, or if the reset button is left off the form altogether. If the reset button is inserted in the form before the save button, Codeception throws an Unreachable field "reset" error. Here is my Codeception code:
<?php
$I = new WebGuy($scenario);
$I->wantTo('find an employee in the database');
$I->amOnPage('/employees/find/');
$I->fillField('employeeLookup[first_name]', 'Sergi');
$I->click('Save', '#employeeLookup_save');
$I->see('Based on your search for Sergi, the following employees were found:');
$I->see('Remmele');
$I->see('Feb 28 1992');
And here is my HTML (much of it being generated from Symfony2):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Find existing employee</title>
</head>
<body>
<div id="content">
<p>Hello, enter either the first name, or the last name of the employee
you are searching for.</p>
<form name="employeeLookup" method="post" action="">
<div><label for="employeeLookup_first_name" class="required">Name: </label><input type="text" id="employeeLookup_first_name" name="employeeLookup[first_name]" required="required" /></div>
<div><button type="reset" id="employeeLookup_reset" name="employeeLookup[reset]">Reset</button></div>
<div><button type="submit" id="employeeLookup_save" name="employeeLookup[save]">Save</button></div>
<input type="hidden" id="employeeLookup__token" name="employeeLookup[_token]" value="RcpMVTGgB6WhKgDoXXRwmV_l4AFYKWTZko-dnBDhhvM" /></form>
</div>
<div id="sfwdte5d291" class="sf-toolbar" style="display: none"></div><script>/*<![CDATA[*/ Sfjs = (function() { "use strict"; var noop = function() {}, profilerStorageKey = 'sf2/profiler/', request = function(url, onSuccess, onError, payload, options) { var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); options = options || {}; xhr.open(options.method || 'GET', url, true); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.onreadystatechange = function(state) { if (4 === xhr.readyState && 200 === xhr.status) { (onSuccess || noop)(xhr); } else if (4 === xhr.readyState && xhr.status != 200) { (onError || noop)(xhr); } }; xhr.send(payload || ''); }, hasClass = function(el, klass) { return el.className.match(new RegExp('\\b' + klass + '\\b')); }, removeClass = function(el, klass) { el.className = el.className.replace(new RegExp('\\b' + klass + '\\b'), ' '); }, addClass = function(el, klass) { if (!hasClass(el, klass)) { el.className += " " + klass; } }, getPreference = function(name) { if (!window.localStorage) { return null; } return localStorage.getItem(profilerStorageKey + name); }, setPreference = function(name, value) { if (!window.localStorage) { return null; } localStorage.setItem(profilerStorageKey + name, value); }; return { hasClass: hasClass, removeClass: removeClass, addClass: addClass, getPreference: getPreference, setPreference: setPreference, request: request, load: function(selector, url, onSuccess, onError, options) { var el = document.getElementById(selector); if (el && el.getAttribute('data-sfurl') !== url) { request( url, function(xhr) { el.innerHTML = xhr.responseText; el.setAttribute('data-sfurl', url); removeClass(el, 'loading'); (onSuccess || noop)(xhr, el); }, function(xhr) { (onError || noop)(xhr, el); }, options ); } return this; }, toggle: function(selector, elOn, elOff) { var i, style, tmp = elOn.style.display, el = document.getElementById(selector); elOn.style.display = elOff.style.display; elOff.style.display = tmp; if (el) { el.style.display = 'none' === tmp ? 'none' : 'block'; } return this; } } })();/*]]>*/</script><script>/*<![CDATA[*/ (function () { Sfjs.load( 'sfwdte5d291', '/employees/app_dev.php/_wdt/e5d291', function(xhr, el) { el.style.display = -1 !== xhr.responseText.indexOf('sf-toolbarreset') ? 'block' : 'none'; if (el.style.display == 'none') { return; } if (Sfjs.getPreference('toolbar/displayState') == 'none') { document.getElementById('sfToolbarMainContent-e5d291').style.display = 'none'; document.getElementById('sfToolbarClearer-e5d291').style.display = 'none'; document.getElementById('sfMiniToolbar-e5d291').style.display = 'block'; } else { document.getElementById('sfToolbarMainContent-e5d291').style.display = 'block'; document.getElementById('sfToolbarClearer-e5d291').style.display = 'block'; document.getElementById('sfMiniToolbar-e5d291').style.display = 'none'; } }, function(xhr) { if (xhr.status !== 0) { confirm('An error occurred while loading the web debug toolbar (' + xhr.status + ': ' + xhr.statusText + ').\n\nDo you want to open the profiler?') && (window.location = '/employees/app_dev.php/_profiler/e5d291'); } } ); })();/*]]>*/</script>
</body>
</html>
Finally, here is the relevant output of the error message from Codeception:
1) Failed to find an employee in the database in FindEmployeeCept.php
Sorry, I couldn't click "Save","#employeeLookup_save":
Behat\Mink\Exception\ElementException: Exception thrown by ((//html/descendant-or-self::*[#id = 'employeeLookup_save'])[1]/.//input[./#type = 'submit' or ./#type = 'image' or ./#type = 'button'][(((./#id = 'Save' or ./#name = 'Save') or contains(./#value, 'Save')) or contains(./#title, 'Save'))] | .//input[./#type = 'image'][contains(./#alt, 'Save')] | .//button[((((./#id = 'Save' or ./#name = 'Save') or contains(./#value, 'Save')) or contains(normalize-space(string(.)), 'Save')) or contains(./#title, 'Save'))] | .//input[./#type = 'image'][contains(./#alt, 'Save')] | .//*[./#role = 'button'][(((./#id = 'Save' or ./#name = 'Save') or contains(./#value, 'Save')) or contains(./#title, 'Save') or contains(normalize-space(string(.)), 'Save'))])[1]
Unreachable field "reset"
Again, if the reset button is rendered after the save button in the HTML, the acceptance tests pass just fine. Also, if the reset button is left off of the form entirely, the acceptance test passes as well. Does anyone have any idea what is causing this?