Skip to content

Commit

Permalink
Merge pull request #12 from HichemTab-tech/feature/11-enable-context-…
Browse files Browse the repository at this point in the history
…menu-in-fake-input

Enable context menu in fake inputs
  • Loading branch information
HichemTab-tech authored Jun 17, 2024
2 parents fa494b8 + 6bbd5f4 commit 6c8cfe7
Show file tree
Hide file tree
Showing 10 changed files with 1,326 additions and 25 deletions.
85 changes: 75 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ You can install OTP-designer-jquery via npm:
You can also include OTP-designer-jquery directly from a CDN by adding the following script tag to your HTML file:

```HTML
<script src="https://cdn.jsdelivr.net/gh/HichemTab-tech/OTP-designer-jquery@2.2.1/dist/otpdesigner.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/HichemTab-tech/OTP-designer-jquery@2.3.0/dist/otpdesigner.min.js"></script>
```

### Local Download
Expand Down Expand Up @@ -232,17 +232,82 @@ $('#otp_target').otpdesigner({
</html>
```
In these examples, the OTP designer is initialized inside the otp_target element with different configurations. The first example demonstrates the basic usage without custom options, while the second example shows a customized OTP input with larger input fields and a length of 8 digits. The third example demonstrates using options as an object to customize the OTP input.

### Example 4: Using Context Menu Options

```HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OTP Designer jQuery Plugin - Using Context Menu Options</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="card mt-5 p-3">
<h1 class="h1">OTP Designer jQuery Plugin - Using Context Menu Options</h1>
<div id="otp_target"></div>
<button class="btn btn-primary mt-3" id="ok">OK</button>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>
<script src="dist/otpdesigner.js"></script>
<script>
$(document).ready(function() {
$('#otp_target').otpdesigner({
typingDone: function (code) {
console.log('Entered OTP code: ' + code);
},
contextMenuElement: $('<div class="dropdown-menu" id="contextMenu" style="display: none; position: fixed;">\n' +
' <a class="dropdown-item paste-action">Paste</a>\n' +
'</div>'),
openContextMenuElement: function (e) {
let $contextMenu = $('#contextMenu');
$contextMenu.css({
display: 'block',
left: e.pageX,
top: e.pageY
});
$('body').append($contextMenu);
},
closeContextMenuElement: function () {
$('#contextMenu').hide();
}
});
$('#ok').on('click', function () {
let result = $('#otp_target').otpdesigner('code');
if (result.done) {
alert('Entered OTP code: ' + result.code);
} else {
alert('Typing incomplete!');
}
});
});
</script>
</body>
</html>
```
In this example, the context menu includes a "Paste" action,
and the element that triggers the paste action has the class `.paste-action`.
Functions to handle opening and closing the context menu are provided.

## Options

| **Option** | **Type** | **Default** | **Description** |
|---------------------------|----------|-------------|----------------------------------------------------------------------------------------|
| **`length`** | Integer | 6 | The number of OTP input fields. |
| **`onluNumbers`** | Boolean | false | Allow only numeric input. |
| **`inputsClasses`** | String | "" | Additional CSS classes to apply to the OTP input fields. |
| **`inputsParentClasses`** | String | "" | Additional CSS classes to apply to the parent container of the OTP input fields. |
| **`typingDone`** | Function | null | A callback function executed when the user completes typing the OTP. |
| **`enterClicked`** | Function | null | A callback function executed when the user click on Enter key when he's done typing. |
| **`onchange`** | Function | null | A callback function executed when the OTP code changed (by typing, clearing, setting). |
| **Option** | **Type** | **Default** | **Description** |
|-------------------------------|----------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`length`** | Integer | 6 | The number of OTP input fields. |
| **`onlyNumbers`** | Boolean | false | Allow only numeric input. |
| **`inputsClasses`** | String | "" | Additional CSS classes to apply to the OTP input fields. |
| **`inputsParentClasses`** | String | "" | Additional CSS classes to apply to the parent container of the OTP input fields. |
| **`typingDone`** | Function | null | A callback function executed when the user completes typing the OTP. |
| **`enterClicked`** | Function | null | A callback function executed when the user click on Enter key when he's done typing. |
| **`onchange`** | Function | null | A callback function executed when the OTP code changed (by typing, clearing, setting). |
| **`contextMenuElement`** | jQuery | null | A jQuery element used as the context menu for the OTP input fields. The element that triggers the paste action should have the class `paste-action`. |
| **`openContextMenuElement`** | Function | null | A function to handle opening the context menu. |
| **`closeContextMenuElement`** | Function | null | A function to handle closing the context menu. |


## Methods
The OTP Designer jQuery Plugin provides the following method:
Expand Down
59 changes: 57 additions & 2 deletions dist/otpdesigner.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* OTP-designer-jquery v2.2.1
* OTP-designer-jquery v2.3.0
* (c) HichemTech
* Released under the MIT License.
* Github: github.com/HichemTab-tech/OTP-designer-jquery
Expand Down Expand Up @@ -56,6 +56,16 @@ ___CSS_LOADER_EXPORT___.push([module.id, `.otp-fake-input {
.realInput{
position: absolute!important;
z-index: -2000!important;
}
.dropdown-item {
cursor: pointer;
transition: 0.1s;
}
.dropdown-item:hover {
background-color: #eeeeee;
transition: 0.1s;
}`, ""]);
// Exports
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
Expand Down Expand Up @@ -638,7 +648,25 @@ const otpdesigner = function (options = {}, ...args) {
inputsParentClasses: '',
enterClicked: null,
typingDone : null,
onchange: null
onchange: null,
contextMenuElement: $('<div class="dropdown-menu" id="contextMenu" style="display: none; position: fixed;">\n' +
' <a class="dropdown-item paste-action">Paste</a>\n' +
'</div>'),
openContextMenuElement: (e) => {
let $contextMenu = $(settings.contextMenuElement);
if (!$contextMenu) return;
$contextMenu.css({
display: 'block',
left: e.pageX,
top: e.pageY
});
$('body').append($contextMenu);
},
closeContextMenuElement: () => {
let $contextMenu = $(settings.contextMenuElement);
if (!$contextMenu) return;
$contextMenu.hide();
}
},
options
);
Expand Down Expand Up @@ -712,6 +740,29 @@ const otpdesigner = function (options = {}, ...args) {
}
$('[data-otpdesigner-id="' + data.idSuffix + '"]').otpdesigner('set', pastedText);
});
$(document).on('click', function() {
settings.closeContextMenuElement();
});
if (settings.contextMenuElement) {
$(settings.contextMenuElement).find('.paste-action').on('click', function (e) {
try {
navigator.clipboard.readText()
.then(text => {
$realInput.trigger('paste', [text]);
})
.catch(err => {
console.error('Failed to read clipboard contents: ', err);
});
} catch (e) {
if (!window.isSecureContext) {
console.error('navigator.clipboard is not supported in insecure contexts');
}
else {
console.error('navigator.clipboard is not supported', e);
}
}
});
}

for (let i = 0; i < settings.length; i++) {
let $fakeInput = $('<div class="m-2 text-center form-control rounded otp-fake-input"><span class="otp-content"></span></div>');
Expand Down Expand Up @@ -782,6 +833,10 @@ const otpdesigner = function (options = {}, ...args) {
}
});
});
$inputs.on('contextmenu', function (e) {
e.preventDefault();
settings.openContextMenuElement(e);
});
}
else{
if (typeof options === 'string' && typeof methods[options] !== 'undefined') {
Expand Down
Loading

0 comments on commit 6c8cfe7

Please sign in to comment.