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;
}
CSSLa configuration de l’interaction des boutons
Ensuite, pour pouvoir gérer les différentes actions que l’utilisateur peut effectuer sur les boutons et les interactions des boutons coulissants entre eux, j’ai besoin de quelques variables et de fonctions.
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+' € ');
}
JavaScriptGestion de la dépendance entre les boutons coulissants
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);
}
});
}
});
});
JavaScript
Si vous n’y arrivez pas, un petit commentaire et j’essaierais de répondre.
Laisser un commentaire
Vous devez vous connecter pour publier un commentaire.