Ce blog est crée à cause du mal que j’ai eu autant de mal en anglais qu’en français à trouver les ressources me permettant de mettre en place des boutons coulissants qui interagissent entre eux et qui soient un peu customisés. Comme un exemple vaut souvent mieux que de longs discours, je voulais faire le simulateur de crédit disponible sur http://www.meilleur-credit.org/.
Pour cela, il fallait que le changement de montant ou de durée puisse influer sur la mensualité. J’ai eu recours pour me simplifier la vie à jQuery-UI (comme User Interface) qui permet d’avoir des boutons coulissants (appelés Sliders dans la langue de Shakespeare ou Seek bars pour l’interface android).
La mise en place graphique
La mise en place est assez simple pour avoir une apparence standard mais elle se complique un peu si on veut une apparence plus personnalisée. J’ai essayé de dire à mon graphiste que je m’en foutais mais vous savez, vous développeurs, comment ils sont intransigeants sur certains points de leurs conceptions. L’idée est de se servir des margins et des widths pour que le bouton coulissant ne coulisse pas trop loin.
.slider { width : 180px; height: 40px; } .ui-slider-horizontal{ background: url('../images/barre.png') no-repeat; border: none; width : 195px; height: 39px; float: left; } .ui-slider-horizontal .ui-state-default{ background: url('../images/bouton_barre.png') no-repeat; border: none; height: 39px; width : 36px; margin-left : -18px; z-index: 0; } .ui-slider-handle .ui-slider { background: url('../images/bouton_barre.png') no-repeat; height: 39px; width : 36px; cursor: pointer; margin-left : -18px; z-index: 0; }
La configuration de l’interaction des boutons
var montant = 0; var duree = 0; var mensualite = 0; var index = 0; /** * Retourne un nouveau montant * @Duree Integer * @Mensualite Integer * @return Integer */ /** * Retourne un nouveau montant * @Duree Integer * @Mensualite Integer * @return Integer */ function changerMontant (Duree,Mensualite,Pas){ return Math.round(Duree*Mensualite/Pas)*Pas; } function changerDuree (Montant,Mensualite){ return Math.round(Montant/Mensualite); } function changerMensualite (Montant,Duree){ var Mensualite = Montant/Duree; return Math.round(Mensualite); } function triTableau(ordre,premier){ var achanger = ordre.pop(); //Enlève un élément à la fin du tableau et le retourne if (achanger == premier){ //Si le dernier élément était montant achanger = ordre.pop(); //On récupère l'avant dernier ordre.unshift(premier); //On met le montant comme premier élément ordre.push(achanger); //On remet l'avant dernier en dernier } else if (premier == ordre[0]){ //Sinon, si montant était le premier élément du tableau ordre.push(achanger); //On remet l'avant dernier en dernier } else { //Sinon, l'élément est le second second = ordre.shift(); //On récupère celui qui va passer second ordre.push(second); //On le met en second ordre.push(achanger); //Puis le dernier } return ordre, achanger; } /** * Mets à jour les données quand la valeur d'un slider change */ function miseajourdonnees(){ mensualiteInt = Math.round((montant*taux/12)/(1-(Math.pow((1+taux),(-(duree*multiduree/12)))))*100)/100; totalCredit= Math.round(mensualiteInt*duree*multiduree*100)/100; interets = Math.round((totalCredit-montant)*100)/100; //On change la valeur du montant car il a été arrondi $("#montant").slider({value : montant}); //Celle de la durée $("#duree").slider({value : duree}); //En fonction du montant et de la durée, on corrige la mensualité minimum ou maximum $("#mensualite").slider({ value : Math.sqrt(mensualiteInt), min : Math.sqrt(Math.round((montant*taux/12)/(1-(Math.pow((1+taux),(-(parseInt(donneeType[index]['DureeMax'])*multiduree/12)))))*100)/100), max : Math.sqrt(parseInt(donneeType[index]['MontantMax'])/(parseInt(donneeType[index]['DureeMin']))/multiduree) }); //On affiche les données modifiées à droite de la barre avec le formatage adéquat $("#valeur-montant").html(formatage(montant,' €')); $("#valeur-duree").html(formatage(duree, ' '+donneeType[index]['UniteDuree'])); $("#valeur-mensualite").html(formatage(mensualiteInt, ' €')); $("#valeur-taux").html((Math.round(taux*10000)/100)+' % '); $("#total-interet").html(interets+' € '); $("#total-credit").html(totalCredit+' € '); }
Ensuite, il faut traiter les interactions. L’idée générale est de changer le bouton coulissant dans les limites qui me sont permises par la logique des crédits. De plus, je devais gérer des crédits qui avaient des échelles de durée différentes (mois dans la plupart des cas mais années dans le cas d’un crédit immobilier). Je récupère les données directement écrites dans le html en JSON. Voici le code commenté :
$(document).ready(function() { //Ecoute les changements sur le select $('.titre-picto').bind("click", function (e){ //On récupère l'index du crédit pour savoir à quel type on a affaire (immobilier, consommation...) index = parseInt(this.getAttribute('attr')); $.ajax({ type : "POST", url : "../helpers/affiche-sliders.php", data : "type="+index, success : function(retour){ $('#contenu-simul').html(retour); $('#valider').show(); var ordre = new Array("#montant", "#duree", "#mensualite"); //Sert à savoir quel slide va faire variable d'ajustement if (donneeType[index]['UniteDuree']=="années"){ multiduree=12; } montant = parseInt(donneeType[index]['MontantMin']); //On récupère les données pour l'affichage suivant le type de crédit qui a été choisi duree = parseInt(donneeType[index]['DureeMin']); mensualite = montant/duree; var PasMontant = parseInt(donneeType[index]['Pas']); var mensualiteMin = montant/parseInt(donneeType[index]['MontantMax'])/multiduree; var mensualiteMax = parseInt(donneeType[index]['MontantMax'])/(parseInt(donneeType[index]['DureeMin']))/multiduree; var achanger; //Va servir à savoir quelle valeur peut être modifiée var premier; //Sert à savoir quel doit être le premier élément du tableau //Gère le slider montant $("#valeur-montant").html(formatage(montant,' €')); //Formate et affecte la valeur par défaut à l'affichage $("#montant").slider({ disabled: false, value : Math.sqrt(parseInt(donneeType[index]['MontantMin'])), //Définit la valeur par défaut min : Math.sqrt(parseInt(donneeType[index]['MontantMin'])), //Minimum max : Math.sqrt(parseInt(donneeType[index]['MontantMax'])), //Maximum step : 5, //Pas entre deux valeurs du slider slide : function (e, ui){ //Fonction déclenchée quand l'utilisateur fait glisser le bouton //On arrondi le montant au pas qu'on veut qu'il prenne montant = Math.round(Math.pow(ui.value,2)/PasMontant)*PasMontant; premier = "#montant"; //Sert à savoir quel doit être le premier élément du tableau ordre, achanger = triTableau(ordre, premier); //Si nous devons changer la mensualité if (achanger == "#mensualite"){ mensualite = changerMensualite(montant, duree*multiduree); if (mensualite < mensualiteMin) mensualite = mensualiteMin; if (mensualite > mensualiteMax) mensualite = mensualiteMax; duree = changerDuree(montant, mensualite*multiduree); //Sinon la durée } else if (achanger == "#duree") { duree = changerDuree(montant, mensualite*multiduree); if (duree < parseInt(donneeType[index]['DureeMin'])) duree = parseInt(donneeType[index]['DureeMin']); if (duree > parseInt(donneeType[index]['DureeMax'])) duree = parseInt(donneeType[index]['DureeMax']); mensualite = changerMensualite(montant, duree*multiduree); } miseajourdonnees(); } }); //Gère le slider durée (le fonctionnement est le même que pour le //montant mais on considère qu'on influe pas sur le montant choisi, //seulement sur la mensualité $("#valeur-duree").html(formatage(parseInt(donneeType[index]['DureeMin']), ' '+donneeType[index]['UniteDuree'])); $("#duree").slider({ disabled: false, value : duree, min : duree, max : parseInt(donneeType[index]['DureeMax']), step : 1, slide : function (e, ui){ duree = ui.value; premier = "#duree"; //Pour que durée soit changé après mensualité si le montant change ordre, achanger = triTableau(ordre, premier); mensualite = changerMensualite(montant, duree*multiduree); if (mensualite < mensualiteMin) mensualite = mensualiteMin; if (mensualite > mensualiteMax) mensualite = mensualiteMax; miseajourdonnees(); } }); //Gère le slider mensualité (fonctionne comme durée) $("#valeur-mensualite").html(formatage(100, ' €')); $("#mensualite").slider({ disabled: false, value : Math.sqrt(mensualite), min : Math.sqrt(mensualiteMin), max : Math.sqrt(mensualiteMax), step : 1, slide : function (e, ui){ mensualite = Math.round(Math.pow(ui.value,2)); premier = "#mensualite"; ordre, achanger = triTableau(ordre, premier); duree = changerDuree(montant, mensualite*multiduree); if (duree < parseInt(donneeType[index]['DureeMin'])) duree = parseInt(donneeType[index]['DureeMin']); if (duree > parseInt(donneeType[index]['DureeMax'])) duree = parseInt(donneeType[index]['DureeMax']); miseajourdonnees(); } }); $("#valeur-taux").html('5 % '); $("#taux").slider({ disabled: false, value : 5, min : 3, max : 20, step : 0.25, slide : function (e, ui){ taux = (ui.value/100); miseajourdonnees(); } }); } }); }); $('#affichbanque').bind("click", function(){ if (index!=0){ _gaq.push(['_trackEvent', 'Affichage des banques', donneeType[index]['Nom'], montant, duree]); $.ajax({ type : "POST", url : "../helpers/banque-simul.php", data : "type="+index+"&montant="+montant+"&duree="+duree, success : function(retour){ $('#affiche-detail').html(retour); } }); } }); $('#planremb').bind("click", function(){ if (index!=0){ _gaq.push(['_trackEvent', 'Plan de remboursement', donneeType[index]['Nom'], montant, duree]); $.ajax({ type : "POST", url : "../helpers/plan-remboursement.php", data : "&montant="+montant+"&duree="+(duree*multiduree)+"&taux="+taux, success : function(retour){ $('#affiche-detail').html(retour); } }); } }); });
Laisser un commentaire
Vous devez vous connecter pour publier un commentaire.