mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-09 19:40:19 +00:00
Convert nfc input to a web component
This commit is contained in:
39
core/static/webpack/core/components/nfc-input-index.ts
Normal file
39
core/static/webpack/core/components/nfc-input-index.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { inheritHtmlElement, registerComponent } from "#core:utils/web-components";
|
||||
|
||||
@registerComponent("nfc-input")
|
||||
export class NfcInput extends inheritHtmlElement("input") {
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
/* Disable feature if browser is not supported or if not HTTPS */
|
||||
// biome-ignore lint/correctness/noUndeclaredVariables: browser API
|
||||
if (typeof NDEFReader === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = document.createElement("button");
|
||||
const logo = document.createElement("i");
|
||||
logo.classList.add("fa-brands", "fa-nfc-symbol");
|
||||
button.setAttribute("type", "button"); // Prevent form submission on click
|
||||
button.appendChild(logo);
|
||||
button.addEventListener("click", async () => {
|
||||
// biome-ignore lint/correctness/noUndeclaredVariables: browser API
|
||||
const ndef = new NDEFReader();
|
||||
await ndef.scan();
|
||||
ndef.addEventListener("readingerror", () => {
|
||||
window.alert(gettext("Unsupported NFC card"));
|
||||
});
|
||||
|
||||
// biome-ignore lint/correctness/noUndeclaredVariables: browser API
|
||||
ndef.addEventListener("reading", (event: NDEFReadingEvent) => {
|
||||
this.node.value = event.serialNumber.replace(/:/g, "").toUpperCase();
|
||||
/* Auto submit form, we need another button to not trigger our previously defined click event */
|
||||
const submit = document.createElement("button");
|
||||
this.node.appendChild(submit);
|
||||
submit.click();
|
||||
submit.remove();
|
||||
});
|
||||
});
|
||||
this.appendChild(button);
|
||||
}
|
||||
}
|
106
core/static/webpack/types/web-nfc.d.ts
vendored
Normal file
106
core/static/webpack/types/web-nfc.d.ts
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
// Type definitions for Web NFC
|
||||
// Project: https://github.com/w3c/web-nfc
|
||||
// Definitions by: Takefumi Yoshii <https://github.com/takefumi-yoshii>
|
||||
// TypeScript Version: 3.9
|
||||
|
||||
// This type definitions referenced to WebIDL.
|
||||
// https://w3c.github.io/web-nfc/#actual-idl-index
|
||||
|
||||
// This has been modified to not trigger biome linting
|
||||
|
||||
// biome-ignore lint/correctness/noUnusedVariables: this is the official definition
|
||||
interface Window {
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
NDEFMessage: NDEFMessage;
|
||||
}
|
||||
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
declare class NDEFMessage {
|
||||
constructor(messageInit: NDEFMessageInit);
|
||||
records: readonly NDEFRecord[];
|
||||
}
|
||||
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
declare interface NDEFMessageInit {
|
||||
records: NDEFRecordInit[];
|
||||
}
|
||||
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
declare type NDEFRecordDataSource = string | BufferSource | NDEFMessageInit;
|
||||
|
||||
// biome-ignore lint/correctness/noUnusedVariables: this is the official definition
|
||||
interface Window {
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
NDEFRecord: NDEFRecord;
|
||||
}
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
declare class NDEFRecord {
|
||||
constructor(recordInit: NDEFRecordInit);
|
||||
readonly recordType: string;
|
||||
readonly mediaType?: string;
|
||||
readonly id?: string;
|
||||
readonly data?: DataView;
|
||||
readonly encoding?: string;
|
||||
readonly lang?: string;
|
||||
toRecords?: () => NDEFRecord[];
|
||||
}
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
declare interface NDEFRecordInit {
|
||||
recordType: string;
|
||||
mediaType?: string;
|
||||
id?: string;
|
||||
encoding?: string;
|
||||
lang?: string;
|
||||
data?: NDEFRecordDataSource;
|
||||
}
|
||||
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
declare type NDEFMessageSource = string | BufferSource | NDEFMessageInit;
|
||||
|
||||
// biome-ignore lint/correctness/noUnusedVariables: this is the official definition
|
||||
interface Window {
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
NDEFReader: NDEFReader;
|
||||
}
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
declare class NDEFReader extends EventTarget {
|
||||
constructor();
|
||||
// biome-ignore lint/suspicious/noExplicitAny: who am I to doubt the w3c definitions ?
|
||||
onreading: (this: this, event: NDEFReadingEvent) => any;
|
||||
// biome-ignore lint/suspicious/noExplicitAny: who am I to doubt the w3c definitions ?
|
||||
onreadingerror: (this: this, error: Event) => any;
|
||||
scan: (options?: NDEFScanOptions) => Promise<void>;
|
||||
write: (message: NDEFMessageSource, options?: NDEFWriteOptions) => Promise<void>;
|
||||
makeReadOnly: (options?: NDEFMakeReadOnlyOptions) => Promise<void>;
|
||||
}
|
||||
|
||||
// biome-ignore lint/correctness/noUnusedVariables: this is the official definition
|
||||
interface Window {
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
NDEFReadingEvent: NDEFReadingEvent;
|
||||
}
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
declare class NDEFReadingEvent extends Event {
|
||||
constructor(type: string, readingEventInitDict: NDEFReadingEventInit);
|
||||
serialNumber: string;
|
||||
message: NDEFMessage;
|
||||
}
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
interface NDEFReadingEventInit extends EventInit {
|
||||
serialNumber?: string;
|
||||
message: NDEFMessageInit;
|
||||
}
|
||||
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
interface NDEFWriteOptions {
|
||||
overwrite?: boolean;
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
interface NDEFMakeReadOnlyOptions {
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
// biome-ignore lint/style/useNamingConvention: this is the official API name
|
||||
interface NDEFScanOptions {
|
||||
signal: AbortSignal;
|
||||
}
|
@ -1,33 +1,5 @@
|
||||
<script-once src="{{ statics.js }}" defer></script-once>
|
||||
|
||||
<span>
|
||||
<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>
|
||||
<!-- NFC icon not available in fontawesome 4.7 -->
|
||||
<button type="button" id="{{ widget.attrs.id }}_button"><i class="fa-brands fa-nfc-symbol"></i></button>
|
||||
<nfc-input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}></nfc-input>
|
||||
</span>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
let button = document.getElementById("{{ widget.attrs.id }}_button");
|
||||
button.addEventListener("click", async () => {
|
||||
let input = document.getElementById("{{ widget.attrs.id }}");
|
||||
const ndef = new NDEFReader();
|
||||
await ndef.scan();
|
||||
|
||||
ndef.addEventListener("readingerror", () => {
|
||||
alert("{{ translations.unsupported }}")
|
||||
});
|
||||
|
||||
ndef.addEventListener("reading", ({ message, serialNumber }) => {
|
||||
input.value = serialNumber.replaceAll(":", "").toUpperCase();
|
||||
/* Auto submit form */
|
||||
b = document.createElement("button");
|
||||
input.appendChild(b)
|
||||
b.click()
|
||||
b.remove()
|
||||
});
|
||||
|
||||
});
|
||||
/* Disable feature if browser is not supported or if not HTTPS */
|
||||
if (typeof NDEFReader === "undefined") {
|
||||
button.remove();
|
||||
}
|
||||
});
|
||||
</script>
|
@ -27,6 +27,9 @@ from captcha.fields import CaptchaField
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
|
||||
from django.contrib.staticfiles.management.commands.collectstatic import (
|
||||
staticfiles_storage,
|
||||
)
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import transaction
|
||||
from django.forms import (
|
||||
@ -72,7 +75,9 @@ class NFCTextInput(TextInput):
|
||||
|
||||
def get_context(self, name, value, attrs):
|
||||
context = super().get_context(name, value, attrs)
|
||||
context["translations"] = {"unsupported": _("Unsupported NFC card")}
|
||||
context["statics"] = {
|
||||
"js": staticfiles_storage.url("webpack/core/components/nfc-input-index.ts")
|
||||
}
|
||||
return context
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user