Mottie / Keyboard

Virtual Keyboard using jQuery ~
http://mottie.github.io/Keyboard/
Other
1.78k stars 723 forks source link

Double input on form submission #500

Closed stav3ng3r closed 7 years ago

stav3ng3r commented 7 years ago

I'm trying to make a simple numeric keypad:

<label class="block clearfix">
    <div class="form-group has-error">
        <span class="block input-icon input-icon-right">
            <input type="text" class="form-control" name="password" id="keyboardInput"
                          required="required" placeholder="PIN"/>
            <i class="ace-icon fa fa-lock"></i>
        </span>

    </div>
</label>
<div class="clearfix">
    <div id="keyboard"></div>
</div>

Here is what I'm using:

var keyboardInput = $('#keyboardInput');

    var keyboard = keyboardInput.keyboard({
        language: 'es',
        restrictInput: true, // Prevent keys not in the displayed keyboard from being typed in
        preventPaste: true,  // prevent ctrl-v and right click
        autoAccept: true,
        lockInput: true, // prevent manual keyboard entry,
        // if true, the keyboard will always be visible
        alwaysOpen: true,
        stayOpen: true,
        maxLength: 6,
        usePreview: false,

        // add keyboard to desired div
        appendTo: '#keyboard',

        // disable position utility
        position: false,

        layout: 'custom',

        customLayout: {
            'normal': [
                '1 2 3',
                '4 5 6',
                '7 8 9',
                '0',
                '{clear}'
            ]
        },

        display: {
            'clear': 'Limpiar'
        }

    }).addScramble({
        targetKeys: /[\d]/i // keys to randomize
    });

It works fine, but when I hit submit on the form I got two input 'password' with one of them being one number less.

So if I hit 123456 on the keyborad, its displayed on the input. But on submit I receive 12345. When looking to the request raw I see two passwords inputs with one of them having 12345 and the other 123456.

The second input is created when I first hit a key on the keypad.

Mottie commented 7 years ago

Hi @stav3ng3r!

The problem is that there is a hidden copy of the input/textarea contained inside the keyboard to determine scroll position. It isn't disabled, yet... I'll make a patch for that. You can solve the issue with your current version by either moving the keyboard outside of the form (don't modify the appendTo option, or by adding the following code:

visible: function(e, keyboard) {
    keyboard.$previewCopy[0].disabled = true;
}
Mottie commented 7 years ago

Additionally, for other users that might encounter this problem, if the usePreview and alwaysOpen options were set as true... the preview would also need to be disabled before form submission; but you'll need to do that in the form submission code:

$('#submit-button').submit(function(e) {
  // prevent automatic form submission
  e.preventDefault();

  // disable alwaysOpen preview inputs
  $('.ui-keyboard-preview').prop('disabled', true);

  // re-enable the preview after submission 
  $('form').one('ajax:complete', function() {
    $('.ui-keyboard-preview').prop('disabled', false);
  });

  // now submit the form
  this.submit();
});
stav3ng3r commented 7 years ago

Thanks @Mottie

I am already testing a dirty

 $('#loginForm').submit(function (e) {
        $('.ui-keyboard-preview-clone').prop('disabled', true);
    });

And is working fine so far. Where would I put that piece of hack ? Tried like this, but got and TypeError: Cannot read property '0' of undefined

var keyboardInput = $('#keyboardInput');

    var keyboard = keyboardInput.keyboard({
        language: 'es',
        restrictInput: true, // Prevent keys not in the displayed keyboard from being typed in
        preventPaste: true,  // prevent ctrl-v and right click
        autoAccept: true,
        lockInput: true, // prevent manual keyboard entry,
        // if true, the keyboard will always be visible
        alwaysOpen: true,
        stayOpen: true,
        maxLength: 6,
        usePreview: false,

        // add keyboard to desired div
        appendTo: '#keyboard',

        // disable position utility
        position: false,

        layout: 'custom',

        customLayout: {
            'normal': [
                '1 2 3',
                '4 5 6',
                '7 8 9',
                '0',
                '{clear}'
            ]
        },

        display: {
            'clear': 'Limpiar'
        },

        visible: function(e, keyboard) {
            keyboard.$previewCopy[0].disabled = true;
        }

    }).addScramble({
        targetKeys: /[\d]/i // keys to randomize
    });
Mottie commented 7 years ago

Hmm, I see the $previewCopy doesn't exist until you start typing... better to just use the updated version that is now available.

stav3ng3r commented 7 years ago

Alright, that does it. Thanks again @Mottie