Association 1901 dans le domaine de l’écologie
Projet :
Application de calcul de prix de stand exposant
Description
L’association Primevère, à l’initiative d’un des plus importants salon annuel de l’écologie à Lyon, souhaitait disposer d’une plateforme en ligne permettant à chaque exposant d’évaluer le prix de son futur stand, en fonction de critères multiples.
Le dispositif devait être facile d’utilisation, avec une séquence iterative de saisie/résultat, permettant à l’exposant d’ajuster ses options en fonction de l’évolution du prix.
Un récapitulatif des options sélectionnées et du prix total devait être téléchargeable au format pdf.
Solutions proposées
- Le développement d’une Web App, application développée sur mesure via une approche prioritairement front-end afin d’optimiser l’interactivité.
- Conception de composants JavaScript modulaires, classes de widgets interconnectés, wrappers destinés à enrichir les comportements natifs des éléments de formulaire.
Technologies
html
css
javascript (Vanilla)
php
dompdf
Mustache
Extrait code composants
export class SelectWidget{
constructor(parameters){
this.value = null;
this.isActive = true;
this.isRequired = true;
this.callbacks = {
'dependance' : null,
'display' : null
};
this.name = parameters.name;
this.containerSelector = parameters.container;
this.labelSelector = parameters.label;
this.widgetSelector = parameters.widget;
this.unit = parameters.unit;
this.changeHandler = this.changeHandler.bind(this);
this.addCallback = this.addCallback.bind(this);
this.setValueByLibelle = this.setValueByLibelle.bind(this);
}
load() {
this.container = document.querySelector(this.containerSelector);
this.label = document.querySelector(this.labelSelector);
this.widget = document.querySelector(this.widgetSelector);
this.setValueByIndex(0);
this.widget.addEventListener('change', this.changeHandler, false);
}
changeHandler() {
this.value = (this.widget.value == 'null')? null : this.widget.value;
if(this.callbacks.length>0 ){
this.callbacks.map(function(callback){
callback(this);
}.bind(this));
}
if(this.callbacks.dependance != null)
this.callbacks.dependance(this);
if(this.callbacks.display != null)
this.callbacks.display(this);
}
getName(){
return this.name;
}
getValue() {
this.value = (this.widget.value == 'null')? null : this.widget.value;
return this.value;
}
getLibelle() {
var libelle = '';
Array.from(this.widget.options).map(function(option){
if(option.selected == true){
libelle = option.text;
}
}.bind(this));
return libelle;
}
isLibelleSelected(libelle){
var selected = false
Array.from(this.widget.options).map(function(option){
if(option.selected == true){
if(option.text == libelle){
selected = true;
}
}
}.bind(this));
return selected;
}
setValueByLibelle(libelle) {
Array.from(this.widget.options).map(function(option){
if(option.text == libelle){
option.selected='selected';
this.value = option.value;
}
}.bind(this));
}
setValueByIndex(index){
this.widget.options[index].selected='selected';
this.value = this.widget.options[index].value;
}
setStyles(element, styles) {
for(var style in styles){
element.style[style] = styles[style];
}
}
setRequired(required){
this.isRequired = required;
}
show(){
this.isActive = true;
this.setRequired(true);
this.setStyles(this.container, {display: 'block'});
}
hide(){
this.isActive = false;
this.setRequired(false);
this.setValueByIndex(0);
this.setStyles(this.container, {display: 'none'});
}
addCallback(callbackname, callback) {
this.callbacks[callbackname] = callback;
}
}
export class WidgetsManager {
constructor() {
this.allWidgetsList = [];
this.points = 0;
this.selecteds = [];
this.constante_calcul = 0;
this.droits_entree_base = 0;
this.callbacks = {
'display': null
};
this.load = this.load.bind(this);
this.getPoints = this.getPoints.bind(this);
this.requiredWidgetsList = [];
this.unrequiredWidgetsList = [];
this.pointsWidgetsList = [];
this.eurosWidgetsList = [];
}
setConstantes(constantes) {
this.constante_calcul = constantes.constante_calcul;
this.droits_entree_base = constantes.droits_entree_base;
}
load() {
this.allWidgetsList.map(function (widget) {
widget.addCallback('display', this.callbacks.display);
}.bind(this));
}
addWidgets(list) {
list.map(function(item){
if(item[1] == 'required'){
this.requiredWidgetsList.push(item[0]);
}
if(item[1] == 'unrequired'){
this.unrequiredWidgetsList.push(item[0]);
}
if(item[2] == 'point'){
this.pointsWidgetsList.push(item[0]);
}
if(item[2] == 'euro'){
this.eurosWidgetsList.push(item[0]);
}
this.allWidgetsList.push(item[0]);
}.bind(this));
}
getPoints() {
var points = this.getSum(this.pointsWidgetsList);
return points;
}
getEuros(){
var euros = this.getSum(this.eurosWidgetsList);
return euros;
}
getSum(widgetlist){
var sum = 0;
widgetlist.map(function(widget){
if(widget.isActive == true){
var value = (widget.getValue() == null) ? 0 : widget.getValue();
if (value.toString().indexOf('/') != -1) {
var value = parseFloat(value.toString().split(' ')[1]);
sum = sum / value;
}
else if (value.toString().indexOf('x') != -1) {
var value = parseFloat(value.toString().split(' ')[1]);
sum = sum * value;
}
else {
sum += parseFloat(value);
}
}
});
return sum;
}
getUnselectedRequiredWidgets(){
var widgetsList = [];
this.requiredWidgetsList.map(function(widget){
if(widget.isActive == true && widget.getValue() == null){
widgetsList.push(widget);
}
});
return widgetsList;
}
getIndice(coefficient, points) {
var indice = null;
if (points != null && coefficient != null) {
indice = parseFloat(points) * parseFloat(coefficient);
}
return indice;
}
getSurface(profondeur, longueur) {
var surface = null;
if (profondeur != null && longueur != null) {
surface = parseFloat(profondeur) * parseFloat(longueur);
}
return surface;
}
getPrixStand(surface, indice, profondeur, angles) {
if(this.getUnselectedRequiredWidgets().length>0) return 0;
var prixStand = 0;
if (surface != null
&& indice != null
&& angles != null
&& profondeur != null) {
prixStand = (surface * indice) + (indice * this.constante_calcul * profondeur * angles);
}
return prixStand;
}
getPrixElectricite_old(tarification, puissance) {
if (tarification == null || puissance == null) return 0;
var base = parseFloat(tarification);
var watts = parseFloat(puissance);
var pas = watts / 100;
var prix = 0;
if (base == 47.5) {
prix = base + (pas * 21.5);
}
if (base == 218) {
prix = base + (pas * 7.5);
}
return prix;
}
getPrixElectricite(tarification, puissance, parametres_electricite) {
if (tarification.getValue() == null || puissance.getValue() == null) return 0;
var pas = parseFloat(parametres_electricite.puissance.pas);
var base = parseFloat(tarification.getValue());
var puissance = parseFloat(puissance.getValue());
var multiplicateur;
parametres_electricite.tarifs.map(function(tarif){
if (parseFloat(tarif.base) == base){
multiplicateur = parseFloat(tarif.multiplicateur);
}
});
var segments = puissance / pas;
var prix = 0;
prix = base + ((segments - 1) * multiplicateur);
return prix;
}
getValueDisplay(value, unit){
var valueDisplay = '';
if (value.toString().indexOf('/') != -1) {
valueDisplay = 'Total ' + unit + 's / ' + parseFloat(value.toString().split(' ')[1]);
}
else if (value.toString().indexOf('x') != -1) {
valueDisplay = 'Total '+ unit + 's x ' + parseFloat(value.toString().split(' ')[1]);
}
else{
if(unit == 'euro'){
valueDisplay = this.formatEuros(value);
}
else if(unit == 'point'){
valueDisplay = value + ' pt(s)';
}
}
return valueDisplay;
}
formatEuros(value) {
var formatter = new Intl.NumberFormat('fr-FR', {
style: 'currency',
currency: 'EUR'
});
return formatter.format(value);
}
toggleWidgetsContainers() {
var containers = Array.from(document.querySelectorAll('.widgets-container-list'));
for (var i = 0; i < containers.length; i++) {
var container = containers[i];
var subcontainers = Array.from(container.querySelectorAll('.widget-container'));
var undisplays = 0;
for (var j = 0; j < subcontainers.length; j++) {
var subcontainer = subcontainers[j];
var display = window.getComputedStyle(subcontainer, null).getPropertyValue('display');
if (display == 'none') undisplays++;
}
if (undisplays == subcontainers.length) {
container.style.display = 'none';
}
else {
container.style.display = 'block';
}
}
}
showModal(body, title) {
var modal = $('.modal');
modal.find('.modal-title').html(title);
modal.find('.modal-body').html(body);
modal.modal('toggle');
}
addCallback(callbackname, callback) {
this.callbacks[callbackname] = callback;
}
}
Charte graphique


