Barcode Scanning AutoTrigger on LiveChange event - sapui5

I have a barcode scanning functionality for my SAPUI5 application. First the user will see a pop-up where he can do barcode scanning and if the scanned barcode is correct it will trigger the Next button and will in turn display another pop-up for the next barcode scanning. For the first barcode, the user must scan 6-7 digits while on the second barcode, it should be 5. My problem is with the autotrigger for the fist barcode. When user scans for 7 digits, it triggers the Next 2x. Is there a way to know the last length of the scanned barcode text?
Here is my liveChange event for TextInput
liveChange: function(oEvent) {
sText = oEvent.getParameter('value');
parent1 = oEvent.getSource().getParent();
if ((typeof sText != 'undefined') && (sText.length >= 6) )
{
sap.ui.getCore().byId(t.createId("costCenterInput")).setValue(sText);
setTimeout(function() {
console.log(parent1.getBeginButton());
if (parent1.getBeginButton() != null){
parent1.getBeginButton().firePress(oEvent);
}
}, 5000);
}
}
The problem with this code is that an external barcode scanner acts as a Bluetooth keyboard that inputs the data one at a time. So say we scan 1234567, upon entering 6 it will already trigger even with the timeout and will trigger again when entering 7.
new code
onScanAddressMobile: function(){
var t = this;
t.oBundle = this.oApplicationFacade.getResourceBundle();
var dialog = new sap.m.Dialog(t.createId("ccDialog"), {
title: t.oBundle.getText("COST_CENTER"),
type: 'Message',
content: [
new sap.m.Text({ text: t.oBundle.getText("SCAN_COST_CENTER")}),
new sap.m.Input(t.createId("costCenterInput"), {
type: "Number",
liveChange:
function(oEvent){
t.onLiveChange(oEvent);
}
}),
.....some more code here...
},
onLiveChange : function(event) {
//alert("onLiveChange");
var value = event.getParameter("value");
if (value && value.length === 6) {
alert("6 character");
this.timer = setTimeout(this.gotoNextPage(value), 4000);
} else if (value && value.length > 6) {
alert("6 or more");
if (this.timer) {
clearTimeout(this.timer);
}
this.gotoNextPage(value);
}
},

Usually, barcode-scanners can be configured to send a 'return' value at the end of the scanned characters (or any other character, but the Chr(13) is most common as it could instantly submit a form when schanned into an input field
See if you can configure yours, and simply check for the last character (return)

A barcode scanner that works as a bluetooth keyboard will "key" in its data quite rapidly. If you have received 6 digits and then didn't receive anything for perhaps 250ms, you can consider the barcode complete and skip to the next page.
If you have received 7 digits, you don't even need to wait anymore, but can immediately skip to the next page.
So I guess your code would have to look something like this:
onLiveChange : function(event) {
var value = event.getParameter("value");
if (value && value.length === 6) {
this.timer = setTimeout(this.gotoNextPage, 250)
} else if (value && value.length > 6) {
if (this.timer) {
clearTimeout(this.timer);
}
this.gotoNextPage();
}
}
Please find an example with slightly longer time-out in this jsbin: http://jsbin.com/kolacez/1/edit?html,output
This is what will happen:
Char 1: Nothing
Char 2: Nothing
Char 3: Nothing
Char 4: Nothing
Char 5: Nothing
Char 6: A timer is set, if character 7 isn't received within a certain timeframe, the barcode is assumed to be complete and it will launch gotoNextPage.
Char 7: The timer is cancelled and gotoNextPage is started directly.
So in case a 7 chars barcode is received, the logic for both char 6 and char 7 is executed, but because the timer-action of char 6 is cancelled, the gotoNextPage method is launched only once.

Related

How Do I stop VSCode from auto-filling unnecessary words on save?

I'm running this code and every time I save, it adds 3 other words that I didn't want to be added.
useEffect(() => {
const fuse = new Fuse(slideRows, { keys: ['data.description', 'data.title', 'data.genre'] });
const results = fuse.search(searchTerm).map(({ item }) => item);
if (slideRows.length > 0 && searchTerm.length > 3 && results.length > 0) {
setSlideRows(results);
} else {
setSlideRows(slides[category]);
}
}, [category, searchTerm, slideRows, slides])
The last line of code I only one one word searchTerm but vs code keeps auto filling the array with the other 3 words.
Is there a setting to prevent this or how do I solve this issue?
because of this it will create infinite loop.you can disable eslint plugging and try if you are using that.because this will do auto filling.

UI5: Validate Whole Form's Required and Visible Fields for Null/Blank Values

onPress of submit button, I want to validate all SimpleForms' fields (ComboBox, Input, DatePicker, etc.) that are
required &
visible
to see if they are null or blank (""). If a targeted (required & visible) field is null/blank, set that control's state to "Error" and display an error message. If no targeted field is null/blank, pop up a success dialog box.
This method is automated so in the future, any fields added later will automatically be checked without need of manual additions to controller code.
Controller code:
requiredAndVisible: function(oControl) {
if (typeof oControl.getRequired === "function") { //certain ctrls like toolbars dont have getRequired as a method, so we want to skim those out, else itll throw an error later in the next check
if (oControl.getRequired() === true && oControl.getVisible() === true) {
return oControl;
}
}
},
onSubmit: function() {
var valid = true,
oView = this.getView(),
aFormInitial = oView.byId("formInitial").getContent(), // get all the controls of SimpleForm1
aFormConfig = oView.byId("formConfiguration").getContent(), // get all controls of SimpleForm2
aControls = aFormInitial.concat(aFormConfig), // combine the 2arrays together into 1
aFilteredControls = aControls.filter(this.requiredAndVisible); // check each element if it required & visible using the 1st function. return only the controls that are both req'd & visible
aFilteredControls.forEach(function(oControl) { // in resultant array, check each element if...
if (!oControl.getValue() || oControl.getValue().length < 1) { // its value is null or blank
oControl.setValueState("Error");
valid = false; // set valid to false if it is
} else {
oControl.setValueState("None");
}
});
if (valid === false) {
// **replace this code with w/e error handling code u want**
oView.byId("errorMsgStrip").setVisible(true);
} else if (valid === true) {
// **replace this code with whatever success handling code u want**
var oDialogConfirm = new sap.ui.xmlfragment("dialogID", "dialog.address.here", this);
oDialogConfirm.open();
}
},

Pressing enter key creates a blank span in tinymce editor

I am using tinyMCE editor in one of my project. When I press enter key inside the equation box,I want to reload the contents of the editor.It works well now but the problem I am facing here is an empty span with class AM that is automatically created on pressing enter key.The tinymce function for reloading the contents is :
tinyMCE.execCommand("mceRepaint");
I have made a javascript functin for this which is given below :
function loadlistener() {
//console.log('load');
$("#elm1_ifr").contents().keydown(function (event) {
//console.log('key');
var code = (event.keyCode ? event.keyCode : event.which);
//console.log(code);
if (code == 13 && amedit) {
tinyMCE.execCommand("mceRepaint");
tinyMCE.activeEditor.focus();
}
});
var p_parent = $("#elm1_ifr").contents().find("p");
setInterval(function () {
if (p_parent.find('span').length && p_parent.find('span')) {
amedit = true;
} else {
amedit = false;
}
}, 200)
};
So my question is how to prevent the creation of this empty span when enter key is pressed.
You can check it live Here
Pleas inspect the html so you can understand my question more clearly.

GWT CellTable highlighted row

So I have a cell table with click event selection model working fine.
I later found out you can press UP and DOWN arrows to get the highlighted row to change, but the awful thing is you have to press Space for it to actually call the SelectionChangeEvent.
I am trying to cheat my way a little, by catching the UP and DOWN events and firing the SPACE event. Sadly it doesn't work :(
Here is my code any help would be appreciated!
table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
table.sinkEvents(Event.KEYUP);
table.sinkEvents(Event.KEYDOWN);
table.sinkEvents(32);
table.addHandler(new KeyUpHandler(){
#Override
public void onKeyUp(KeyUpEvent event)
{
System.out.println(event.getNativeKeyCode());
if(event.getNativeEvent().getKeyCode() == 40)
{
// down is pressed
int i = rows.getFilterList().indexOf(selectionModel.getLastSelectedObject())+1;
if(i >= 0 && i < rows.getFilterList().size())
{
// selectionModel.setSelected(selectionModel.getLastSelectedObject(), false);
// selectionModel.setSelected(rows.getFilterList().get(i), true);
// SelectionChangeEvent.fire(selectionModel);
System.out.println("firing native event space");
DomEvent.fireNativeEvent(Document.get().createKeyUpEvent(false, false, false, false, 32), table);
}
}
else if(event.getNativeEvent().getKeyCode() == 38)
{
// up is pressed
int i = rows.getFilterList().indexOf(selectionModel.getLastSelectedObject())-1;
if(i >= 0 && i < rows.getFilterList().size())
{
// selectionModel.setSelected(selectionModel.getLastSelectedObject(), false);
// selectionModel.setSelected(rows.getFilterList().get(i), true);
// SelectionChangeEvent.fire(selectionModel);
System.out.println("firing native event space");
DomEvent.fireNativeEvent(Document.get().createKeyUpEvent(false, false, false, false, 32), table);
}
}
}
}, KeyUpEvent.getType());
32 is assumingly the NativeEvent for space, my console prints something like:
40
firing native event space
32
so assumingly the event type 32 is being called for the object table.
I check if the object is selected, because on the right hand side of the screen I have additional information being pulled out from a list, since the cell table doesn't show all the information. I want it so when I press UP and DOWN the RHS information changes and I dont have to press SPACE to prompt the info change
Ideally you would poke into the selection internals. Specifically the DefaultKeyboardSelectionHandler is the default implementation of keyboard navigation and the DefaultSelectionEventManager is the default implementation of selection actions using spacebar/clicks (they are both CellPreviewEvent.Handlers).
Anyway, you can force the keyboard selection to be bound to the underlying SelectionModel by using setKeyboardSelectionPolicy(KeyboardSelectionPolicy.BOUND_TO_SELECTION). It should be fine for your use case. Much like what is done for the CellList showcase sample (the selection API is the same across cell widgets).

How to fire place_changed event for Google places auto-complete on Enter key

The click seems to fire the event and set the cookies but pressing enter to submit doesn't set the cookies and instead the page redirects without the cookies.
function locationAuto() {
$('.search-location').focus(function () {
autocomplete = new google.maps.places.Autocomplete(this);
searchbox = this;
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var thisplace = autocomplete.getPlace();
if (thisplace.geometry.location != null) {
$.cookie.raw = true;
$.cookie('location', searchbox.value, { expires: 1 });
$.cookie('geo', thisplace.geometry.location, { expires: 1 });
}
});
});
The .search-location is a class on multiple textboxes.
There is a submit button that takes the values from the cookies and redirects (server side)
Adapted from Jonathan Caulfield's answer:
$('.search-location').keypress(function(e) {
if (e.which == 13) {
google.maps.event.trigger(autocomplete, 'place_changed');
return false;
}
});
I've encountered this problem as well, and came up with a good solution. In my website I wanted to save the autocomplete.getPlace().formatted_address in a hidden input prior to submission. This worked as expected when clicking the form's submit button, but not when pressing the Enter key on the selection in the autocomplete's dropdown menu. My solution was as follows:
$(document).ready(function() {
// Empty the value on page load
$("#formattedAddress").val("");
// variable to indicate whether or not enter has been pressed on the input
var enterPressedInForm = false;
var input = document.getElementById("inputName");
var options = {
componentRestrictions: {country: 'uk'}
};
autocomplete = new google.maps.places.Autocomplete(input, options);
$("#formName").submit(function(e) {
// Only submit the form if information has been stored in our hidden input
return $("#formattedAddress").val().length > 0;
});
$("#inputName").bind("keypress", function(e) {
if(e.keyCode == 13) {
// Note that simply triggering the 'place_changed' event in here would not suffice, as this would just create an object with the name as typed in the input field, and no other information, as that has still not been retrieved at this point.
// We change this variable to indicate that enter has been pressed in our input field
enterPressedInForm = true;
}
});
// This event seems to fire twice when pressing enter on a search result. The first time getPlace() is undefined, and the next time it has the data. This is why the following logic has been added.
google.maps.event.addListener(autocomplete, 'place_changed', function () {
// If getPlace() is not undefined (so if it exists), store the formatted_address (or whatever data is relevant to you) in the hidden input.
if(autocomplete.getPlace() !== undefined) {
$("#formattedAddress").val(autocomplete.getPlace().formatted_address);
}
// If enter has been pressed, submit the form.
if(enterPressedInForm) {
$("#formName").submit();
}
});
});
This solution seems to work well.
Both of the above responses are good answers for the general question of firing a question when the user presses "enter." However - I ran into a more specific problem when using Google Places Autocomplete, which might have been part of the OP's problem. For the place_changed event to do anything useful, the user needs to have selected one of the autocomplete options. If you just trigger 'place_changed', the if () block is skipped and the cookie isn't set.
There's a very good answer to the second part of the question here:
https://stackoverflow.com/a/11703018/1314762
NOTE: amirnissim's answer, not the chosen answer, is the one to use for reasons you'll run into if you have more than one autocomplete input on the same page.
Maybe not the most user friendly solution but you could use JQuery to disable the enter key press.
Something like this...
$('.search-location').keypress(function(e) {
if (e.which == 13) {
return false;
}
});