0

I have a passcode or OTP input modal to verify the user's email and phone number.

<form>
 <span id="ap-email-otp" class="actions-pack-otp">
   <input type="tel" class="ap-otp-input" data-channel="email" data-index="0" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="email" data-index="1" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="email" data-index="2" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="email" data-index="3" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="email" data-index="4" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="email" data-index="5" maxlength="1" required>
 </span>
 <span id="ap-phone-otp" class="actions-pack-otp">
   <input type="tel" class="ap-otp-input" data-channel="phone" data-index="0" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="phone" data-index="1" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="phone" data-index="2" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="phone" data-index="3" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="phone" data-index="4" maxlength="1" required>
   <input type="tel" class="ap-otp-input" data-channel="phone" data-index="5" maxlength="1" required>
 </span>
</form>

enter image description here I want to update an object otp on every keyup event.


otp = {};

$document.on('keyup', '.ap-otp-input', function (e){

    if( e.keyCode === 8 || e.keyCode === 37 ){
        $(this).prev(':input').focus();
    }
    else{
        $(this).next(':input').focus();
    }

    otp[$(this).attr('data-channel')] = Array(6).splice( $(this).attr('data-index'), 0, $(this).val());

});

Output Getting:

otp{
  email : [], // Empty array
  phone : [], // Empty array
}

Expected Output Value of input should be inserted at it's data index.

Note : The "channel" names i.e email, phone etc are not predictable. It is dynamically calculated from the input's data-channel attribute.

SkyRar
  • 1,107
  • 1
  • 20
  • 37
  • 2
    `Array(6)` creates an **empty** array of length 6; what is it that you expect the splice to do? – Pointy May 02 '20 at 12:41
  • I wanted to insert the value of an individual input at a specific index that is calculated from its data-index attribute. – SkyRar May 02 '20 at 12:44
  • But `Array(6)` creates a **new** array in that statement, and you overwrite the previous value. I don't think you need `.splice()` at all. – Pointy May 02 '20 at 12:45
  • [`splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) returns the deleted items from the array. Why are you using splice on empty array? – adiga May 02 '20 at 12:47
  • @Pointy Yes I wanted to create an array dynamically. Could you please tell me an alternative solution to update the value of each object? – SkyRar May 02 '20 at 12:47
  • @adiga right, and because 0 elements are removed, that always returns an empty array. – Pointy May 02 '20 at 12:48
  • @adiga first of all I don't think that is an empty array. It is an array of undefined like [undefined, undefined, undefined.....] I just want to update the value in a particular index. The index is calculated from this.att('data-index') – SkyRar May 02 '20 at 12:53
  • `Array(6)` creates an array with *holes* (`[empty × 6]`) and this is not the same as assigning undefined values to each index like `Array.from({ length: 6 })`. For example: [JavaScript “new Array(n)” and “Array.prototype.map” weirdness](https://stackoverflow.com/questions/5501581) – adiga May 02 '20 at 12:57

1 Answers1

1

Initialize otp with two empty arrays:

otp = { email: [], phone: [] };

Then you can update those arrays; no need to construct a new array on every key:

otp[$(this).data('channel')][$(this).data("index")] = $(this).val();

Note also that data- attributes can be accessed more easily via the jQuery .data() method.

If your "channel" names are not predictable, all you need to do is initialize the arrays when you see a new one:

if (!otp[$(this).data('channel')])
  otp[$(this).data('channel')] = [];
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • That could be done if you know the channel's name. E.g channels here are email, phone etc. But channels are variable and only be calculated from data-channel. So how can I define an object of dynamic objects of array? – SkyRar May 02 '20 at 12:51
  • @SkyRar your question did not mention that detail, but I'll extend the answer. – Pointy May 02 '20 at 12:56
  • `otp[$(this).data('channel')][$(this).data("index")] = $(this).val();` This helps only if you know the channels name e.g email, phone . But in my case I dont know the channel's name. – SkyRar May 02 '20 at 12:57