2082 lines
87 KiB
JavaScript
2082 lines
87 KiB
JavaScript
jQuery(function($) {
|
|
jQuery('form.load_simulator').each(function() {
|
|
jQuery(this).attr('action', window.location.origin + '/credit-step1')
|
|
})
|
|
|
|
/**
|
|
* Système de sauvegarde localStorage
|
|
*/
|
|
const FORM_STORAGE_KEY = 'credit_direct_form_data';
|
|
const FORM_STORAGE_TIMESTAMP = 'credit_direct_form_timestamp';
|
|
const STORAGE_EXPIRY_HOURS = 24; // Les données expirent après 24h
|
|
|
|
/**
|
|
* Affiche l'indicateur de sauvegarde
|
|
*/
|
|
function showSaveIndicator(message, type = 'success') {
|
|
let indicator = jQuery('.auto-save-indicator');
|
|
|
|
if (indicator.length === 0) {
|
|
indicator = jQuery('<div class="auto-save-indicator"></div>');
|
|
jQuery('body').append(indicator);
|
|
}
|
|
|
|
indicator.removeClass('show saving error').addClass('show ' + type);
|
|
indicator.text(message);
|
|
|
|
// Masquer après 3 secondes
|
|
setTimeout(() => {
|
|
indicator.removeClass('show');
|
|
}, 3000);
|
|
}
|
|
|
|
/**
|
|
* Sauvegarde les données du formulaire dans localStorage
|
|
*/
|
|
function saveFormData() {
|
|
// Afficher l'indicateur de sauvegarde
|
|
showSaveIndicator('Sauvegarde en cours...', 'saving');
|
|
|
|
const formData = {};
|
|
const currentStep = getCurrentStep();
|
|
|
|
// Récupérer tous les champs du formulaire
|
|
jQuery('form.form-submit').find('input, select, textarea').each(function() {
|
|
const $field = jQuery(this);
|
|
const name = $field.attr('name');
|
|
const type = $field.attr('type');
|
|
|
|
if (!name) return;
|
|
|
|
let value = '';
|
|
|
|
switch (type) {
|
|
case 'checkbox':
|
|
value = $field.is(':checked') ? $field.val() : '';
|
|
break;
|
|
case 'radio':
|
|
if ($field.is(':checked')) {
|
|
value = $field.val();
|
|
}
|
|
break;
|
|
case 'file':
|
|
// Ne pas sauvegarder les fichiers
|
|
return;
|
|
default:
|
|
value = $field.val() || '';
|
|
break;
|
|
}
|
|
|
|
// Ne sauvegarder que si la valeur n'est pas vide
|
|
if (value !== '') {
|
|
formData[name] = value;
|
|
}
|
|
});
|
|
|
|
// Sauvegarder avec l'étape actuelle et le timestamp
|
|
const dataToSave = {
|
|
step: currentStep,
|
|
data: formData,
|
|
timestamp: Date.now()
|
|
};
|
|
|
|
try {
|
|
localStorage.setItem(FORM_STORAGE_KEY, JSON.stringify(dataToSave));
|
|
localStorage.setItem(FORM_STORAGE_TIMESTAMP, Date.now().toString());
|
|
console.log('Données sauvegardées dans localStorage:', dataToSave);
|
|
|
|
// Afficher le succès
|
|
setTimeout(() => {
|
|
showSaveIndicator('Données sauvegardées', 'success');
|
|
}, 500);
|
|
|
|
} catch (e) {
|
|
console.error('Erreur lors de la sauvegarde localStorage:', e);
|
|
showSaveIndicator('Erreur de sauvegarde', 'error');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Restaure les données du formulaire depuis localStorage
|
|
*/
|
|
function restoreFormData() {
|
|
try {
|
|
const savedData = localStorage.getItem(FORM_STORAGE_KEY);
|
|
if (!savedData) return false;
|
|
|
|
const parsedData = JSON.parse(savedData);
|
|
const now = Date.now();
|
|
const savedTime = parsedData.timestamp || 0;
|
|
|
|
console.log('parsedData', parsedData);
|
|
|
|
// Vérifier si les données ne sont pas expirées
|
|
if (now - savedTime > STORAGE_EXPIRY_HOURS * 60 * 60 * 1000) {
|
|
console.log('Données localStorage expirées, suppression...');
|
|
clearFormData();
|
|
return false;
|
|
}
|
|
|
|
const formData = parsedData.data || {};
|
|
let restoredCount = 0;
|
|
|
|
// Traiter d'abord les champs de crédits en cours
|
|
const currentLoansData = {};
|
|
const coCurrentLoansData = {};
|
|
|
|
// Séparer les données des crédits en cours des autres champs
|
|
Object.keys(formData).forEach(name => {
|
|
if (name.startsWith('currentloans[')) {
|
|
const match = name.match(/currentloans\[(\d+)\]\[([^\]]+)\]/);
|
|
if (match) {
|
|
const index = parseInt(match[1]);
|
|
const field = match[2];
|
|
if (!currentLoansData[index]) currentLoansData[index] = {};
|
|
currentLoansData[index][field] = formData[name];
|
|
}
|
|
} else if (name.startsWith('cocurrentloans[')) {
|
|
const match = name.match(/cocurrentloans\[(\d+)\]\[([^\]]+)\]/);
|
|
if (match) {
|
|
const index = parseInt(match[1]);
|
|
const field = match[2];
|
|
if (!coCurrentLoansData[index]) coCurrentLoansData[index] = {};
|
|
coCurrentLoansData[index][field] = formData[name];
|
|
}
|
|
}
|
|
});
|
|
|
|
// Restaurer les valeurs des champs simples
|
|
Object.keys(formData).forEach(name => {
|
|
// Ignorer les champs de crédits en cours (traités séparément)
|
|
if (name.startsWith('currentloans[') || name.startsWith('cocurrentloans[')) {
|
|
return;
|
|
}
|
|
|
|
const $field = jQuery('form.form-submit').find(`[name="${name}"]`);
|
|
if ($field.length === 0) return;
|
|
|
|
const value = formData[name];
|
|
const type = $field.attr('type');
|
|
|
|
switch (type) {
|
|
case 'checkbox':
|
|
if (value) {
|
|
$field.prop('checked', true);
|
|
}
|
|
break;
|
|
case 'radio':
|
|
$field.filter(`[value="${value}"]`).prop('checked', true);
|
|
break;
|
|
default:
|
|
$field.val(value);
|
|
break;
|
|
}
|
|
|
|
// Ajouter un effet visuel temporaire
|
|
$field.addClass('field-restored');
|
|
setTimeout(() => {
|
|
$field.removeClass('field-restored');
|
|
}, 2000);
|
|
|
|
restoredCount++;
|
|
});
|
|
|
|
// Restaurer les crédits en cours de l'emprunteur
|
|
Object.keys(currentLoansData).forEach(index => {
|
|
const loanData = currentLoansData[index];
|
|
const blockIndex = parseInt(index);
|
|
|
|
// Créer le bloc si nécessaire
|
|
while (jQuery('.wpcf-currentloan--block').length <= blockIndex) {
|
|
addCurrentLoan();
|
|
}
|
|
|
|
// Remplir les champs du bloc
|
|
const $block = jQuery('.wpcf-currentloan--block').eq(blockIndex);
|
|
Object.keys(loanData).forEach(field => {
|
|
const $field = $block.find(`[name="currentloans[${index}][${field}]"]`);
|
|
if ($field.length > 0) {
|
|
$field.val(loanData[field]);
|
|
$field.addClass('field-restored');
|
|
setTimeout(() => {
|
|
$field.removeClass('field-restored');
|
|
}, 2000);
|
|
restoredCount++;
|
|
}
|
|
});
|
|
|
|
// Appliquer la logique de désactivation du champ durationmonth selon le type de prêt
|
|
const loanType = loanData.loantype;
|
|
if (loanType === '1') {
|
|
const $durationField = $block.find('input[name*="durationmonth"]');
|
|
if ($durationField.length > 0) {
|
|
$durationField.prop('readonly', true);
|
|
$durationField.addClass('readonly-field');
|
|
}
|
|
|
|
// Mettre à jour les labels selon le type de prêt
|
|
const $borrowedCapitalField = $block.find('input[name*="borrowedcapital"]');
|
|
const $monthlyPaymentField = $block.find('input[name*="monthlypayment"]');
|
|
|
|
if ($borrowedCapitalField.length > 0) {
|
|
const $borrowedCapitalLabel = $borrowedCapitalField.closest('.form-group').find('label');
|
|
if ($borrowedCapitalLabel.length > 0) {
|
|
$borrowedCapitalLabel.text('Plafond de la carte');
|
|
}
|
|
}
|
|
|
|
if ($monthlyPaymentField.length > 0) {
|
|
const $monthlyPaymentLabel = $monthlyPaymentField.closest('.form-group').find('label');
|
|
if ($monthlyPaymentLabel.length > 0) {
|
|
$monthlyPaymentLabel.text('Remboursement mensuel');
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Restaurer les crédits en cours du co-emprunteur
|
|
Object.keys(coCurrentLoansData).forEach(index => {
|
|
const loanData = coCurrentLoansData[index];
|
|
const blockIndex = parseInt(index);
|
|
|
|
// Créer le bloc si nécessaire
|
|
while (jQuery('.wpcf-cocurrentloan--block').length <= blockIndex) {
|
|
addCoCurrentLoan();
|
|
}
|
|
|
|
// Remplir les champs du bloc
|
|
const $block = jQuery('.wpcf-cocurrentloan--block').eq(blockIndex);
|
|
Object.keys(loanData).forEach(field => {
|
|
const $field = $block.find(`[name="cocurrentloans[${index}][${field}]"]`);
|
|
if ($field.length > 0) {
|
|
$field.val(loanData[field]);
|
|
$field.addClass('field-restored');
|
|
setTimeout(() => {
|
|
$field.removeClass('field-restored');
|
|
}, 2000);
|
|
restoredCount++;
|
|
}
|
|
});
|
|
|
|
// Appliquer la logique de désactivation du champ durationmonth selon le type de prêt
|
|
const loanType = loanData.loantype;
|
|
if (loanType === '1') {
|
|
const $durationField = $block.find('input[name*="durationmonth"]');
|
|
if ($durationField.length > 0) {
|
|
$durationField.prop('readonly', true);
|
|
$durationField.addClass('readonly-field');
|
|
}
|
|
|
|
// Mettre à jour les labels selon le type de prêt
|
|
const $borrowedCapitalField = $block.find('input[name*="borrowedcapital"]');
|
|
const $monthlyPaymentField = $block.find('input[name*="monthlypayment"]');
|
|
|
|
if ($borrowedCapitalField.length > 0) {
|
|
const $borrowedCapitalLabel = $borrowedCapitalField.closest('.form-group').find('label');
|
|
if ($borrowedCapitalLabel.length > 0) {
|
|
$borrowedCapitalLabel.text('Plafond de la carte');
|
|
}
|
|
}
|
|
|
|
if ($monthlyPaymentField.length > 0) {
|
|
const $monthlyPaymentLabel = $monthlyPaymentField.closest('.form-group').find('label');
|
|
if ($monthlyPaymentLabel.length > 0) {
|
|
$monthlyPaymentLabel.text('Remboursement mensuel');
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
console.log(`${restoredCount} champs restaurés depuis localStorage`);
|
|
|
|
if (restoredCount > 0) {
|
|
showSaveIndicator(`${restoredCount} champs restaurés`, 'success');
|
|
}
|
|
|
|
return restoredCount > 0;
|
|
|
|
} catch (e) {
|
|
console.error('Erreur lors de la restauration localStorage:', e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Efface les données du formulaire du localStorage
|
|
*/
|
|
function clearFormData() {
|
|
try {
|
|
localStorage.removeItem(FORM_STORAGE_KEY);
|
|
localStorage.removeItem(FORM_STORAGE_TIMESTAMP);
|
|
console.log('Données localStorage effacées');
|
|
|
|
// Masquer le message d'information
|
|
jQuery('.localstorage-info').fadeOut();
|
|
|
|
// Afficher un message de confirmation
|
|
showSaveIndicator('Données effacées', 'success');
|
|
|
|
} catch (e) {
|
|
console.error('Erreur lors de l\'effacement localStorage:', e);
|
|
showSaveIndicator('Erreur lors de l\'effacement', 'error');
|
|
}
|
|
}
|
|
|
|
// Rendre la fonction accessible globalement
|
|
window.clearFormData = clearFormData;
|
|
|
|
/**
|
|
* Détermine l'étape actuelle basée sur l'URL
|
|
*/
|
|
function getCurrentStep() {
|
|
const path = window.location.pathname;
|
|
if (path.includes('credit-step1')) return 'step1';
|
|
if (path.includes('credit-step2')) return 'step2';
|
|
if (path.includes('credit-step3')) return 'step3';
|
|
if (path.includes('credit-step4')) return 'step4';
|
|
if (path.includes('credit-step5')) return 'step5';
|
|
return 'unknown';
|
|
}
|
|
|
|
/**
|
|
* Sauvegarde automatique lors de la modification des champs
|
|
*/
|
|
function setupAutoSave() {
|
|
// Sauvegarde sur clic du lien "previous-step"
|
|
jQuery('a.previous-step').on('click', function(e) {
|
|
/* e.preventDefault(); */
|
|
saveFormData();
|
|
});
|
|
|
|
// Sauvegarde sur changement de valeur (désactivé)
|
|
// jQuery('form.form-submit').on('change input', 'input, select, textarea', function() {
|
|
// // Debounce pour éviter trop de sauvegardes
|
|
// clearTimeout(window.autoSaveTimeout);
|
|
// window.autoSaveTimeout = setTimeout(saveFormData, 1000);
|
|
// });
|
|
|
|
// Sauvegarde sur clic des boutons radio/checkbox (désactivé)
|
|
// jQuery('form.form-submit').on('click', 'input[type="radio"], input[type="checkbox"]', function() {
|
|
// setTimeout(saveFormData, 100);
|
|
// });
|
|
|
|
// Sauvegarde avant soumission du formulaire (désactivé)
|
|
// jQuery('form.form-submit').on('submit', function() {
|
|
// saveFormData();
|
|
// });
|
|
|
|
// Sauvegarde avant navigation (bouton étape précédente) (désactivé)
|
|
// jQuery('a[href*="credit-step"]').on('click', function() {
|
|
// saveFormData();
|
|
// });
|
|
|
|
// Sauvegarde lors de l'ajout/suppression de crédits en cours (désactivé)
|
|
// $(document).on('currentLoanAdded currentLoanRemoved', function() {
|
|
// setTimeout(saveFormData, 500);
|
|
// });
|
|
}
|
|
|
|
/**
|
|
* Affiche le message d'information localStorage
|
|
*/
|
|
function showLocalStorageInfo() {
|
|
const savedData = localStorage.getItem(FORM_STORAGE_KEY);
|
|
if (!savedData) return;
|
|
|
|
// Vérifier si le message existe déjà
|
|
if (jQuery('.localstorage-info').length > 0) return;
|
|
|
|
const infoHtml = `
|
|
<div class="localstorage-info">
|
|
<span class="icon">💾</span>
|
|
Vos données sont sauvegardées automatiquement.
|
|
<button class="clear-storage-btn" onclick="clearFormData()">Effacer</button>
|
|
</div>
|
|
`;
|
|
|
|
// Insérer au début du formulaire
|
|
jQuery('form.form-submit').prepend(infoHtml);
|
|
}
|
|
|
|
/**
|
|
* Initialise le système de sauvegarde
|
|
*/
|
|
function initFormStorage() {
|
|
|
|
if(hasCreditDirectToken())
|
|
return;
|
|
|
|
//check if localStorage is empty
|
|
/* if(localStorage.getItem(FORM_STORAGE_KEY) === null)
|
|
return; */
|
|
|
|
// Restaurer les données au chargement
|
|
const restored = restoreFormData();
|
|
|
|
// Configurer la sauvegarde automatique
|
|
setupAutoSave();
|
|
|
|
// Effacer les données après soumission réussie (optionnel)
|
|
jQuery(document).on('formSubmitted', function() {
|
|
clearFormData();
|
|
});
|
|
|
|
// Si des données ont été restaurées, initialiser l'affichage des zones conditionnelles
|
|
if (restored) {
|
|
setTimeout(function() {
|
|
initializePreFilledValues();
|
|
}, 200);
|
|
}
|
|
|
|
// Afficher le message d'information
|
|
showLocalStorageInfo();
|
|
|
|
console.log('Système de sauvegarde localStorage initialisé');
|
|
}
|
|
|
|
function hasCreditDirectToken() {
|
|
return window.location.search.includes('credit-direct-token');
|
|
}
|
|
|
|
// Initialiser le système de sauvegarde UNIQUEMENT si le paramètre est présent dans l'URL
|
|
// (déplacé après la définition des fonctions addCurrentLoan et addCoCurrentLoan)
|
|
if (hasCreditDirectToken()) {
|
|
}
|
|
|
|
/**
|
|
* General
|
|
*/
|
|
function empty(value) { return value == undefined || value == null || value == [] || value == ''; }
|
|
|
|
function makeLabelRequired(containerSelector = 'body') {
|
|
if (jQuery(containerSelector).length > 0) {
|
|
jQuery(containerSelector).find('input:required, select:required, textarea:required').each(function() {
|
|
var labelId = jQuery(this).attr('id');
|
|
var label = jQuery('label[for="' + labelId + '"]')
|
|
|
|
if (label.length > 0 && label.html().charAt(label.html().length - 1) !== '*') {
|
|
label.html(label.html() + '*')
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Marque les champs initialement requis pour pouvoir restaurer l'attribut required quand on ré-affiche une zone
|
|
function markInitialRequired(containerSelector) {
|
|
if (jQuery(containerSelector).length > 0) {
|
|
jQuery(containerSelector).find('input, select, textarea').each(function() {
|
|
var $el = jQuery(this);
|
|
if ($el.is('[required]')) {
|
|
$el.attr('data-initial-required', '1');
|
|
}
|
|
var pattern = $el.attr('pattern');
|
|
if (typeof pattern !== 'undefined' && pattern !== null && pattern !== '') {
|
|
$el.attr('data-initial-pattern', '1');
|
|
$el.attr('data-initial-pattern-value', pattern);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// Active/désactive l'attribut pattern pour les seuls champs date (input.input-date) du conteneur
|
|
function togglePatternForContainer($container, isVisible) {
|
|
if (!$container || $container.length === 0) { return; }
|
|
$container.find('input.input-date').each(function() {
|
|
var $el = jQuery(this);
|
|
var defaultDatePattern = '\\d{1,2}/\\d{1,2}/\\d{4}';
|
|
// Capture paresseuse du pattern initial si non marqué mais présent
|
|
var currentPattern = $el.attr('pattern');
|
|
if (!$el.attr('data-initial-pattern') && typeof currentPattern !== 'undefined' && currentPattern !== '') {
|
|
$el.attr('data-initial-pattern', '1');
|
|
$el.attr('data-initial-pattern-value', currentPattern);
|
|
}
|
|
|
|
if (isVisible) {
|
|
if ($el.attr('data-initial-pattern') === '1') {
|
|
$el.attr('pattern', $el.attr('data-initial-pattern-value'));
|
|
} else {
|
|
// Si aucun pattern initial, appliquer le pattern date par défaut
|
|
$el.attr('pattern', defaultDatePattern);
|
|
}
|
|
} else {
|
|
$el.removeAttr('pattern');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Retire l'attribut required de tous les champs dans les sections cachées
|
|
// Cette fonction est appelée avant la soumission du formulaire pour éviter l'erreur
|
|
// "An invalid form control with name='...' is not focusable"
|
|
function removeRequiredFromHiddenFields() {
|
|
// Retirer required uniquement des champs qui sont VRAIMENT cachés (display:none ou visibility:hidden)
|
|
// Ne pas toucher aux champs visibles même s'ils ont la classe d-none (qui peut être retirée dynamiquement)
|
|
jQuery('input, select, textarea').each(function() {
|
|
var $field = jQuery(this);
|
|
var $fieldElement = $field[0];
|
|
|
|
// Vérifier si le champ est vraiment caché (display:none ou dans un élément avec display:none)
|
|
var isReallyHidden = false;
|
|
|
|
// Vérifier d'abord si l'élément lui-même est caché
|
|
if ($fieldElement.offsetParent === null && $field.css('display') === 'none') {
|
|
isReallyHidden = true;
|
|
} else {
|
|
// Vérifier si un parent est caché avec display:none ou a la classe 'hidden'
|
|
var $parent = $field.parent();
|
|
while ($parent.length > 0 && !$parent.is('form') && !$parent.is('body')) {
|
|
// Ignorer les sections co-emprunteur qui pourraient être visibles
|
|
if ($parent.hasClass('wpcf-coborrower') || $parent.hasClass('co-borrower-section') || $parent.hasClass('co-emprunteur')) {
|
|
// Si la section co-emprunteur n'est pas vraiment cachée, ne pas retirer required
|
|
if ($parent.css('display') !== 'none' && $parent.is(':visible') && !$parent.hasClass('hidden')) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Vérifier aussi la classe 'hidden' pour les sections comme independent_section
|
|
if ($parent.css('display') === 'none' || !$parent.is(':visible') || $parent.hasClass('hidden')) {
|
|
isReallyHidden = true;
|
|
break;
|
|
}
|
|
$parent = $parent.parent();
|
|
}
|
|
}
|
|
|
|
// Retirer required seulement si vraiment caché ET que ce n'est pas un champ du co-emprunteur visible
|
|
if (isReallyHidden) {
|
|
// Exception : ne pas retirer required des champs du co-emprunteur si celui-ci est activé
|
|
// et que la section est visible (même si elle a la classe d-none)
|
|
var hasCoBorrower = jQuery('input[name="hascoborrower"]:checked').length > 0 &&
|
|
jQuery('input[name="hascoborrower"]:checked').val() == '1';
|
|
|
|
if (hasCoBorrower) {
|
|
var $coSection = $field.closest('.wpcf-coborrower, .co-borrower-section, .co-emprunteur');
|
|
if ($coSection.length > 0) {
|
|
// Vérifier si la section co-emprunteur est visible malgré la classe d-none/hidden
|
|
if ($coSection.is(':visible') && $coSection.css('display') !== 'none' && !$coSection.hasClass('hidden')) {
|
|
// Vérifier aussi si le champ est dans une sous-section cachée (comme independent_section)
|
|
var $hiddenSubSection = $field.closest('.hidden');
|
|
if ($hiddenSubSection.length === 0) {
|
|
// Ne pas retirer required si la section est visible et pas dans une sous-section cachée
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$field.removeAttr('required');
|
|
}
|
|
});
|
|
}
|
|
|
|
if (jQuery('.wpcf-borrower').length > 0) {
|
|
makeLabelRequired('.wpcf-borrower')
|
|
} else {
|
|
makeLabelRequired('.form-submit')
|
|
}
|
|
|
|
// Enregistrer l'état initial des champs requis/pattern (global + zones clés)
|
|
markInitialRequired('.form-submit');
|
|
markInitialRequired('.co-borrower-section');
|
|
markInitialRequired('.wpcf-coborrower');
|
|
markInitialRequired('.isIndependant');
|
|
|
|
/**
|
|
* Step 2
|
|
*/
|
|
function changeJobLabels(value, container) {
|
|
var jobLabels = {
|
|
independent: {
|
|
factory: 'de l\'entreprise',
|
|
salary: 'Revenu imposable annuel',
|
|
startDate: 'de début d\'activité'
|
|
},
|
|
withoutEmployer: {
|
|
employer: 'de l\'employeur/organisme de paiement',
|
|
salary: 'Indemnités mensuelles',
|
|
startDate: 'd\'engagement'
|
|
},
|
|
withEmployer: {
|
|
employer: 'de l\'employeur/organisme de paiement',
|
|
salary: 'Salaire net mensuel',
|
|
startDate: 'd\'engagement'
|
|
}
|
|
}, job = {
|
|
independent: 5,
|
|
withoutEmployer: ['1','6','9','12']
|
|
};
|
|
|
|
console.log('job', value, job.independent);
|
|
|
|
var prefix = container.find('#IDcofirstname').length > 0 ? 'co' : ''
|
|
var fields = ['emname', 'emaddress', 'emzip', 'emcity', 'emcountry', 'commitmentdate', 'salary']
|
|
|
|
fields.forEach(id => {
|
|
var labelText = null
|
|
|
|
switch (id) {
|
|
case 'commitmentdate':
|
|
if(value === job.independent) {
|
|
labelText = jobLabels.independent.startDate
|
|
} else if(job.withoutEmployer.includes(value)) {
|
|
labelText = jobLabels.withoutEmployer.startDate
|
|
} else {
|
|
labelText = jobLabels.withEmployer.startDate
|
|
}
|
|
break;
|
|
|
|
case 'salary':
|
|
|
|
if(value === job.independent) {
|
|
labelText = jobLabels.independent.salary
|
|
} else if(job.withoutEmployer.includes(value)) {
|
|
labelText = jobLabels.withoutEmployer.salary
|
|
} else {
|
|
labelText = jobLabels.withEmployer.salary
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if(value === job.independent) {
|
|
labelText = jobLabels.independent.factory
|
|
} else if(job.withoutEmployer.includes(value)) {
|
|
labelText = jobLabels.withoutEmployer.employer
|
|
} else {
|
|
labelText = jobLabels.withEmployer.employer
|
|
}
|
|
break;
|
|
}
|
|
|
|
container.find('label[for="ID' + prefix + id + '"] > span').text(labelText);
|
|
|
|
console.log('labelText', labelText);
|
|
});
|
|
|
|
/* console.log('container', container);
|
|
console.log('prefix', container.find('.'+prefix+'independent_section')); */
|
|
console.log('value', value);
|
|
|
|
excludedFields = ['IDnotice_of_assessment', 'IDpaycheck', 'IDcopaycheck', 'IDconotice_of_assessment'];
|
|
|
|
if(value == job.independent) {
|
|
container.find('.'+prefix+'independent_section').fadeIn().removeClass('hidden');
|
|
//remove required attributes
|
|
container.find('.'+prefix+'employee_section').find('input, select').removeAttr('required');
|
|
container.find('.'+prefix+'employee_section').fadeOut().addClass('hidden');
|
|
container.find('.'+prefix+'independent_section').find('input, select').each(function() {
|
|
var fieldId = jQuery(this).attr('id');
|
|
if (excludedFields.indexOf(fieldId) === -1) {
|
|
jQuery(this).attr('required', true);
|
|
}
|
|
});
|
|
// Patterns: visible sur independent_section, masqué sur employee_section
|
|
togglePatternForContainer(container.find('.'+prefix+'independent_section'), true);
|
|
togglePatternForContainer(container.find('.'+prefix+'employee_section'), false);
|
|
} else if(job.withoutEmployer.includes(value)) {
|
|
container.find('.withemployer_section').fadeOut().addClass('hidden');
|
|
container.find('.withemployer_section').find('input, select').removeAttr('required');
|
|
togglePatternForContainer(container.find('.withemployer_section'), false);
|
|
|
|
// Retirer aussi required des champs de la section indépendant (cas où on passe de indépendant à sans employeur)
|
|
container.find('.'+prefix+'independent_section').fadeOut().addClass('hidden');
|
|
container.find('.'+prefix+'independent_section').find('input, select').removeAttr('required');
|
|
togglePatternForContainer(container.find('.'+prefix+'independent_section'), false);
|
|
|
|
console.log((jobLabels.withoutEmployer.salary));
|
|
/* container.find('.'+prefix+'IDsalary').prev().text(jobLabels.withoutEmployer.salary);
|
|
|
|
console.log(container.find('#'+prefix+'IDsalary').prev()); */
|
|
} else {
|
|
container.find('.'+prefix+'independent_section').fadeOut().addClass('hidden');
|
|
//not input field required
|
|
container.find('.'+prefix+'employee_section').find('input:not([type="file"]), select').attr('required', true);
|
|
container.find('.'+prefix+'employee_section').fadeIn().removeClass('hidden');
|
|
|
|
//except file inputs
|
|
container.find('.'+prefix+'independent_section').find('input, select').removeAttr('required');
|
|
|
|
if(jQuery('.withemployer_section').hasClass('hidden')) {
|
|
jQuery('.withemployer_section').fadeIn().removeClass('hidden');
|
|
jQuery('.withemployer_section').find('input, select').attr('required', true);
|
|
togglePatternForContainer(jQuery('.withemployer_section'), true);
|
|
}
|
|
// Patterns: visible sur employee_section, masqué sur independent_section
|
|
togglePatternForContainer(container.find('.'+prefix+'employee_section'), true);
|
|
togglePatternForContainer(container.find('.'+prefix+'independent_section'), false);
|
|
}
|
|
|
|
container
|
|
.find('#ID' + prefix + 'emnumber')
|
|
.attr('required', value === job.independent)
|
|
.parent()
|
|
.toggleClass('d-none', value !== job.independent)
|
|
|
|
makeLabelRequired()
|
|
}
|
|
|
|
// Ajouter un gestionnaire sur les boutons submit pour retirer required AVANT la validation HTML5
|
|
jQuery('body').on('click', '.form-submit button[type="submit"]', function(e) {
|
|
// Retirer l'attribut required de tous les champs dans les sections cachées
|
|
// AVANT la validation HTML5 pour éviter l'erreur "not focusable"
|
|
removeRequiredFromHiddenFields();
|
|
});
|
|
|
|
function displayCoBorrower() {
|
|
// Éviter les exécutions multiples
|
|
if (displayCoBorrower._isRunning) {
|
|
return;
|
|
}
|
|
displayCoBorrower._isRunning = true;
|
|
|
|
var
|
|
excludedFieldsName = [
|
|
'cocontract_type',
|
|
'coemname',
|
|
'coemaddress',
|
|
'coemzip',
|
|
'coemcity',
|
|
'coemcountry',
|
|
'cocommitmentdate',
|
|
'cooiamouthmealvoucher',
|
|
'cooiamouthrentalincome',
|
|
'cooiamouthunemployment',
|
|
'cooiamouthother',
|
|
'cooiothertext',
|
|
'co_secteur_activite',
|
|
'co_num_tva',
|
|
'coMtn_loyer',
|
|
'coHabitation_loyer'
|
|
],
|
|
hasCoBorrower =
|
|
jQuery('input[name="hascoborrower"]:checked').length > 0 &&
|
|
jQuery('input[name="hascoborrower"]:checked').val() == 1,
|
|
key = '.wpcf-coborrower',
|
|
cols_key = '.credit-cols';
|
|
|
|
console.log('hasCoBorrower', hasCoBorrower);
|
|
|
|
// Gestion de l'affichage/masquage
|
|
jQuery(key).toggleClass('d-none', !hasCoBorrower);
|
|
jQuery('.co-borrower-section').toggleClass('d-none', !hasCoBorrower);
|
|
// Note: .co-emprunteur est géré dans cd_main.js pour le formulaire one-step
|
|
|
|
// Gérer l'attribut required/pattern en fonction de la visibilité
|
|
var coContainers = jQuery(key).add('.co-borrower-section');
|
|
var cojobValue = jQuery('select[name="cojob"]').val();
|
|
var isCojobIndependent = cojobValue === '5';
|
|
|
|
if (hasCoBorrower) {
|
|
coContainers.find('input, select, textarea').each(function() {
|
|
var wasRequired = jQuery(this).attr('data-initial-required') === '1';
|
|
if (wasRequired) {
|
|
jQuery(this).attr('required', true);
|
|
} else {
|
|
jQuery(this).removeAttr('required');
|
|
}
|
|
});
|
|
|
|
// Gestion des patterns selon le statut indépendant du cojob
|
|
// Activer les patterns pour tous les conteneurs sauf co-independent_section / coindependent_section
|
|
togglePatternForContainer(coContainers.not('.co-independent_section, .coindependent_section'), true);
|
|
|
|
// Pour co-independent_section / coindependent_section, activer le pattern uniquement si cojob = 5
|
|
if (isCojobIndependent) {
|
|
togglePatternForContainer(jQuery('.co-independent_section, .coindependent_section'), true);
|
|
} else {
|
|
togglePatternForContainer(jQuery('.co-independent_section, .coindependent_section'), false);
|
|
}
|
|
} else {
|
|
coContainers.find('input, select, textarea').removeAttr('required');
|
|
togglePatternForContainer(coContainers, false);
|
|
}
|
|
|
|
makeLabelRequired();
|
|
|
|
// Gestion des colonnes
|
|
if (hasCoBorrower) {
|
|
// Mode deux colonnes
|
|
jQuery(cols_key).removeClass('col-md-12').addClass('col-md-6');
|
|
|
|
// Ajuster les colonnes internes
|
|
jQuery('.credit-cols [class*="col-md-"]').each(function() {
|
|
var classes = jQuery(this).attr('class').split(' ');
|
|
classes.forEach(function(className) {
|
|
if (className.startsWith('col-md-')) {
|
|
var currentSize = parseInt(className.replace('col-md-', ''));
|
|
console.log('currentSize', currentSize);
|
|
|
|
// Sauvegarder la taille originale si ce n'est pas déjà fait
|
|
if (!jQuery(this).data('original-size')) {
|
|
jQuery(this).data('original-size', className);
|
|
}
|
|
|
|
// Définir la nouvelle taille
|
|
jQuery(this).removeClass(className).addClass('col-md-12');
|
|
}
|
|
}.bind(this));
|
|
});
|
|
|
|
// Ajuster spécifiquement les colonnes dans .other-credit-cols et ses sous-éléments
|
|
jQuery('.other-credit-cols').find('[class*="col-md-"]').each(function() {
|
|
var classes = jQuery(this).attr('class').split(' ');
|
|
classes.forEach(function(className) {
|
|
if (className.startsWith('col-md-')) {
|
|
var currentSize = parseInt(className.replace('col-md-', ''));
|
|
console.log('currentSize other-credit-cols', currentSize);
|
|
|
|
// Sauvegarder la taille originale si ce n'est pas déjà fait
|
|
if (!jQuery(this).data('original-size')) {
|
|
jQuery(this).data('original-size', className);
|
|
}
|
|
|
|
// Définir la nouvelle taille pour .other-credit-cols et ses sous-éléments
|
|
jQuery(this).removeClass(className).addClass('col-md-6');
|
|
}
|
|
}.bind(this));
|
|
});
|
|
} else {
|
|
// Mode une colonne
|
|
jQuery('.credit-cols .wpcf-borrower').removeClass('col-md-6');
|
|
|
|
if(!jQuery(cols_key).hasClass('col-md-12'))
|
|
jQuery(cols_key).addClass('col-md-12').removeClass('col-md-6');
|
|
|
|
// Restaurer les colonnes internes à leur taille d'origine
|
|
jQuery('.credit-cols [class*="col-md-"]').each(function() {
|
|
var originalSize = jQuery(this).data('original-size');
|
|
|
|
if (originalSize) {
|
|
// Supprimer toutes les classes col-md-* actuelles
|
|
var classes = jQuery(this).attr('class').split(' ');
|
|
classes.forEach(function(className) {
|
|
if (className.startsWith('col-md-')) {
|
|
jQuery(this).removeClass(className);
|
|
}
|
|
}.bind(this));
|
|
|
|
// Restaurer la taille originale
|
|
jQuery(this).addClass(originalSize);
|
|
}
|
|
});
|
|
|
|
// Pour .other-credit-cols, forcer une taille appropriée même sans co-emprunteur
|
|
jQuery('.other-credit-cols').find('[class*="col-md-"]').each(function() {
|
|
// Supprimer toutes les classes col-md-* actuelles
|
|
var classes = jQuery(this).attr('class').split(' ');
|
|
classes.forEach(function(className) {
|
|
if (className.startsWith('col-md-')) {
|
|
jQuery(this).removeClass(className);
|
|
}
|
|
}.bind(this));
|
|
|
|
// Toujours appliquer col-md-6 pour .other-credit-cols, même sans co-emprunteur
|
|
jQuery(this).addClass('col-md-6');
|
|
});
|
|
}
|
|
|
|
// Gestion des champs requis
|
|
jQuery(key).find('input[type="text"], input[type="number"], input[type="date"], select, textarea').each(function() {
|
|
if (excludedFieldsName.indexOf(jQuery(this).attr('name')) < 0) {
|
|
jQuery(this).attr('required', hasCoBorrower)
|
|
}
|
|
})
|
|
|
|
if (!hasCoBorrower) {
|
|
jQuery(key).find('input[type="checkbox"]:checked, input[type="radio"][value="0"]').each(function() {
|
|
jQuery(this).prop('checked', jQuery(this).attr('type') === 'radio')
|
|
})
|
|
|
|
jQuery(key).find('input:not([type="checkbox"]):not([type="radio"]), select, textarea').each(function() {
|
|
jQuery(this).val('')
|
|
})
|
|
}
|
|
|
|
makeLabelRequired(key)
|
|
|
|
// Afficher les autres revenus si nécessaire (même si cojob = 5)
|
|
displayOtherIncome(
|
|
hasCoBorrower && jQuery('input[name="cohasotherincome"]:checked').length > 0 && jQuery('input[name="cohasotherincome"]:checked').val() == 1,
|
|
'.co'
|
|
);
|
|
|
|
// Réinitialiser le flag après un court délai
|
|
setTimeout(function() {
|
|
displayCoBorrower._isRunning = false;
|
|
}, 50);
|
|
}
|
|
|
|
function displayOtherIncome(show, key) {
|
|
var target = jQuery('.wpcf-otherincome' + key)
|
|
|
|
if (target.length > 0) {
|
|
target.toggleClass('d-none', !show);
|
|
|
|
if (!show) {
|
|
target.find('input[type="checkbox"]:checked, input[type="radio"][value="0"]').each(function() {
|
|
jQuery(this).prop('checked', jQuery(this).attr('type') === 'radio')
|
|
})
|
|
}
|
|
|
|
displayOtherIncomeSubFields(target.find('input[type="checkbox"], input[type="radio"]:checked'))
|
|
}
|
|
}
|
|
|
|
function displayOtherIncomeSubFields(el) {
|
|
el.each(function() {
|
|
var subFields = jQuery(this).closest('.form-row').find('.form-group')
|
|
|
|
if (subFields.length > 0) {
|
|
subFields.toggleClass('d-none', !jQuery(this).is(':checked'))
|
|
subFields.find('input').attr('required', jQuery(this).is(':checked'))
|
|
}
|
|
})
|
|
}
|
|
|
|
function initializePreFilledValues() {
|
|
// Gérer l'affichage des sections basé sur les valeurs pré-remplies
|
|
setTimeout(function() {
|
|
// Vérifier si hascoborrower est pré-rempli
|
|
var hasCoBorrowerChecked = jQuery('input[name="hascoborrower"]:checked');
|
|
if (hasCoBorrowerChecked.length > 0) {
|
|
displayCoBorrower();
|
|
}
|
|
|
|
// Vérifier si hasotherincome est pré-rempli (emprunteur)
|
|
var hasOtherIncomeChecked = jQuery('input[name="hasotherincome"]:checked');
|
|
if (hasOtherIncomeChecked.length > 0) {
|
|
displayOtherIncome(hasOtherIncomeChecked.val() == 1, '.em');
|
|
}
|
|
|
|
// Vérifier si cohasotherincome est pré-rempli (co-emprunteur)
|
|
var coHasOtherIncomeChecked = jQuery('input[name="cohasotherincome"]:checked');
|
|
if (coHasOtherIncomeChecked.length > 0) {
|
|
displayOtherIncome(coHasOtherIncomeChecked.val() == 1, '.co');
|
|
}
|
|
|
|
// Vérifier si hascurrentloan est pré-rempli
|
|
var hasCurrentLoanChecked = jQuery('input[name="hascurrentloan"]:checked');
|
|
if (hasCurrentLoanChecked.length > 0) {
|
|
var isChecked = hasCurrentLoanChecked.val() == '1';
|
|
jQuery('.wpcf-currentloan').toggleClass('d-none', !isChecked);
|
|
}
|
|
|
|
// Vérifier si cohascurrentloan est pré-rempli
|
|
var coHasCurrentLoanChecked = jQuery('input[name="cohascurrentloan"]:checked');
|
|
if (coHasCurrentLoanChecked.length > 0) {
|
|
var isChecked = coHasCurrentLoanChecked.val() == '1';
|
|
jQuery('.wpcf-cocurrentloan').toggleClass('d-none', !isChecked);
|
|
}
|
|
|
|
// Gérer les champs autres revenus pré-remplis
|
|
jQuery('.wpcf-otherincome input[type="checkbox"]:checked').each(function() {
|
|
displayOtherIncomeSubFields(jQuery(this));
|
|
});
|
|
|
|
// Gérer les champs indépendant pré-remplis
|
|
var jobSelect = jQuery('select[name="job"]');
|
|
if (jobSelect.length > 0 && jobSelect.val()) {
|
|
changeJobLabels(jobSelect.val(), jobSelect.closest('fieldset'));
|
|
}
|
|
|
|
var coJobSelect = jQuery('select[name="cojob"]');
|
|
if (coJobSelect.length > 0 && coJobSelect.val()) {
|
|
changeJobLabels(coJobSelect.val(), coJobSelect.closest('fieldset'));
|
|
}
|
|
}, 100); // Petit délai pour s'assurer que le DOM est chargé
|
|
}
|
|
|
|
var hasCoBorrowerField = jQuery('input[name="hascoborrower"]:checked')
|
|
|
|
if (hasCoBorrowerField.length > 0) {
|
|
displayCoBorrower()
|
|
}
|
|
|
|
if (jQuery('input[name="hasotherincome"]:checked').length > 0) {
|
|
displayOtherIncome(jQuery('input[name="hasotherincome"]:checked').val() == 1, '.em')
|
|
}
|
|
|
|
// Initialisation pour les valeurs pré-remplies
|
|
initializePreFilledValues();
|
|
|
|
// Flag pour éviter les déclenchements multiples
|
|
var isProcessingJobChange = false;
|
|
|
|
jQuery('body').on('change', 'input[name="hascoborrower"]', function() {
|
|
// Éviter les déclenchements multiples quand cojob = 5
|
|
if (!isProcessingJobChange) {
|
|
displayCoBorrower();
|
|
}
|
|
});
|
|
|
|
jQuery('body').on('change', 'input[name="hasotherincome"]', function() {
|
|
displayOtherIncome(jQuery(this).val() == 1, '.em')
|
|
});
|
|
|
|
jQuery('body').on('change', 'input.wpcf-otherincome--oitype', function(e) {
|
|
displayOtherIncomeSubFields(jQuery(e.target))
|
|
});
|
|
|
|
jQuery('body').on('change', 'input[name="cohasotherincome"]', function() {
|
|
displayOtherIncome(jQuery(this).val() == 1, '.co')
|
|
});
|
|
|
|
jQuery('body').on('change', 'select[name="job"], select[name="cojob"]', function() {
|
|
var jobValue = jQuery(this).val();
|
|
var isCojob = jQuery(this).attr('name') === 'cojob';
|
|
var container = jQuery(this).closest('fieldset');
|
|
|
|
// Activer le flag pour éviter les déclenchements multiples
|
|
isProcessingJobChange = true;
|
|
|
|
// Appeler changeJobLabels
|
|
changeJobLabels(jobValue, container);
|
|
|
|
// Si c'est cojob, mettre à jour les patterns dans displayCoBorrower
|
|
if (isCojob) {
|
|
var hasCoBorrower = jQuery('input[name="hascoborrower"]:checked').length > 0 &&
|
|
jQuery('input[name="hascoborrower"]:checked').val() == 1;
|
|
|
|
if (hasCoBorrower) {
|
|
// Mettre à jour les patterns pour co-independent_section / coindependent_section selon la valeur
|
|
if (jobValue == '5') {
|
|
togglePatternForContainer(jQuery('.co-independent_section, .coindependent_section'), true);
|
|
} else {
|
|
togglePatternForContainer(jQuery('.co-independent_section, .coindependent_section'), false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Si c'est cojob et valeur = 5, éviter de déclencher displayCoBorrower en cascade
|
|
if (isCojob && jobValue == '5') {
|
|
// Attendre un peu avant de réactiver pour éviter les cascades
|
|
setTimeout(function() {
|
|
isProcessingJobChange = false;
|
|
}, 100);
|
|
} else {
|
|
isProcessingJobChange = false;
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Step 3
|
|
*/
|
|
jQuery('body').on('change', 'select[name="hometype"], select[name="cohometype"]', function(e) {
|
|
var val = jQuery(this).val(),
|
|
c = 'd-none',
|
|
cname = 'wpcf-' + jQuery(this).attr('name') + '--complement-home' + val,
|
|
elements = jQuery('.wpcf-' + jQuery(this).attr('name') + '--complement .form-group');
|
|
|
|
elements.addClass(c);
|
|
|
|
elements.each(function() {
|
|
if (jQuery(this).hasClass(cname)) {
|
|
jQuery('.' + cname).removeClass(c);
|
|
}
|
|
|
|
jQuery(this).find('input, select').attr('required', !jQuery(this).hasClass(c))
|
|
// Synchroniser aussi le pattern avec la visibilité (comme required)
|
|
togglePatternForContainer(jQuery(this), !jQuery(this).hasClass(c))
|
|
makeLabelRequired(jQuery(this).context)
|
|
})
|
|
|
|
});
|
|
|
|
var currentLoanProto = jQuery('.wpcf-currentloan--block').length > 0 ? jQuery('.wpcf-currentloan--block') : null;
|
|
var currentLoanCount = 0;
|
|
|
|
if (currentLoanProto !== null) {
|
|
currentLoanProto.removeClass('wpcf-prototype');
|
|
currentLoanProto = currentLoanProto[0].outerHTML
|
|
jQuery('.wpcf-currentloan--block').remove()
|
|
}
|
|
|
|
var coCurrentLoanProto = jQuery('.wpcf-cocurrentloan--block').length > 0 ? jQuery('.wpcf-cocurrentloan--block') : null;
|
|
var coCurrentLoanCount = 0;
|
|
|
|
if (coCurrentLoanProto !== null) {
|
|
coCurrentLoanProto.removeClass('wpcf-prototype');
|
|
coCurrentLoanProto = coCurrentLoanProto[0].outerHTML
|
|
jQuery('.wpcf-cocurrentloan--block').remove()
|
|
}
|
|
|
|
jQuery('body').on('change', 'input[name="hascurrentloan"], input[name="cohascurrentloan"]', function(e) {
|
|
var selector = jQuery(this).attr('name') === 'hascurrentloan' ? '.wpcf-currentloan' : '.wpcf-cocurrentloan';
|
|
var elem = jQuery(selector),
|
|
c = 'd-none';
|
|
// Pour les radio, on vérifie la value sélectionnée
|
|
var isChecked = jQuery('input[name="' + jQuery(this).attr('name') + '"]:checked').val() == '1';
|
|
elem.toggleClass(c, !isChecked);
|
|
if (!isChecked) {
|
|
jQuery(this).attr('name') === 'hascurrentloan' ? jQuery('.wpcf-currentloan--block').remove() : jQuery('.wpcf-cocurrentloan--block').remove();
|
|
} else if (elem.find(selector + '--block').length < 1) {
|
|
jQuery(this).attr('name') === 'hascurrentloan' ? addCurrentLoan() : addCoCurrentLoan();
|
|
}
|
|
});
|
|
|
|
// Affichage initial au chargement de la page
|
|
function updateCurrentLoanVisibility() {
|
|
var isChecked = jQuery('input[name="hascurrentloan"]:checked').val() == '1';
|
|
jQuery('.wpcf-currentloan').toggleClass('d-none', !isChecked);
|
|
if (!isChecked) {
|
|
jQuery('.wpcf-currentloan--block').remove();
|
|
} else if (jQuery('.wpcf-currentloan--block').length < 1) {
|
|
addCurrentLoan();
|
|
}
|
|
var isCoChecked = jQuery('input[name="cohascurrentloan"]:checked').val() == '1';
|
|
jQuery('.wpcf-cocurrentloan').toggleClass('d-none', !isCoChecked);
|
|
if (!isCoChecked) {
|
|
jQuery('.wpcf-cocurrentloan--block').remove();
|
|
} else if (jQuery('.wpcf-cocurrentloan--block').length < 1) {
|
|
addCoCurrentLoan();
|
|
}
|
|
}
|
|
// Appel au chargement
|
|
updateCurrentLoanVisibility();
|
|
|
|
// Initialiser l'état des champs durationmonth et labels selon les types de prêt existants
|
|
function initializeDurationMonthFields() {
|
|
jQuery('.wpcf-currentloan--block, .wpcf-cocurrentloan--block').each(function() {
|
|
const $block = jQuery(this);
|
|
const $loanTypeField = $block.find('select[name*="loantype"]');
|
|
const $durationField = $block.find('input[name*="durationmonth"]');
|
|
const $borrowedCapitalField = $block.find('input[name*="borrowedcapital"]');
|
|
const $monthlyPaymentField = $block.find('input[name*="monthlypayment"]');
|
|
|
|
if ($loanTypeField.length > 0) {
|
|
const selectedValue = $loanTypeField.val();
|
|
|
|
// Gestion du champ durationmonth
|
|
if ($durationField.length > 0) {
|
|
if (selectedValue === '1') {
|
|
$durationField.prop('readonly', true);
|
|
$durationField.addClass('readonly-field');
|
|
} else {
|
|
$durationField.prop('readonly', false);
|
|
$durationField.removeClass('readonly-field');
|
|
}
|
|
}
|
|
|
|
// Gestion des labels borrowedcapital
|
|
if ($borrowedCapitalField.length > 0) {
|
|
const $borrowedCapitalLabel = $borrowedCapitalField.closest('.form-group').find('label');
|
|
if ($borrowedCapitalLabel.length > 0) {
|
|
if (selectedValue === '1') {
|
|
$borrowedCapitalLabel.text('Plafond de la carte');
|
|
} else {
|
|
$borrowedCapitalLabel.text('Capital emprunté');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Gestion des labels monthlypayment
|
|
if ($monthlyPaymentField.length > 0) {
|
|
const $monthlyPaymentLabel = $monthlyPaymentField.closest('.form-group').find('label');
|
|
if ($monthlyPaymentLabel.length > 0) {
|
|
if (selectedValue === '1') {
|
|
$monthlyPaymentLabel.text('Remboursement mensuel');
|
|
} else {
|
|
$monthlyPaymentLabel.text('Mensualité');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initialiser au chargement de la page
|
|
initializeDurationMonthFields();
|
|
|
|
// Initialiser le système de sauvegarde après la définition des fonctions addCurrentLoan et addCoCurrentLoan
|
|
initFormStorage();
|
|
|
|
jQuery('body').on('click', 'button.wpcf-currentload--add, button.wpcf-cocurrentload--add', function(e) {
|
|
e.preventDefault()
|
|
jQuery(this).hasClass('wpcf-currentload--add') ? addCurrentLoan() : addCoCurrentLoan()
|
|
})
|
|
|
|
function addCurrentLoan() {
|
|
var newLoan = currentLoanProto.replaceAll('__number__', currentLoanCount)
|
|
jQuery(newLoan).insertBefore(jQuery('.wpcf-currentload--add'))
|
|
|
|
currentLoanCount++
|
|
|
|
// Déclencher l'événement personnalisé pour la sauvegarde
|
|
$(document).trigger('currentLoanAdded');
|
|
}
|
|
|
|
function addCoCurrentLoan() {
|
|
var newLoan = coCurrentLoanProto.replaceAll('__number__', coCurrentLoanCount)
|
|
jQuery(newLoan).insertBefore(jQuery('.wpcf-cocurrentload--add'))
|
|
|
|
coCurrentLoanCount++
|
|
|
|
// Déclencher l'événement personnalisé pour la sauvegarde
|
|
$(document).trigger('currentLoanAdded');
|
|
}
|
|
|
|
jQuery('body').on('click', '.wpcf-currentloan--block--remove, .wpcf-cocurrentloan--block--remove', function(e) {
|
|
e.preventDefault();
|
|
jQuery(this).parent().remove();
|
|
|
|
// Déclencher l'événement personnalisé pour la sauvegarde
|
|
$(document).trigger('currentLoanRemoved');
|
|
});
|
|
|
|
// Gestionnaire pour les champs de type de prêt des crédits en cours
|
|
jQuery('body').on('change', 'select[name*="loantype"]', function() {
|
|
const selectedValue = jQuery(this).val();
|
|
const $currentBlock = jQuery(this).closest('.wpcf-currentloan--block, .wpcf-cocurrentloan--block');
|
|
|
|
console.log('Type de prêt sélectionné:', selectedValue, 'dans le bloc:', $currentBlock);
|
|
|
|
// Gestion du champ durationmonth selon le type de prêt
|
|
const $durationField = $currentBlock.find('input[name*="durationmonth"]');
|
|
if ($durationField.length > 0) {
|
|
if (selectedValue === '1') {
|
|
// Si le type de prêt vaut "1", rendre le champ durationmonth readonly
|
|
$durationField.prop('readonly', true);
|
|
$durationField.addClass('readonly-field');
|
|
console.log('Champ durationmonth mis en readonly');
|
|
} else {
|
|
// Sinon, rendre le champ éditable
|
|
$durationField.prop('readonly', false);
|
|
$durationField.removeClass('readonly-field');
|
|
console.log('Champ durationmonth rendu éditable');
|
|
}
|
|
}
|
|
|
|
// Gestion des labels des champs borrowedcapital et monthlypayment
|
|
const $borrowedCapitalField = $currentBlock.find('input[name*="borrowedcapital"]');
|
|
const $monthlyPaymentField = $currentBlock.find('input[name*="monthlypayment"]');
|
|
|
|
if ($borrowedCapitalField.length > 0) {
|
|
const $borrowedCapitalLabel = $borrowedCapitalField.closest('.form-group').find('label');
|
|
if ($borrowedCapitalLabel.length > 0) {
|
|
if (selectedValue === '1') {
|
|
$borrowedCapitalLabel.text('Plafond de la carte');
|
|
} else {
|
|
$borrowedCapitalLabel.text('Capital emprunté');
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($monthlyPaymentField.length > 0) {
|
|
const $monthlyPaymentLabel = $monthlyPaymentField.closest('.form-group').find('label');
|
|
if ($monthlyPaymentLabel.length > 0) {
|
|
if (selectedValue === '1') {
|
|
$monthlyPaymentLabel.text('Remboursement mensuel');
|
|
} else {
|
|
$monthlyPaymentLabel.text('Mensualité');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ici vous pouvez ajouter la logique spécifique selon le type de prêt sélectionné
|
|
// Par exemple, afficher/masquer d'autres champs selon le type
|
|
|
|
// Exemple de logique conditionnelle selon le type de prêt
|
|
switch(selectedValue) {
|
|
case '1': // Hypothèque
|
|
console.log('Prêt hypothécaire sélectionné');
|
|
// Logique spécifique pour les prêts hypothécaires
|
|
break;
|
|
case '2': // Prêt personnel
|
|
console.log('Prêt personnel sélectionné');
|
|
// Logique spécifique pour les prêts personnels
|
|
break;
|
|
case '3': // Crédit auto
|
|
console.log('Crédit auto sélectionné');
|
|
// Logique spécifique pour les crédits auto
|
|
break;
|
|
default:
|
|
console.log('Autre type de prêt sélectionné:', selectedValue);
|
|
break;
|
|
}
|
|
|
|
// Déclencher l'événement personnalisé pour la sauvegarde
|
|
$(document).trigger('currentLoanTypeChanged', {
|
|
value: selectedValue,
|
|
block: $currentBlock
|
|
});
|
|
});
|
|
|
|
// Fonction pour afficher/cacher la zone isFichedDisplay
|
|
function displayIsFichedZone() {
|
|
var hasFiched = jQuery('input[name="isFiched"]:checked').length > 0 &&
|
|
jQuery('input[name="isFiched"]:checked').val() == 1;
|
|
|
|
jQuery('.isFichedDisplay').toggleClass('d-none', !hasFiched);
|
|
}
|
|
|
|
// Vérifier l'état initial
|
|
var isFichedField = jQuery('input[name="isFiched"]:checked');
|
|
if (isFichedField.length > 0) {
|
|
displayIsFichedZone();
|
|
}
|
|
|
|
// Ajouter l'écouteur d'événement pour le changement
|
|
jQuery('body').on('change', 'input[name="isFiched"]', displayIsFichedZone);
|
|
|
|
// Fonction pour afficher/cacher la zone isIndependant
|
|
function displayIsIndependantZone() {
|
|
var isIndependant = jQuery('select[name="job"]').val() === '5';
|
|
var zone = jQuery('.isIndependant');
|
|
zone.toggleClass('d-none', !isIndependant);
|
|
|
|
// Gérer l'attribut required/pattern en fonction de la visibilité
|
|
if (isIndependant) {
|
|
zone.find('input, select, textarea').each(function() {
|
|
var wasRequired = jQuery(this).attr('data-initial-required') === '1';
|
|
if (wasRequired) {
|
|
jQuery(this).attr('required', true);
|
|
} else {
|
|
jQuery(this).removeAttr('required');
|
|
}
|
|
});
|
|
togglePatternForContainer(zone, true);
|
|
} else {
|
|
zone.find('input, select, textarea').removeAttr('required');
|
|
togglePatternForContainer(zone, false);
|
|
}
|
|
|
|
makeLabelRequired();
|
|
}
|
|
|
|
// Vérifier l'état initial
|
|
var jobSelect = jQuery('select[name="job"]');
|
|
if (jobSelect.length > 0) {
|
|
displayIsIndependantZone();
|
|
}
|
|
|
|
// Ajouter l'écouteur d'événement pour le changement
|
|
jQuery('body').on('change', 'select[name="job"]', displayIsIndependantZone);
|
|
|
|
// Fonction pour afficher/cacher la zone hasLoyer
|
|
function displayHasLoyerZone() {
|
|
var isLocataire = jQuery('select[name="habitation_type"]').val() === 'locataire';
|
|
jQuery('.hasLoyer').toggleClass('d-none', !isLocataire);
|
|
}
|
|
|
|
// Vérifier l'état initial
|
|
var situationSelect = jQuery('select[name="habitation_type"]');
|
|
if (situationSelect.length > 0) {
|
|
displayHasLoyerZone();
|
|
}
|
|
|
|
// Ajouter l'écouteur d'événement pour le changement
|
|
jQuery('body').on('change', 'select[name="habitation_type"]', displayHasLoyerZone);
|
|
|
|
// Affichage de la taille totale des fichiers sélectionnés pour le champ IDpaycheck + vérification taille max 2 Mo
|
|
jQuery('body').on('change', '#IDpaycheck, #IDcopaycheck', function(e) {
|
|
var files = e.target.files;
|
|
var totalSize = 0;
|
|
var maxSize = 2 * 1024 * 1024; // 2 Mo en octets
|
|
var errorFiles = [];
|
|
for (var i = 0; i < files.length; i++) {
|
|
totalSize += files[i].size;
|
|
if (files[i].size > maxSize) {
|
|
errorFiles.push(files[i].name);
|
|
}
|
|
}
|
|
// Conversion en Mo, arrondi à 2 décimales
|
|
var totalSizeMo = (totalSize / (1024 * 1024)).toFixed(2);
|
|
// Création ou sélection de l'élément d'affichage
|
|
var infoId = 'paycheck-size-info';
|
|
var infoElem = jQuery('#' + infoId);
|
|
if (infoElem.length === 0) {
|
|
infoElem = jQuery('<div id="' + infoId + '" style="font-size:0.9em;color:#555;"></div>');
|
|
jQuery(this).after(infoElem);
|
|
}
|
|
// Création ou sélection de l'élément d'erreur
|
|
var errorId = 'paycheck-size-error';
|
|
var errorElem = jQuery('#' + errorId);
|
|
if (errorElem.length === 0) {
|
|
errorElem = jQuery('<div id="' + errorId + '" style="font-size:0.95em;color:#c00;"></div>');
|
|
infoElem.after(errorElem);
|
|
}
|
|
var submitBtn = jQuery('.form-submit button[type="submit"]');
|
|
if (files.length > 0) {
|
|
infoElem.text('Taille totale des fichiers sélectionnés : ' + totalSizeMo + ' Mo');
|
|
} else {
|
|
infoElem.text('');
|
|
}
|
|
if (errorFiles.length > 0) {
|
|
errorElem.html('Fichier(s) trop volumineux (> 2 Mo) :<br><b>' + errorFiles.join(', ') + '</b>');
|
|
submitBtn.prop('disabled', true);
|
|
} else {
|
|
errorElem.text('');
|
|
submitBtn.prop('disabled', false);
|
|
}
|
|
});
|
|
|
|
// Affichage conditionnel du champ "fonds propres" selon le choix Oui/Non avec effet slide
|
|
const yesRadio = document.getElementById('estateequity_yes');
|
|
const noRadio = document.getElementById('estateequity_no');
|
|
if (yesRadio && noRadio) {
|
|
$(yesRadio).on('change', function() {
|
|
if (yesRadio.checked) {
|
|
$('.fonds-propres').stop(true, true).slideDown();
|
|
$('[name="estateequity"]').prop('required', true);
|
|
}
|
|
});
|
|
$(noRadio).on('change', function() {
|
|
if (noRadio.checked) {
|
|
$('.fonds-propres').stop(true, true).slideUp();
|
|
$('[name="estateequity"]').prop('required', false);
|
|
}
|
|
});
|
|
// Initialisation à l'ouverture de la page
|
|
if (yesRadio.checked) {
|
|
$('.fonds-propres').show();
|
|
} else {
|
|
$('.fonds-propres').hide();
|
|
}
|
|
}
|
|
|
|
// Variables pour le debouncing des inputs
|
|
let capitalTimeout;
|
|
let durationTimeout;
|
|
let isCreditCalculationEnabled = true;
|
|
|
|
if(jQuery('#creditCalcManualSwitch').length > 0)
|
|
isCreditCalculationEnabled = true;
|
|
|
|
// Liste des types de crédit qui utilisent des années
|
|
const LOAN_TYPES_IN_YEARS = ['am', 'amr', 'cied', 'ph'];
|
|
|
|
// Fonction pour mettre à jour l'affichage des valeurs calculées
|
|
function updateCreditDisplay(result) {
|
|
console.log('updateCreditDisplay - result:', result);
|
|
|
|
// Calcul du TAEG
|
|
const taeg = parseFloat(result.taux_nominal_annuel.replace('%', ''));
|
|
const taux_debiteur = (taeg * 0.11 + taeg).toFixed(2);
|
|
|
|
// Mise à jour des champs cachés
|
|
jQuery('input[name="capital"]').val(result.capital);
|
|
jQuery('input[name="duree"]').val(result.duree);
|
|
jQuery('input[name="cout_total"]').val(result.cout_total);
|
|
jQuery('input[name="mensualite"]').val(result.mensualite);
|
|
jQuery('input[name="taux_nominal_annuel"]').val(result.taux_nominal_annuel);
|
|
|
|
console.log('updateCreditDisplay - Champs cachés mis à jour:', {
|
|
capital: result.capital,
|
|
duree: result.duree,
|
|
cout_total: result.cout_total,
|
|
mensualite: result.mensualite,
|
|
taux: result.taux_nominal_annuel
|
|
});
|
|
|
|
// Mise à jour de l'affichage dans .credit-info
|
|
jQuery('.credit-info .credit-item').each(function() {
|
|
var $value = jQuery(this).find('.credit-value');
|
|
var $label = jQuery(this).find('.credit-label');
|
|
|
|
if($label.text().includes('Montant:')) {
|
|
$value.text(result.capital + ' €');
|
|
}
|
|
else if($label.text().includes('Durée:')) {
|
|
$value.text(result.duree + ($('input[name="type_credit"]').val() === 'am' ? ' ans' : ' mois'));
|
|
}
|
|
else if($label.text().includes('Mensualité:')) {
|
|
$value.text(result.mensualite + '€');
|
|
}
|
|
else if($label.text().includes('Coût total:')) {
|
|
$value.text(result.cout_total + '€');
|
|
}
|
|
else if($label.text().includes('TAEG:')) {
|
|
$value.text(taux_debiteur + '%');
|
|
}
|
|
else if($label.text().includes('Taux débiteur:')) {
|
|
$value.text(result.taux_nominal_annuel);
|
|
}
|
|
});
|
|
|
|
// Mise à jour du récapitulatif dans .info-credits-step
|
|
jQuery('.info-credits-step .row > div').each(function() {
|
|
$(this).find('p').each(function() {
|
|
var $label = $(this);
|
|
var $value = $label.next('span');
|
|
|
|
if($label.text().includes('Montant emprunté :')) {
|
|
$value.text(result.capital + ' €');
|
|
}
|
|
else if($label.text().includes('Durée :')) {
|
|
$value.text(result.duree + ($('input[name="type_credit"]').val() === 'am' ? ' ans' : ' mois'));
|
|
}
|
|
else if($label.text().includes('Mensualité :')) {
|
|
$value.text(result.mensualite + ' €');
|
|
}
|
|
else if($label.text().includes('Coût Total :')) {
|
|
$value.text(result.cout_total + ' €');
|
|
}
|
|
else if($label.text().includes('Taux débiteur :')) {
|
|
$value.text(result.taux_nominal_annuel);
|
|
}
|
|
else if($label.text().includes('Taeg :')) {
|
|
$value.text(taux_debiteur + '%');
|
|
}
|
|
});
|
|
});
|
|
|
|
console.log('updateCreditDisplay - Affichage mis à jour');
|
|
}
|
|
|
|
// Fonction pour mettre à jour les limites et valeurs des champs selon le type de crédit
|
|
function updateFieldLimits(selectedType) {
|
|
const creditType = map_values[selectedType];
|
|
if (!creditType) {
|
|
console.warn('Type de crédit non reconnu:', selectedType);
|
|
return;
|
|
}
|
|
|
|
const $capitalField = jQuery('#IDbatiment_emprunt');
|
|
const $durationField = jQuery('#IDbatiment_duree');
|
|
let currentCapital = parseFloat($capitalField.val());
|
|
|
|
// Récupérer les limites depuis form_sliders pour les durées
|
|
const sliderConfig = form_sliders[creditType];
|
|
if (!sliderConfig) {
|
|
console.warn('Configuration slider non trouvée pour:', creditType);
|
|
return;
|
|
}
|
|
|
|
// Récupérer les limites spécifiques du crédit depuis cd_js.groups
|
|
const creditConfig = cd_js.groups[selectedType];
|
|
if (creditConfig && creditConfig.capital_max) {
|
|
// Ne modifier le montant que s'il dépasse la limite du crédit choisi
|
|
if (currentCapital > creditConfig.capital_max) {
|
|
currentCapital = creditConfig.capital_selected || creditConfig.capital_max;
|
|
$capitalField.val(currentCapital);
|
|
}
|
|
}
|
|
|
|
// Mettre à jour les attributs min/max du champ capital
|
|
$capitalField.attr('min', sliderConfig.capital_min);
|
|
$capitalField.attr('max', sliderConfig.capital_max);
|
|
$capitalField.attr('step', sliderConfig.capital_step || 100);
|
|
|
|
// Ajuster la valeur du capital si nécessaire selon les limites du slider
|
|
if (currentCapital > sliderConfig.capital_max) {
|
|
currentCapital = sliderConfig.capital_max;
|
|
$capitalField.val(currentCapital);
|
|
} else if (currentCapital < sliderConfig.capital_min) {
|
|
currentCapital = sliderConfig.capital_min;
|
|
$capitalField.val(currentCapital);
|
|
}
|
|
|
|
// Déterminer la durée maximale disponible pour ce montant
|
|
const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType);
|
|
let maxDurationForAmount = sliderConfig.durees[sliderConfig.durees.length - 1];
|
|
|
|
// Parcourir les durées disponibles dans l'ordre décroissant
|
|
for (let i = sliderConfig.durees.length - 1; i >= 0; i--) {
|
|
const duration = sliderConfig.durees[i];
|
|
// Vérifier si cette durée est valide pour le montant actuel
|
|
if (currentCapital >= sliderConfig.capital_min && currentCapital <= sliderConfig.capital_max) {
|
|
maxDurationForAmount = duration;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Convertir la durée maximale en années si nécessaire
|
|
const displayDuration = isYearlyDuration ? Math.floor(maxDurationForAmount / 12) : maxDurationForAmount;
|
|
const minDuration = isYearlyDuration ? Math.ceil(sliderConfig.duree_min / 12) : sliderConfig.duree_min;
|
|
const maxDuration = isYearlyDuration ? Math.floor(sliderConfig.duree_max / 12) : sliderConfig.duree_max;
|
|
|
|
// Mettre à jour les attributs min/max du champ durée
|
|
$durationField.attr('min', minDuration);
|
|
$durationField.attr('max', maxDuration);
|
|
|
|
// Définir la durée maximale disponible
|
|
$durationField.val(displayDuration);
|
|
|
|
// Mettre à jour l'unité dans l'input-group-text
|
|
jQuery('.input-group-text').text(isYearlyDuration ? 'Ans' : 'Mois');
|
|
|
|
// Mettre à jour l'affichage
|
|
calculateCredit();
|
|
|
|
// Mettre à jour le champ caché type_credit
|
|
jQuery('input[name="type_credit"]').val(creditType);
|
|
}
|
|
|
|
// Gestionnaire pour le changement de type de crédit
|
|
jQuery('#IDestateloantype').on('change', function() {
|
|
const creditType = jQuery(this).val();
|
|
if (creditType) {
|
|
updateFieldLimits(creditType);
|
|
calculateCredit();
|
|
}
|
|
});
|
|
|
|
// Fonction pour arrondir le capital à la valeur acceptable la plus proche
|
|
function snapCapitalValue(value, creditType) {
|
|
if (!creditType || !form_sliders[creditType]) {
|
|
return value;
|
|
}
|
|
|
|
const sliderConfig = form_sliders[creditType];
|
|
|
|
// Utiliser le step défini dans form_sliders
|
|
const step = sliderConfig.capital_step || 100;
|
|
|
|
// S'assurer que la valeur est dans les limites
|
|
value = Math.max(sliderConfig.capital_min, Math.min(value, sliderConfig.capital_max));
|
|
|
|
// Arrondir à la valeur la plus proche selon le step
|
|
return Math.round(value / step) * step;
|
|
}
|
|
|
|
// Fonction pour arrondir la durée à la valeur acceptable la plus proche
|
|
function snapDurationValue(value, creditType) {
|
|
if (!creditType || !form_sliders[creditType]) {
|
|
return value;
|
|
}
|
|
|
|
const sliderConfig = form_sliders[creditType];
|
|
const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType);
|
|
|
|
console.log('snapDurationValue - value:', value);
|
|
console.log('snapDurationValue - creditType:', creditType);
|
|
console.log('snapDurationValue - isYearlyDuration:', isYearlyDuration);
|
|
|
|
if (isYearlyDuration) {
|
|
// Pour les crédits en années, on vérifie juste les limites min/max
|
|
// Les limites sont déjà en années pour ces types de crédit
|
|
const minYears = sliderConfig.duree_min;
|
|
const maxYears = sliderConfig.duree_max;
|
|
|
|
console.log('snapDurationValue - minYears:', minYears);
|
|
console.log('snapDurationValue - maxYears:', maxYears);
|
|
|
|
if (value > maxYears) return maxYears;
|
|
if (value < minYears) return minYears;
|
|
return value;
|
|
} else {
|
|
// Pour les autres crédits, on cherche la durée disponible la plus proche
|
|
let closestDuration = sliderConfig.durees[0];
|
|
let minDiff = Math.abs(value - sliderConfig.durees[0]);
|
|
|
|
for (let i = 1; i < sliderConfig.durees.length; i++) {
|
|
const diff = Math.abs(value - sliderConfig.durees[i]);
|
|
if (diff < minDiff) {
|
|
minDiff = diff;
|
|
closestDuration = sliderConfig.durees[i];
|
|
}
|
|
}
|
|
return closestDuration;
|
|
}
|
|
}
|
|
|
|
// Fonction pour calculer la mensualité
|
|
function calc_mens(mnt, dur, taeg) {
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
|
|
// Pour le crédit pont, on ne calcule que les intérêts mensuels
|
|
if (creditType === 'cdp') {
|
|
const t100 = taeg / 100;
|
|
// Calcul des intérêts mensuels uniquement : (capital * taux_annuel) / 12
|
|
const mens = (mnt * t100) / 12;
|
|
return Math.floor(mens * 100) / 100;
|
|
}
|
|
|
|
// Pour les autres types de crédit, calcul normal
|
|
const t100 = taeg / 100;
|
|
const t101 = 1 + t100;
|
|
const d12 = 1 / 12;
|
|
const dur12 = dur / 12;
|
|
const buf1 = Math.pow(t101, d12);
|
|
const buf2 = Math.pow(1 / t101, dur12);
|
|
const mens = (mnt * (buf1 - 1)) / (1 - buf2);
|
|
|
|
return Math.floor(mens * 100) / 100;
|
|
}
|
|
|
|
// Notre propre fonction de calcul qui utilise les fonctions de base de cd_main.js
|
|
function calculateCredit() {
|
|
const capital = parseFloat(jQuery('#IDbatiment_emprunt').val());
|
|
const duration = parseInt(jQuery('#IDbatiment_duree').val());
|
|
const selectedType = jQuery('#IDestateloantype').val();
|
|
const creditType = map_values[selectedType];
|
|
|
|
console.log('=== Début calcul crédit ===');
|
|
console.log('Type sélectionné:', selectedType);
|
|
console.log('Type de crédit mappé:', creditType);
|
|
console.log('Capital:', capital);
|
|
console.log('Durée:', duration);
|
|
|
|
if (isNaN(capital) || isNaN(duration) || !creditType) {
|
|
console.warn('Valeurs invalides pour le calcul:', {
|
|
capital: isNaN(capital) ? 'invalide' : capital,
|
|
duration: isNaN(duration) ? 'invalide' : duration,
|
|
selectedType,
|
|
creditType: !creditType ? 'non mappé' : creditType
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Convertir la durée en mois si nécessaire pour les calculs
|
|
const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType);
|
|
const durationForCalculation = isYearlyDuration ? duration * 12 : duration;
|
|
|
|
console.log('Durée pour calcul:', durationForCalculation, isYearlyDuration ? '(en années)' : '(en mois)');
|
|
|
|
let results;
|
|
// Appeler la fonction de calcul appropriée
|
|
switch(creditType) {
|
|
case 'pat':
|
|
results = calculate_pat(capital, duration);
|
|
break;
|
|
case 'am':
|
|
results = calculate_am(capital, duration);
|
|
break;
|
|
case 'ph':
|
|
results = calculate_ph(capital, duration);
|
|
break;
|
|
case 'amr':
|
|
case 'cdp':
|
|
case 'cied':
|
|
results = calculate_mono_rate_bt_10_30(creditType, capital, duration);
|
|
break;
|
|
case 'fin_neuve':
|
|
results = calculate_fin_neuve(capital, duration);
|
|
break;
|
|
case 'fin_occ_m3a':
|
|
results = calculate_pao_m_3(capital, duration);
|
|
break;
|
|
case 'fin_occ_p3a':
|
|
results = calculate_pao_p_3(capital, duration);
|
|
break;
|
|
case 'mobil_carav':
|
|
results = calculate_mobilhome(capital, duration);
|
|
break;
|
|
case 'regroup_cred':
|
|
results = calculate_regroupement_de_credit(capital, duration);
|
|
break;
|
|
case 'frais_notaire':
|
|
results = calculate_frais_notaire(capital, duration);
|
|
break;
|
|
case 'but_immo':
|
|
results = calculate_but_immo(capital, duration);
|
|
break;
|
|
default:
|
|
console.warn('Type de crédit non reconnu:', creditType);
|
|
results = calculate_pat(capital, duration);
|
|
}
|
|
|
|
if (!results) {
|
|
console.warn('Pas de résultats retournés par la fonction de calcul');
|
|
return;
|
|
}
|
|
|
|
console.log('Résultats bruts:', results);
|
|
|
|
// Extraire les valeurs des résultats
|
|
const [min_duration, max_duration, selected_duration, duree_in_range, taux_nominal] = results;
|
|
|
|
// Convertir le taux en nombre si c'est une chaîne
|
|
const taux = parseFloat(String(taux_nominal).replace('%', ''));
|
|
|
|
if (isNaN(taux)) {
|
|
console.error('Taux nominal invalide après conversion:', {
|
|
original: taux_nominal,
|
|
converti: taux
|
|
});
|
|
return;
|
|
}
|
|
|
|
console.log('Taux nominal (débiteur):', taux + '%');
|
|
console.log('Durée sélectionnée:', selected_duration, isYearlyDuration ? 'mois (convertie)' : 'mois');
|
|
|
|
// Pour les crédits en années, la durée retournée est déjà en mois
|
|
const durationInMonths = isYearlyDuration ? durationForCalculation : selected_duration;
|
|
|
|
// Calculer la mensualité avec notre fonction locale
|
|
const mensualite = calc_mens(capital, durationInMonths, taux);
|
|
|
|
if (isNaN(mensualite)) {
|
|
console.error('Erreur dans le calcul de la mensualité:', {
|
|
capital,
|
|
durationInMonths,
|
|
taux
|
|
});
|
|
return;
|
|
}
|
|
|
|
const cout_total = (mensualite * durationInMonths).toFixed(2);
|
|
|
|
console.log('Mensualité calculée:', mensualite.toFixed(2) + '€');
|
|
console.log('Coût total calculé:', cout_total + '€');
|
|
|
|
// Créer l'objet result pour updateCreditDisplay
|
|
const displayResult = {
|
|
capital: capital,
|
|
duree: duration,
|
|
mensualite: mensualite.toFixed(2),
|
|
cout_total: cout_total,
|
|
taux_nominal_annuel: taux.toFixed(2) + ' %',
|
|
taux_debiteur: taux.toFixed(2) + ' %'
|
|
};
|
|
|
|
console.log('Résultat final pour affichage:', displayResult);
|
|
console.log('--- Fin calcul crédit ---');
|
|
|
|
// Mettre à jour l'affichage
|
|
updateCreditDisplay(displayResult);
|
|
|
|
// Mettre à jour le champ caché type_credit
|
|
jQuery('input[name="type_credit"]').val(creditType);
|
|
}
|
|
|
|
if(isCreditCalculationEnabled) {
|
|
// Remplacer tous les appels à calculate_mensualite par calculateCredit
|
|
jQuery('#IDbatiment_emprunt')
|
|
.on('input', function() {
|
|
const $this = jQuery(this);
|
|
clearTimeout(capitalTimeout);
|
|
|
|
if ($this.val() !== '') {
|
|
capitalTimeout = setTimeout(() => {
|
|
let capital = parseFloat($this.val());
|
|
if (!isNaN(capital)) {
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
const snappedValue = snapCapitalValue(capital, creditType);
|
|
if (snappedValue !== capital) {
|
|
$this.val(snappedValue);
|
|
}
|
|
calculateCredit();
|
|
}
|
|
}, 500); // Délai un peu plus long pour laisser le temps de taper
|
|
}
|
|
})
|
|
.on('change', function() {
|
|
// Validation finale quand on quitte le champ (onblur)
|
|
const $this = jQuery(this);
|
|
if ($this.val() !== '') {
|
|
let capital = parseFloat($this.val());
|
|
if (!isNaN(capital)) {
|
|
const selectedType = jQuery('#IDestateloantype').val();
|
|
const creditConfig = cd_js.groups[selectedType];
|
|
|
|
// Vérifier les limites du crédit
|
|
if (creditConfig && creditConfig.capital_max && capital > creditConfig.capital_max) {
|
|
capital = creditConfig.capital_selected || creditConfig.capital_max;
|
|
$this.val(capital);
|
|
}
|
|
|
|
// Snap à la valeur la plus proche et recalcul
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
const snappedValue = snapCapitalValue(capital, creditType);
|
|
if (snappedValue !== capital) {
|
|
$this.val(snappedValue);
|
|
}
|
|
calculateCredit();
|
|
}
|
|
}
|
|
});
|
|
|
|
jQuery('#IDbatiment_duree')
|
|
.on('input', function() {
|
|
const $this = jQuery(this);
|
|
clearTimeout(durationTimeout);
|
|
durationTimeout = setTimeout(() => {
|
|
let duration = parseInt($this.val());
|
|
if (!isNaN(duration)) {
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
console.log('Input duration:', duration);
|
|
console.log('Credit type:', creditType);
|
|
console.log('Is yearly:', LOAN_TYPES_IN_YEARS.includes(creditType));
|
|
|
|
// Ne pas snapper pendant la saisie pour les crédits en années
|
|
if (LOAN_TYPES_IN_YEARS.includes(creditType)) {
|
|
calculateCredit();
|
|
} else {
|
|
const snappedValue = snapDurationValue(duration, creditType);
|
|
if (snappedValue !== duration) {
|
|
$this.val(snappedValue);
|
|
}
|
|
calculateCredit();
|
|
}
|
|
}
|
|
}, 300);
|
|
})
|
|
.on('change', function() {
|
|
let duration = parseInt($(this).val());
|
|
if (!isNaN(duration)) {
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
console.log('onchange - creditType:', creditType);
|
|
console.log('onchange - LOAN_TYPES_IN_YEARS:', LOAN_TYPES_IN_YEARS);
|
|
console.log('onchange - includes?', LOAN_TYPES_IN_YEARS.includes(creditType));
|
|
|
|
if (LOAN_TYPES_IN_YEARS.includes(creditType)) {
|
|
console.log('change', duration);
|
|
const snappedValue = snapDurationValue(duration, creditType);
|
|
console.log('snappedValue', snappedValue);
|
|
if (snappedValue !== duration) {
|
|
$(this).val(snappedValue);
|
|
}
|
|
} else {
|
|
// Pour les autres crédits, comportement normal
|
|
const snappedValue = snapDurationValue(duration, creditType);
|
|
if (snappedValue !== duration) {
|
|
$(this).val(snappedValue);
|
|
}
|
|
}
|
|
calculateCredit();
|
|
}
|
|
});
|
|
|
|
// Calcul initial au chargement
|
|
/* $(document).ready(function() {
|
|
const creditType = $('input[name="type_credit"]').val();
|
|
if (creditType) {
|
|
updateFieldLimits(creditType);
|
|
calculateCredit();
|
|
}
|
|
}); */
|
|
|
|
// Gestionnaire pour la soumission du formulaire - s'exécute AVANT la validation HTML5
|
|
jQuery('.form-submit').on('submit', function(e) {
|
|
// Retirer l'attribut required de tous les champs dans les sections cachées
|
|
// AVANT la validation HTML5 pour éviter l'erreur "not focusable"
|
|
removeRequiredFromHiddenFields();
|
|
// Recalculer une dernière fois avant l'envoi
|
|
calculateCredit();
|
|
// Laisser le formulaire se soumettre normalement après avoir retiré les required des champs cachés
|
|
});
|
|
}
|
|
|
|
function findRate(type) {
|
|
console.log('findRate - Type recherché:', type);
|
|
let rate;
|
|
|
|
switch(type) {
|
|
case 'amr':
|
|
rate = cd_js.groups.achat_maison_de_rapport.de_10_a_30_ans;
|
|
break;
|
|
case 'cdp':
|
|
rate = cd_js.groups.credit_pont.de_10_a_30_ans;
|
|
break;
|
|
case 'cied':
|
|
rate = cd_js.groups.independants_et_entreprises_en_difficultes.de_10_a_30_ans;
|
|
break;
|
|
default:
|
|
console.warn('Type de crédit non reconnu pour le taux mono:', type);
|
|
rate = null;
|
|
}
|
|
|
|
console.log('findRate - Taux trouvé:', rate);
|
|
return rate;
|
|
}
|
|
|
|
function calculate_mono_rate_bt_10_30(type, selected_capital, selected_duration) {
|
|
const annual_rate = findRate(type);
|
|
if (!annual_rate) {
|
|
console.error('Taux non trouvé pour le type:', type);
|
|
return null;
|
|
}
|
|
|
|
const min_duration = 10;
|
|
const max_duration = 30;
|
|
let duree_in_range = true;
|
|
const add_message = '';
|
|
|
|
if (min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration) {
|
|
// La durée est dans la plage
|
|
} else {
|
|
duree_in_range = false;
|
|
selected_duration = max_duration;
|
|
}
|
|
|
|
// Convertir la durée en mois pour le calcul
|
|
selected_duration = selected_duration * 12;
|
|
|
|
return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message];
|
|
}
|
|
|
|
});
|
|
|
|
// --- Changement dynamique du label Numéro de registre national selon la nationalité (emprunteur et co-emprunteur) ---
|
|
jQuery(function($) {
|
|
function setupNationalRegLabel(selectId, labelId) {
|
|
var defaultLabel = 'Numéro de registre national';
|
|
var luxLabel = 'Numéro de sécurité sociale';
|
|
var select = $('#' + selectId);
|
|
var labelSelector = 'label[for="' + labelId + '"]';
|
|
function updateLabel() {
|
|
var val = select.val();
|
|
if (val === 'LU') {
|
|
$(labelSelector).text(luxLabel);
|
|
} else {
|
|
$(labelSelector).text(defaultLabel);
|
|
}
|
|
}
|
|
select.on('change', updateLabel);
|
|
// Initialisation au chargement
|
|
updateLabel();
|
|
}
|
|
setupNationalRegLabel('IDnationality', 'IDnationalregistrationnumber');
|
|
setupNationalRegLabel('IDconationality', 'IDconationalregistrationnumber');
|
|
});
|
|
|
|
// --- Initialisation des Inputmasks pour les champs de date ---
|
|
jQuery(function($) {
|
|
// Initialisation des champs de date avec inputmask
|
|
jQuery('input[data-inputmask]').inputmask();
|
|
|
|
// Configuration spécifique pour tous les champs de date
|
|
jQuery('.input-date').inputmask({
|
|
mask: '99/99/9999',
|
|
placeholder: 'JJ/MM/AAAA',
|
|
clearMaskOnLostFocus: false,
|
|
showMaskOnHover: true,
|
|
showMaskOnFocus: true
|
|
});
|
|
});
|
|
|
|
if(jQuery('.etat-civil-pat').length > 0) {
|
|
|
|
// Variable pour tracker si le co-emprunteur a été forcé par l'état civil
|
|
let coBorrowerForcedByCivilStatus = false;
|
|
|
|
jQuery('#IDcivilstatus').on('change', function() {
|
|
let etatCivil = jQuery('#IDcivilstatus').val(),
|
|
switchValue = 4,
|
|
hascoborrower_input = jQuery('[name="hascoborrower"]'),
|
|
parent = hascoborrower_input.parents('fieldset'),
|
|
info = cd_js.info_pat;
|
|
|
|
if(etatCivil == switchValue) {
|
|
// État civil = 4 : forcer l'activation du co-emprunteur
|
|
hascoborrower_input[1].checked = true;
|
|
coBorrowerForcedByCivilStatus = true;
|
|
parent.append('<div class="alert alert-warning">' + info + '</div>');
|
|
} else {
|
|
// État civil ≠ 4 : ne désactiver que si c'était précédemment forcé
|
|
if(coBorrowerForcedByCivilStatus) {
|
|
hascoborrower_input[0].checked = true;
|
|
coBorrowerForcedByCivilStatus = false;
|
|
parent.find('.alert').remove();
|
|
}
|
|
// Si ce n'était pas forcé, on laisse le choix de l'utilisateur
|
|
}
|
|
|
|
// Déclencher l'événement change sur le bouton radio pour activer displayCoBorrower
|
|
// Mais éviter les déclenchements multiples si cojob = 5
|
|
var cojobValue = jQuery('select[name="cojob"]').val();
|
|
if (cojobValue !== '5') {
|
|
jQuery('input[name="hascoborrower"]:checked').trigger('change');
|
|
} else {
|
|
// Si cojob = 5, appeler directement sans trigger pour éviter la cascade
|
|
displayCoBorrower();
|
|
}
|
|
});
|
|
|
|
// Réinitialiser le flag quand l'utilisateur change manuellement le co-emprunteur
|
|
jQuery('[name="hascoborrower"]').on('change', function() {
|
|
if(!jQuery('#IDcivilstatus').val() == 4) {
|
|
coBorrowerForcedByCivilStatus = false;
|
|
}
|
|
});
|
|
|
|
} |