a
This commit is contained in:
parent
71b7c83738
commit
c7a72b5d4f
|
|
@ -3,307 +3,95 @@
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Champ NFC complètement caché et sécurisé */
|
/* Masquage du texte */
|
||||||
#donneesCarte {
|
#donneesCarte {
|
||||||
position: absolute !important;
|
color: transparent !important;
|
||||||
left: -9999px !important;
|
text-shadow: 0 0 8px rgba(0,0,0,0.5) !important;
|
||||||
top: -9999px !important;
|
user-select: none !important;
|
||||||
opacity: 0 !important;
|
}
|
||||||
pointer-events: none !important;
|
|
||||||
width: 1px !important;
|
|
||||||
height: 1px !important;
|
|
||||||
z-index: -1 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zone d'affichage visuel principale */
|
#donneesCarte::placeholder {
|
||||||
.nfc-status-display {
|
color: #6c757d !important;
|
||||||
font-size: 24pt;
|
text-shadow: none !important;
|
||||||
min-height: 200px;
|
}
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border: 3px dashed #ccc;
|
|
||||||
border-radius: 15px;
|
|
||||||
background: #f8f9fa;
|
|
||||||
margin: 30px auto;
|
|
||||||
max-width: 600px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
padding: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nfc-status-display.reading {
|
/* Animation lors de la saisie */
|
||||||
border-color: #4caf50;
|
#donneesCarte.reading {
|
||||||
background: #e8f5e9;
|
border-color: #4caf50 !important;
|
||||||
animation: glow 1.5s infinite;
|
box-shadow: 0 0 0 0.2rem rgba(76, 175, 80, 0.25) !important;
|
||||||
}
|
animation: pulse-border 1s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
.nfc-status-display.error {
|
@keyframes pulse-border {
|
||||||
border-color: #dc3545;
|
0%, 100% { border-color: #4caf50; }
|
||||||
background: #f8d7da;
|
50% { border-color: #66bb6a; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes glow {
|
/* Indicateur visuel simple */
|
||||||
0%, 100% { box-shadow: 0 0 10px rgba(76, 175, 80, 0.3); }
|
.reading-indicator {
|
||||||
50% { box-shadow: 0 0 25px rgba(76, 175, 80, 0.6); }
|
display: none;
|
||||||
}
|
text-align: center;
|
||||||
|
color: #4caf50;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Icône NFC animée */
|
.reading-indicator.active {
|
||||||
.nfc-icon {
|
display: block;
|
||||||
font-size: 100px;
|
}
|
||||||
margin-bottom: 20px;
|
</style>
|
||||||
animation: pulse 2s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
<form id="frmrechercheparcarte" name="frmrechercheparcarte" method="post" action="Rechercheparcarte/index/">
|
||||||
0%, 100% { transform: scale(1); opacity: 1; }
|
<INPUT style='font-size:40pt; height: 50px; text-align: center;'
|
||||||
50% { transform: scale(1.08); opacity: 0.85; }
|
class="form-control"
|
||||||
}
|
TYPE="text"
|
||||||
|
id="donneesCarte"
|
||||||
|
name="donneesCarte"
|
||||||
|
autofocus
|
||||||
|
AUTOCOMPLETE="OFF"
|
||||||
|
placeholder="<?= _("Veuillez scanner la carte NFC!")?>">
|
||||||
|
|
||||||
.nfc-status-display.reading .nfc-icon {
|
<div class="reading-indicator" id="reading-indicator">
|
||||||
animation: rotate-pulse 1.2s linear infinite;
|
<i class="fa fa-check-circle"></i> <?= _("Carte détectée") ?>
|
||||||
}
|
</div>
|
||||||
|
|
||||||
@keyframes rotate-pulse {
|
<input id="lancerrechercheparcarte" name="lancerrechercheparcarte" class="sr-only" type="submit" value="<?= _("Rechercher") ?>" >
|
||||||
0% { transform: rotate(0deg) scale(1); }
|
</form>
|
||||||
50% { transform: rotate(180deg) scale(1.1); }
|
|
||||||
100% { transform: rotate(360deg) scale(1); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Texte du statut */
|
<div id ="div_wait_nfc"> </div>
|
||||||
#nfc-placeholder {
|
|
||||||
font-size: 20px;
|
|
||||||
color: #666;
|
|
||||||
font-weight: 500;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Points de feedback visuel */
|
<?php if (isset($msgErreur) && $msgErreur>" "): ?>
|
||||||
#nfc-dots {
|
<div class="alert alert-danger" style="height:38px; padding:5px; text-align: center;">
|
||||||
letter-spacing: 15px;
|
<H4><?= $msgErreur ?></H4>
|
||||||
color: #4caf50;
|
</div>
|
||||||
font-size: 40px;
|
<?php endif; ?>
|
||||||
margin-top: 15px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Spinner de validation - utilise votre spinner existant */
|
|
||||||
#div_wait_nfc {
|
|
||||||
text-align: center;
|
|
||||||
min-height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adaptation de votre alerte existante */
|
|
||||||
.alert {
|
|
||||||
margin-top: 20px;
|
|
||||||
border-radius: 10px;
|
|
||||||
animation: slideIn 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-10px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Container responsive */
|
|
||||||
.nfc-container {
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Info section */
|
|
||||||
.info-helper {
|
|
||||||
background: #e9ecef;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 15px;
|
|
||||||
margin-top: 20px;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #495057;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-helper i {
|
|
||||||
color: #4caf50;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="nfc-container">
|
|
||||||
<form id="frmrechercheparcarte" name="frmrechercheparcarte" method="post" action="Rechercheparcarte/index/">
|
|
||||||
|
|
||||||
<!-- Champ invisible mais fonctionnel (conserve votre logique) -->
|
|
||||||
<input type="text"
|
|
||||||
id="donneesCarte_1"
|
|
||||||
name="donneesCarte_1"
|
|
||||||
autofocus
|
|
||||||
autocomplete="off"
|
|
||||||
tabindex="-1">
|
|
||||||
|
|
||||||
<!-- Bouton submit caché (conservé pour compatibilité) -->
|
|
||||||
<input id="lancerrechercheparcarte"
|
|
||||||
name="lancerrechercheparcarte"
|
|
||||||
class="sr-only"
|
|
||||||
type="submit"
|
|
||||||
value="<?= _("Rechercher") ?>">
|
|
||||||
|
|
||||||
<!-- Zone d'affichage visuel -->
|
|
||||||
<div id="nfc-display" class="nfc-status-display">
|
|
||||||
<div class="nfc-icon">📱</div>
|
|
||||||
<span id="nfc-placeholder"><?= _("Veuillez scanner la carte NFC!") ?></span>
|
|
||||||
<span id="nfc-dots" style="display:none;"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- Votre spinner existant -->
|
|
||||||
<div id="div_wait_nfc"></div>
|
|
||||||
|
|
||||||
<!-- Votre message d'erreur existant -->
|
|
||||||
<?php if (isset($msgErreur) && $msgErreur > " "): ?>
|
|
||||||
<div class="alert alert-danger" style="height:38px; padding:5px; text-align: center;">
|
|
||||||
<H4><?= $msgErreur ?></H4>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<!-- Section d'aide -->
|
|
||||||
<div class="info-helper">
|
|
||||||
<i class="fa fa-info-circle"></i>
|
|
||||||
<?= _("Positionnez la carte NFC sur le lecteur pour démarrer la recherche automatique") ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Configuration
|
const inputField = document.getElementById('donneesCarte');
|
||||||
const NFC_CONFIG = {
|
const indicator = document.getElementById('reading-indicator');
|
||||||
minLength: 3, // Longueur minimale (votre logique actuelle)
|
|
||||||
autoSubmitDelay: 200, // Délai avant soumission (ms)
|
|
||||||
refocusDelay: 10 // Délai avant re-focus (ms)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Éléments DOM
|
// Protection
|
||||||
const nfcElements = {
|
inputField.addEventListener('contextmenu', e => e.preventDefault());
|
||||||
input: document.getElementById('donneesCarte'),
|
inputField.addEventListener('copy', e => e.preventDefault());
|
||||||
display: document.getElementById('nfc-display'),
|
inputField.addEventListener('cut', e => e.preventDefault());
|
||||||
placeholder: document.getElementById('nfc-placeholder'),
|
|
||||||
dots: document.getElementById('nfc-dots'),
|
|
||||||
form: document.getElementById('frmrechercheparcarte'),
|
|
||||||
waitDiv: document.getElementById('div_wait_nfc')
|
|
||||||
};
|
|
||||||
|
|
||||||
// Réinitialiser l'affichage
|
// Feedback visuel pendant la saisie
|
||||||
function resetNFCDisplay() {
|
inputField.addEventListener('input', function() {
|
||||||
nfcElements.display.className = 'nfc-status-display';
|
if (this.value.length > 0) {
|
||||||
nfcElements.placeholder.style.display = 'block';
|
this.classList.add('reading');
|
||||||
nfcElements.placeholder.textContent = '<?= _("Veuillez scanner la carte NFC!") ?>';
|
indicator.classList.add('active');
|
||||||
nfcElements.placeholder.style.color = '';
|
|
||||||
nfcElements.dots.style.display = 'none';
|
|
||||||
nfcElements.waitDiv.innerHTML = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Afficher le spinner de chargement (votre logique existante)
|
|
||||||
function showLoadingSpinner() {
|
|
||||||
nfcElements.waitDiv.innerHTML = '<div style="padding-top:80px; text-align:center; font-size:14px; color: #4caf50;"><span><i class="fa fa-spinner fa-spin fa-5x"></i></span></div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gestion de la saisie avec événement 'change' (conserve votre logique)
|
|
||||||
nfcElements.input.addEventListener('change', function() {
|
|
||||||
if (this.value.length > NFC_CONFIG.minLength) {
|
|
||||||
showLoadingSpinner();
|
|
||||||
this.form.submit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Gestion de la saisie en temps réel pour le feedback visuel
|
|
||||||
nfcElements.input.addEventListener('input', function() {
|
|
||||||
const length = this.value.length;
|
|
||||||
|
|
||||||
if (length > 0) {
|
|
||||||
// Activer le mode "lecture"
|
|
||||||
nfcElements.display.classList.add('reading');
|
|
||||||
nfcElements.placeholder.style.display = 'none';
|
|
||||||
nfcElements.dots.style.display = 'block';
|
|
||||||
|
|
||||||
// Afficher des points (maximum 10 pour ne pas surcharger)
|
|
||||||
nfcElements.dots.textContent = '•'.repeat(Math.min(length, 10));
|
|
||||||
|
|
||||||
// Si longueur suffisante, préparer la soumission
|
|
||||||
if (length > NFC_CONFIG.minLength) {
|
|
||||||
nfcElements.placeholder.textContent = '<?= _("Validation en cours...") ?>';
|
|
||||||
nfcElements.placeholder.style.display = 'block';
|
|
||||||
nfcElements.placeholder.style.color = '#4caf50';
|
|
||||||
nfcElements.dots.style.display = 'none';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
resetNFCDisplay();
|
this.classList.remove('reading');
|
||||||
|
indicator.classList.remove('active');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Maintenir le focus sur le champ caché
|
// Votre logique existante
|
||||||
nfcElements.input.addEventListener('blur', function() {
|
inputField.addEventListener('change', function () {
|
||||||
setTimeout(() => {
|
if (this.value.length > 3) {
|
||||||
this.focus();
|
var div_wait_nfc = $('#div_wait_nfc');
|
||||||
}, NFC_CONFIG.refocusDelay);
|
div_wait_nfc.html('<div style="padding-top:80px; text-align:center; font-size:14px; color: #4caf50;"><span><i class="fa fa-spinner fa-spin fa-5x" >' + '</span></div>');
|
||||||
|
this.form.submit();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Empêcher les actions de copier/coller/menu contextuel
|
|
||||||
nfcElements.input.addEventListener('contextmenu', e => e.preventDefault());
|
|
||||||
nfcElements.input.addEventListener('copy', e => e.preventDefault());
|
|
||||||
nfcElements.input.addEventListener('cut', e => e.preventDefault());
|
|
||||||
nfcElements.input.addEventListener('paste', e => e.preventDefault());
|
|
||||||
|
|
||||||
// Gestion des touches clavier
|
|
||||||
nfcElements.input.addEventListener('keydown', function(e) {
|
|
||||||
// Échap pour réinitialiser
|
|
||||||
if (e.key === 'Escape') {
|
|
||||||
e.preventDefault();
|
|
||||||
this.value = '';
|
|
||||||
resetNFCDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empêcher Tab
|
|
||||||
if (e.key === 'Tab') {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enter force la soumission si assez de caractères
|
|
||||||
if (e.key === 'Enter' && this.value.length > NFC_CONFIG.minLength) {
|
|
||||||
e.preventDefault();
|
|
||||||
showLoadingSpinner();
|
|
||||||
this.form.submit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Focus initial
|
|
||||||
window.addEventListener('load', function() {
|
|
||||||
nfcElements.input.focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Re-focus au clic sur la page
|
|
||||||
document.addEventListener('click', function(e) {
|
|
||||||
// Ne pas refocus si on clique sur un élément interactif
|
|
||||||
if (e.target.tagName !== 'A' &&
|
|
||||||
e.target.tagName !== 'BUTTON' &&
|
|
||||||
e.target.tagName !== 'INPUT' &&
|
|
||||||
e.target.type !== 'submit') {
|
|
||||||
nfcElements.input.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Gestion de la visibilité de la page
|
|
||||||
document.addEventListener('visibilitychange', function() {
|
|
||||||
if (!document.hidden) {
|
|
||||||
resetNFCDisplay();
|
|
||||||
nfcElements.input.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Log de démarrage (retirer en production)
|
|
||||||
console.log('NFC Reader initialisé - Mode sécurisé');
|
|
||||||
</script>
|
</script>
|
||||||
Loading…
Reference in New Issue
Block a user