Barcode scanner auto-return feature - javascript

I'm attempting to build a very simple app that displays a webview to a site which contains a field to input product upc information. Only reason for the app is to provide our warehouse employees with a built in barcode scanner feature. All works well so far, up to inserting the scanned barcode information into the textfield with the following code:
webView.evaluateJavaScript("document.activeElement.value='\(text)'")
The problem I've run into is I am trying to code a way for the form to submit/search immediately following scan. As of now, the Search button does not even appear as using the value property does not seem to register as text input.
I have searched (perhaps incorrectly) for hours online for a similar issue and the only resolve I can think of is simulating keypresses with the textfield focused. At best, a simple keypress for the Enter key. However, with the search button not appearing until text is actually typed on the onscreen keyboard, I'm wondering if a combination of Space/Delete keys are needed, followed by the Enter key. So far, nothing has worked and I'd love some suggestions on what approach should be used here.

If submit is not visible it's probably due to a change event not firing, simulate the change event after filling a text value.
webView.evaluateJavaScript("document.activeElement.dispatchEvent(new Event('change', { 'bubbles': true }))")
after the change event we can target the button and fire the click event.
webView.evaluateJavaScript("var btn = document.querySelector('button')if(btn.textContent.includes('Search')){btn.click()}")

Add an event listener to the input and submit a form accordingly
const input = document.querySelector('input');
const log = document.getElementById('values');
input.addEventListener('input', updateValue);
function updateValue(e) {
log.textContent = e.target.value;
// code to search barcode
}
<input placeholder="Enter some text" name="name"/>
<p id="values"></p>

Related

How to restrict from entering a decimal value in input type number?

So I want to have an input of type number <input type="number"> and I want to RESTRICT users from ENTERING DECIMAL VALUE
Note: I'm hiding the spin buttons of the input type text. Know more here
EDIT: ANYTHING WILL WORK! EVEN JAVASCRIPT!
I searched a lot but found nothing.
I did find this answer but it basically blocks the use of any other key on the keypad except the number keys, so the basic problems occur such as the user cannot use backspace and cut the number entered, another problem is the user cannot use tab to change focus onto the next input.
Thank You!
Preventing user input can be done with JavaScript. I'd use the input event for catching values, as it's a unified interface, encompassing any input method you can think of keyup, paste, pointer events, touch events, etc...
document.querySelector('input').addEventListener('input', e => {
e.target.value = Math.round(e.target.value.replace(/\D/g,''))
});
<input>
But you really should not do it! For at least the following reasons:
Forbidding user input is, by and large, perceived as disrespectful and drives users away. In short, it reduces any user engagement metric you can think of (funneling, sales, visits, sharing, etc...). Don't take my word for it. Do some A/B testing: present the same form with and without blocking user input and look at the results.
Form elements are just tools to help users give you data. But they are completely by-pass-able. If you give me a form I can send whatever I want using it, by simply opening the browser console. The validation must be done on server side. If you're using the value to do something on client side, sanitize the input value in the method, without changing user input.
A respectful way to inform users decimal values are not valid is by making the input :invalid, using the pattern attribute ( e.g: pattern="[0-9]"), styling accordingly (e.g: :invalid { border-color: red }), and displaying an appropriate message.
Don't delete or block user input. They'll do it themselves if you tell them why the value is invalid.
When following web standards, your solution lasts. When you come up with hacks, there will always be the odd device in which your hack doesn't work. You don't know where things will be in 1-2 years from now, nevermind 5 or 10.
Last, but not least, have a closer look at Constraint Validation. You'll need to know and use it when creating quality UX and accessible forms.
This is one option for creating an input element using javascript to limit the values that can be entered. I create an array of allowed keys, including all the digits, backspace, and tab as you specified. I added an event listener for the keydown event, and if the key pressed is not in the allowed group, I prevent the default action, or prevent the value from being entered.
I also added an event listener to the paste event, as you could right click paste and enter information that does not meet the criteria. Instead of trying to validate pasted values I disable pasting all together.
If you have any questions, please ask.
const allowedKeys = [..."0123456789", "Backspace", "Tab"];
const myInput = document.querySelector("input");
myInput.addEventListener("keydown", e => {
const key = e.key;
const allowed = allowedKeys.includes(key);
if (!allowed) e.preventDefault();
});
myInput.addEventListener("paste", e => e.preventDefault());
<input type="number">

Simulate sending data to the text input field with JS

I have a task where I need to automate Sign in form authentication. For this example, I'll show you Tiktok authentication form (Mobile interface, not desktop. E-mail and password option)
If I enter text values into the fields programmatically, the Login button won't become active, and if I manually focus on the fields with a mouse click, the value disappears. These are two lines of code I run to put the value in:
let email_input = document.getElementsByName("email")[0];
email_input.value = 'sample#email.com';
I understand it needs to trigger a certain event to assign a value into it's JS model, but I can't figure out how to do it. I have tried sending change or input events onto this text field with no luck using this code:
let email_input = document.getElementsByName("email");
email_input[0].value = 'sample#email.com';
custom_event = new Event('input');
email_input[0].dispatchEvent(custom_event);
// tried also change, textInput like so:
custom_event = new Event('change');
email_input[0].dispatchEvent(custom_event);
But this does not seem to help.
So my goal is to put values into both fields Email and Password in the way it will be detected and Log in button would become active.
Any suggestion would be much appreciated
You should first focus needed input element and then execute document.execCommand with insertText command:
let email_input = document.getElementsByName("email");
email_input[0].focus();
document.execCommand('insertText', false, 'sample#email.com');
With this method input\textarea value modification should be captured by all major frameworks including Angular and Vuejs. This modification will be processed by frameworks the same way as if user pressed "Paste" option in browser main menu.
It all depends...
Who/what are you? A normal browser user? A bot? The browser author?
Because code like this is useless...
let email_input = document.getElementsByName("email")[0];
What document are you referring to? Who's document? Did you inject this instruction into the page and executed it?
You're not telling us where you're coming from, but anyway...
If you are the browser author, or you can run JavaScript macros from your browser (ie: the Classic browser) then you can do something like this...
var Z=W.contentWindow.document.querySelectorAll('input[type="password"]');
if(Z.length>0){
Z[0].value='password123';
Z=W.contentWindow.document.querySelectorAll('input[type="email"]');
if(Z.length>0){Z[0].value='email#abc.com';}
}
To automatically populate such fields, and if you also want you can SubmitButtonID.click() the submit button for as long as the isTrusted property is not tested by the website.
Continued...
Test if normal (non-custom) submit button exists and click...
Z=W.contentWindow.document.querySelectorAll('input[type="submit"]');
if(Z.length>0){
if(Z[0].hasAttribute('disabled')){Z[0].removeAttribute('disabled');} <--- Enable it if disabled
Z[0].click(); <--- automate click
}

How can I get around a keypress requirement on a javascript textbox?

Hello and thanks for reading.
So I am trying to automatically log into this form using Chrome.
https://app.patientaccess.com/login
I use my own Chrome extension to do this. It's basically just a javascript file that fills in the fields automatically. I use it for a range of websites.
For example, this is my function for filling in a textbox:
function fld(param, val){try{document.querySelectorAll(param)[0].value = val} catch(e){}}
And I call it like this:
fld("input[id='loginForm-email']", "mail#myemail.com")
For most websites it works. But for the Patient Access website above, it doesn't and I think the reason is because the password textbox requires a physical keypress (or listening for a change event or something).
When I run my script, it fills in the textboxes just fine but it doesn't let me click next because, even though the textboxes appear to be filled in, the webpage knows that I haven't actually pressed any keys.
To get around it, I have to have my script fill in the form, then click in the password box, press space, delete the space I just entered and then it lets me sign in because it knows I have physically pressed a key in the password box.
So my question is how can I make my automatic sign in javascript work on this website?
I don't think a script can use keypress events to type into a textbox but that's ok because I can fill in the textbox programmatically (using the fld function above). But how can I convince the page that I have typed into the password textbox so it lets me submit the form?
I am using JavaScript as I said and I can include jQuery if needed.
Thanks.
After much trial and error, I was able to solve it with JavaScript using this:
var fireOnThis = document.querySelectorAll("[type='text']")[0]
const changeEvent = new Event('input', { bubbles: true, cancelable: true });
fireOnThis.dispatchEvent(changeEvent);
It works absolutely beautifully. I turned this into a function and all I do is run this function after automatically filling in the text field (it doesn't work before filling in the field, has to be after).
I tried many other solutions on other websites and none worked but this one does. Whee!
I got the concept from a Chrome Extension called Form Filler. I tried the extension on the form I was trying to automate and to my surprise, it filled in the form without issue. So I looked at the source code to find out how it did it and I found this:
['input', 'click', 'change', 'blur'].forEach(event => {
const changeEvent = new Event(event, { bubbles: true, cancelable: true });
element.dispatchEvent(changeEvent);
});
So I just converted that into the code in my answer and it worked a treat. So credit should really go to Hussein Shabbir, the developer of Form Filler.

WebApp doesn't recognize that an input field was changed when set with jQuery in PhantomJS

I open telegram with PhantomJS and try to fill phone number input with evaluate page like below:
page.evaluate(function(){
$("input[name='phone_number']").val("123456789");
});
When PhantomJS clicks on next button with jQuery the alert massage says:
"tel input is empty"
but when the page is rendered we can see numbers in the input field. How can I fill this input?
The problem is probably that the web app has some event listeners on that field, but they are not called when you change the value directly. You can try to trigger some of those events with jQuery.
For example:
$("input[name='phone_number']").blur();
or
$("input[name='phone_number']").change();
I found that this doesn't necessarily work. You can try to use the native keypress events in PhantomJS like this:
page.evaluate(function() {
document.querySelector("input[name='phone_number']").focus();
});
page.sendEvent("keypress", "123456789");
page.sendEvent() sends the given keys to the focussed input field. That's why you need to focus to the intended field beforehand.

jQuery onClick once with on/off switch

I am trying to figure out how to do something but can not figure out the correct terminology to do so.
What I am trying to do is have a textbox (#price) that when clicked once it will open up a pdf calculator that will then either prefill the textbox when completed or will then allow the user to enter the amount in. But I also want this to work if the textbox is "tabbed" over to also instead of the onClick. (Maybe onBlur) Basically anytime that textbox is used I need it to work like that. But how do I make the onClick know when the amount is ok to be entered or if the calculator needs to open?
What also makes this tricky is I need to have an On/Off switch basically a checkbox that when checked it allows that pop up pdf calculator and when its not checked it just ignores it and allows the price to be entered still.
Does anyone have any suggestions or pointers in how I can achieve this goal?
1. A textbox (#price) that when click once it will open up a pdf calculator
Use jQuery's click() handler or bind("click", ...)
var $price = $("#price");
$price.click(function() {
$("#pdf_calculator").fadeIn();
});
2. But I also want this to work if the textbox is "tabbed" over to also
Use the focus event to know when an input is active (i.e, has been "tabbed" to). Alternatively, the blur event can be used if you want to know when a user is "leaving" the input field. ('blur' is the opposite of 'focus')
$price.on("focus click", function() {
$("#pdf_calculator").fadeIn();
});
3. But how do I make the onClick know when the amount is ok to be entered or if the calculator needs to open?
Grab the amount typed in by the user, convert it to a numerical value, then perform your validation steps.
$price.on("focus click", function() {
// Do some validation checking on the amount entered.
var enteredValue = parseFloat($price.val());
if (!isNaN(enteredValue) && enteredValue > 0) {
$("#pdf_calculator").fadeIn();
}
});
4. What also makes this tricky is I need to have an On/Off switch basically a checkbox that when checked it allows that pop up pdf calculator and when its not checked it just ignores it and allows the price to be entered still.
Simply check that the checkbox is checked using jQuery's is(":checked") then combine the steps above, and your fully working code looks like this:
var $price = $("#price");
$price.on("focus click blur", function() {
// your checkbox element
var checkbox = $("#show_calculator");
// Check if the checkbox is checked
if (checkbox.is(":checked")) {
// convert the entered string to a number
// then validate it according to your needs
var enteredValue = parseFloat($price.val());
if (!isNaN(enteredValue) && enteredValue > 0) {
// if all conditions are met,
// show the pdf calculator
$("#pdf_calculator").fadeIn();
}
}
});
Click here to review a working jsfiddle of these ideas.
As for the pdf form (and getting values in and out again of a pdf form) there isn't a straight-forward method that doesn't involve a 'hack' (that may or may not work across different browsers). If the pdf only has ONE input, then you can capture the keyboard events on your form popup, and send them back to the HTML form (which is an ugly hack), but if this were my project, I would just convert the pdf functionality to javascript, and then you have all the freedom you need, and your calculator is 100% compatible with the rest of your application.
Hope this helps!
The event(s) you are looking for is onFocus and onBlur. I would bind a function to the onFocus event that first checks if the corresponding checkbox has a "true" (or "checked") value, then continue if it does and do nothin if it doesn't.
I'd create an example in jsfiddle for you if I wasn't answering this from my phone.
Bind event handler to focus event (blur is for when control looses focus).
$("#price").on({
"focus": eventHandler
})
Then in your eventHandler() check if calculator needs to be invoked, by checking if it's already opened: $("#calculatorDiv").is(":visible"), and checking if your checkbox is 'checked': $("#checkboxId").is(':checked'), and depending on that open it.

Categories