web-dev-qa-db-fra.com

Détecter quand la zone de saisie est remplie par le clavier et par le scanner de codes à barres.

Comment puis-je détecter par programme quand le texte saisi est rempli en tapant sur le clavier et quand il est automatiquement rempli par un scanner de code à barres? 

18
MyTitle

Eh bien, un code à barres ne déclenchera aucun événement clé, vous pouvez donc faire quelque chose comme:

$('#my_field').on({
    keypress: function() { typed_into = true; },
    change: function() {
        if (typed_into) {
            alert('type');
            typed_into = false; //reset type listener
        } else {
            alert('not type');
        }
    }
});

Selon le moment où vous souhaitez évaluer cela, vous souhaiterez peut-être effectuer cette vérification non pas sur le changement, mais sur la soumission, etc.

5
Utkanos

J'ai écrit cette réponse car mon scanneur de codes à barres Motorola LS1203 a généré un événement de frappe au clavier. Je ne peux donc pas utiliser la solution d'Utkanos.

Ma solution est:

var BarcodeScanerEvents = function() {
     this.initialize.apply(this, arguments);
};

BarcodeScanerEvents.prototype = {
    initialize: function() {
       $(document).on({
          keyup: $.proxy(this._keyup, this)
       });
    },
    _timeoutHandler: 0,
    _inputString: '',
    _keyup: function (e) {
        if (this._timeoutHandler) {
            clearTimeout(this._timeoutHandler);
            this._inputString += String.fromCharCode(e.which);
        } 

        this._timeoutHandler = setTimeout($.proxy(function () {
            if (this._inputString.length <= 3) {
                this._inputString = '';
                return;
            }

            $(document).trigger('onbarcodescaned', this._inputString);

            this._inputString = '';

        }, this), 20);
    }
};
24
Vitall

Adapté de la réponse super utile Vitall ci-dessus pour utiliser un IIFE au lieu du prototypage, au cas où quelqu'un se contenterait de voir ceci maintenant le serait. 

Ceci utilise également l'événement 'keypress' au lieu de keyup, ce qui m'a permis d'utiliser de manière fiable KeyboardEvent.key, puisque KeyboardEvent.which est déconseillé maintenant. J'ai trouvé que cela fonctionnait aussi bien pour le balayage de codes à barres que pour les cartes magnétiques. 

D'après mon expérience, le traitement des glissements de carte avec keyup m'a amené à effectuer un travail supplémentaire en manipulant des codes de touche "Shift", par exemple. un code Shift serait suivi du code représentant '/', le caractère voulu étant '?'. L'utilisation de 'Keypress' a également résolu ce problème. 

(function($) {
    var _timeoutHandler = 0,
        _inputString = '',
        _onKeypress = function(e) {
            if (_timeoutHandler) {
                clearTimeout(_timeoutHandler);
            }
            _inputString += e.key;

            _timeoutHandler = setTimeout(function () {
                if (_inputString.length <= 3) {
                    _inputString = '';
                    return;
                }
                $(e.target).trigger('altdeviceinput', _inputString);
                _inputString = '';

            }, 20);
        };
    $(document).on({
        keypress: _onKeypress
    });
})($);
4
Spence7

vous pouvez essayer l'exemple suivant, en utilisant le plugin jQuery https://plugins.jquery.com/scannerdetection/

Son détecteur de scanner basé sur le temps, hautement configurable. Il peut être utilisé comme solution pour les scanneurs de codes à barres basés sur le préfixe/postfix. 

Didacticiel sur l’utilisation et les meilleures pratiques, ainsi que sur divers modèles de scanner de codes à barres et leur traitement. http://a.kabachnik.info/jquery-scannerdetection-tutorial.html

$(window).ready(function(){

	//$("#bCode").scannerDetection();

	console.log('all is well');
	
	$(window).scannerDetection();
	$(window).bind('scannerDetectionComplete',function(e,data){
            console.log('complete '+data.string);
            $("#bCode").val(data.string);
        })
        .bind('scannerDetectionError',function(e,data){
            console.log('detection error '+data.string);
        })
        .bind('scannerDetectionReceive',function(e,data){
            console.log('Recieve');
            console.log(data.evt.which);
        })

        //$(window).scannerDetection('success');
<input id='bCode'type='text' value='barcode appears here'/>

4
dextermini

Si vous pouvez définir un préfixe pour votre lecteur de code à barres, voici ce que je suggère (j'ai un peu modifié le code Vitall):

var BarcodeScanner = function(options) {
     this.initialize.call(this, options);
};
BarcodeScanner.prototype = {
    initialize: function(options) {
       $.extend(this._options,options);
       if(this._options.debug) console.log("BarcodeScanner: Initializing");
       $(this._options.eventObj).on({
          keydown: $.proxy(this._keydown, this),
       });
    },
    destroy: function() {
        $(this._options.eventObj).off("keyup",null,this._keyup);
        $(this._options.eventObj).off("keydown",null,this._keydown);
    },
    fire: function(str){
        if(this._options.debug) console.log("BarcodeScanner: Firing barcode event with string: "+str);
        $(this._options.fireObj).trigger('barcode',[str]);
    },
    isReading: function(){
        return this._isReading;
    },
    checkEvent: function(e){
        return this._isReading || (this._options.isShiftPrefix?e.shiftKey:!e.shiftKey) && e.which==this._options.prefixCode;
    },
    _options: {timeout: 600, prefixCode: 36, suffixCode: 13, minCode: 32, maxCode: 126, isShiftPrefix: false, debug: false, eventObj: document, fireObj: document},
    _isReading: false,
    _timeoutHandler: false,
    _inputString: '',
    _keydown: function (e) {
        if(this._input.call(this,e))
            return false;
    },
    _input: function (e) {
        if(this._isReading){
            if(e.which==this._options.suffixCode){
                //read end
                if(this._options.debug) console.log("BarcodeScanner: Read END");
                if (this._timeoutHandler) 
                    clearTimeout(this._timeoutHandler);
                this._isReading=false;
                this.fire.call(this,this._inputString);
                this._inputString='';
            }else{
                //char reading
                if(this._options.debug) console.log("BarcodeScanner: Char reading "+(e.which));
                if(e.which>=this._options.minCode && e.which<=this._options.maxCode)
                    this._inputString += String.fromCharCode(e.which);
            }
            return true;
        }else{
            if((this._options.isShiftPrefix?e.shiftKey:!e.shiftKey) && e.which==this._options.prefixCode){
                //start reading
                if(this._options.debug) console.log("BarcodeScanner: Start reading");
                this._isReading=true;
                this._timeoutHandler = setTimeout($.proxy(function () {
                    //read timeout
                    if(this._options.debug) console.log("BarcodeScanner: Read timeout");
                    this._inputString='';
                    this._isReading=false;
                    this._timeoutHandler=false;
                }, this), this._options.timeout);
                return true;
            }
        }
        return false;
    }
};

Si vous avez besoin de personnaliser le délai, le suffixe, le préfixe, le code ascii min/max lu:

new BarcodeScanner({timeout: 600, prefixKeyCode: 36, suffixKeyCode: 13, minKeyCode: 32, maxKeyCode: 126});

J'ai également ajouté l'option isShiftPrefix pour utiliser, par exemple, le caractère $ avec les options suivantes: new BarcodeScanner({prefixKeyCode: 52, isShiftPrefix: true});

C'est un violon: https://jsfiddle.net/xmt76ca5/

2
Tobia

La solution de Vitall ne fonctionne bien que si vous avez déjà appuyé sur au moins une touche. Sinon, le premier caractère sera ignoré (si (this._timeoutHandler) renvoie false et que le caractère ne sera pas ajouté).

Si vous souhaitez commencer à numériser immédiatement, vous pouvez utiliser le code suivant:

var BarcodeScanerEvents = function() {
	this.initialize.apply(this, arguments);
};

BarcodeScanerEvents.prototype = {
	initialize : function() {
		$(document).on({
			keyup : $.proxy(this._keyup, this)
		});
	},
	_timeoutHandler : 0,
	_inputString : '',
	_keyup : function(e) {
		if (this._timeoutHandler) {
			clearTimeout(this._timeoutHandler);
		}
		this._inputString += String.fromCharCode(e.which);

		this._timeoutHandler = setTimeout($.proxy(function() {
			if (this._inputString.length <= 3) {
				this._inputString = '';
				return;
			}

			$(document).trigger('onbarcodescaned', this._inputString);

			this._inputString = '';

		}, this), 20);
	}
};

1
Mhastrich

Vous pouvez utiliser un événement "onkeyup" sur cette zone de saisie. Si l'événement s'est déclenché, vous pouvez l'appeler "Entrée à partir du clavier".

1
Sudip Pal

$(window).ready(function(){

	//$("#bCode").scannerDetection();

	console.log('all is well');
	
	$(window).scannerDetection();
	$(window).bind('scannerDetectionComplete',function(e,data){
            console.log('complete '+data.string);
            $("#bCode").val(data.string);
        })
        .bind('scannerDetectionError',function(e,data){
            console.log('detection error '+data.string);
        })
        .bind('scannerDetectionReceive',function(e,data){
            console.log('Recieve');
            console.log(data.evt.which);
        })

        //$(window).scannerDetection('success');
<input id='bCode'type='text' value='barcode appears here'/>

0
mallesh mk

Salut, j'ai une solution alternative pour évaluer un résultat du scanner de code à barres sans utiliser jQuery, vous devez d’abord et saisir du texte qui a un intérêt dès que le scanner de code à barres fonctionne

<input id="input_resultado" type="text" />

Le code en JavaScript est:

var elmInputScan = document.getElementById('input_resultado');           

elmInputScan.addEventListener('keypress', function (e){        
  clearInterval( timer_response );    
  timer_response = setTimeout( "onInputChange()", 10);
});    

Lorsque le lecteur de code à barres a entré le texte, l'appel a déjà été envoyé à l'événement de frappe, mais seul le résultat final m'intéresse. C'est pour cette raison que j'utilise le chronomètre. C'est tout, vous pouvez traiter la valeur dans la fonction onInputChange.

function onInputChange() {    
  console.log( document.getElementById('input_resultado').value );
}
0
Juan Carlos