Created
March 17, 2014 13:43
-
-
Save zouloux/9599393 to your computer and use it in GitHub Desktop.
RadioComponent Solid
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
// Un gestionnaire de composants radio | |
var RadioComponent = function (pDOMGroupSelector, pSelectedHandler) | |
{ | |
// L'élément DOM associé | |
var $element; | |
// La nouvelle DOM | |
var _newDOM = '<div class="radioComponent">'; | |
_newDOM += ' <span class="radioBack"></span>'; | |
_newDOM += ' <span class="radioFront"></span>'; | |
_newDOM += '</div>'; | |
// L'index séléctionné | |
var _selectedIndex = -1; | |
// Le handler lorsqu'un radio est séléctionné | |
var _selectedHandler; | |
// Créer le contexte du composant | |
var that = { | |
// Le constructeur | |
construct: function () | |
{ | |
// Remplacer la DOM | |
that.replaceDOM(); | |
// Définir l'event à écouter selon la plateforme | |
_eventToListen = ("Modernizr" in window && Modernizr.touch ? "touchstart" : "click"); | |
// Ecouter les clics sur le bouton pour ouvrir le menu | |
$element.each(function (i, el) | |
{ | |
// Si le composant est dans un container input | |
var parentContainer = $(this).parents(".inputContainer"); | |
// Si on a au moins un parent inputContainer | |
if (parentContainer.length == 1) | |
{ | |
// Ecouter les clic/tap sur ce dernier | |
parentContainer.eq(0).css({ | |
cursor: "pointer" | |
}).bind(_eventToListen, that.clickHandler); | |
} | |
else | |
{ | |
// Ecouter les clic/tap directement sur le composant | |
$(this).bind(_eventToListen, that.clickHandler); | |
} | |
}); | |
// Enregistrer le handler | |
_selectedHandler = pSelectedHandler; | |
// Récupérer l'index du séléctionné s'il y a | |
var currentSelected = $element.filter(".selected"); | |
// Si on a déjà un élément radio séléctionné | |
if (currentSelected.length == 1) | |
{ | |
// Enregistrer l'index de l'élément séléctionné | |
_selectedIndex = $element.index(currentSelected); | |
} | |
else | |
{ | |
// Tout déséléctionner | |
$element.removeClass("selected"); | |
} | |
}, | |
// Remplacer l'élément de base par une DOM stylisable | |
replaceDOM: function () | |
{ | |
// La liste des nouveaux éléments | |
var newElements = []; | |
// Parcourir les éléments natifs que l'on a à remplacer | |
$(pDOMGroupSelector).each(function (i, el) | |
{ | |
// Cibler le scope jQuery | |
var $this = $(this); | |
// Si c'est déjà un objet radioComponent | |
if ($this.hasClass("radioComponent")) | |
{ | |
// Ajouter directement et ne pas remplacer | |
newElements.push(this); | |
return; | |
} | |
// Créer un objet jQuery avec le nouvel élément | |
var $newElement = $(_newDOM); | |
// Lui passer les valeurs | |
$newElement.toggleClass("selected", $this.attr("checked") == "checked"); | |
// Remplacer | |
$newElement.insertAfter($this); | |
$newElement.append($this); | |
// Ajouter ce nouvel élément à la liste | |
newElements.push($newElement[0]); | |
}); | |
// Cibler l'élément | |
$element = $(newElements); | |
}, | |
// Lorsque l'utilisateur à intéragi avec le composant | |
clickHandler: function (pEvent) | |
{ | |
console.log(this) | |
// Si on est sur un inputContainer | |
var $target = $(this).hasClass("inputContainer") ? $(this).find(".radioComponent") : $(this); | |
// Récupérer l'index de l'élément séléctionné | |
that.setSelectedIndex($element.index($target)); | |
}, | |
// Récupérer l'index sélectionné | |
getSelectedIndex: function () { return _selectedIndex; }, | |
setSelectedIndex: function (pValue) | |
{ | |
// Si la valeur est différent | |
if (pValue != _selectedIndex) | |
{ | |
// Enregistrer la valeur en limitant la valeur | |
_selectedIndex = Math.max(-1, Math.min(pValue, $element.length)); | |
// Séléctionner le bon élément visuel | |
$element.each(function (i, el) | |
{ | |
var $target = $(this); | |
var isSelected = $element.index($target) == _selectedIndex; | |
// Actualiser l'état sur la div remplaçante et sur l'input caché | |
$target.toggleClass('selected', isSelected); | |
$target.find("input[type=radio]").attr("checked", isSelected ? "checked" : null) | |
}); | |
// Signaler le changement | |
if (_selectedHandler != null) | |
{ | |
_selectedHandler(); | |
} | |
} | |
}, | |
// Récupérer la valeur sélectionnée | |
getSelectedValue: function () | |
{ | |
return $element.filter(".selected").find("input[type=radio]").attr("value"); | |
} | |
}; | |
// Appeler le constructeur | |
that.construct(); | |
// Retourner le contexte du composant | |
return that; | |
} | |
// Déclarer la librairie | |
if ("Require" in window) Require.register("lhs/radio", RadioComponent); | |
</script> | |
<form action=""> | |
<input type="radio" name="tutu" value="1"> | |
<input type="radio" name="tutu" value="2"> | |
<input type="radio" name="tutu" value="3"> | |
<input type="radio" name="tutu" value="4"> | |
</form> | |
<script type="text/javascript"> | |
// Chargé synchro dans script head | |
$(function () | |
{ | |
new RadioComponent("input[name=tutu]"); | |
}); | |
// Charger ASYNC avec Require | |
Require.load("lhs/radio", function (RadioComponent) | |
{ | |
$(function () | |
{ | |
new RadioComponent("input[name=tutu]"); | |
}); | |
}); | |
</script> | |
<style> | |
/** | |
* Boutons radio et checkboxes | |
*/ | |
.radioComponent, | |
.checkboxComponent | |
{ | |
// Placer | |
position: relative; | |
.inlineBlock; | |
.size(20px, 20px); | |
outline: none; | |
// Apparence | |
cursor: pointer; | |
// Masquer l'input | |
> input | |
{ | |
display: none; | |
} | |
// La partie cochée | |
> .radioFront, | |
> .checkboxFront | |
{ | |
// Placer | |
.place(50%, auto, auto, 50%); | |
.size(10px, 10px); | |
margin-left: -5px; | |
margin-top: -5px; | |
// Transparent par défaut | |
opacity: 0; | |
// Rendu | |
background-color: @mainColor; | |
// Transition entre les états | |
transition: opacity 150ms ease-in-out; | |
} | |
// Le fond | |
> .radioBack, | |
> .checkboxBack | |
{ | |
// Placer | |
.place(0, 0, 0, 0); | |
// Rendu | |
border: 1px solid @lightSeparatorColor; | |
background-color: white; | |
} | |
// La radio est juste arrondi | |
> .radioFront | |
{ | |
border-radius: 5px; | |
} | |
> .radioBack | |
{ | |
border-radius: 10px; | |
} | |
// Lorsque le bouton est sélectionné | |
&.selected | |
{ | |
> .radioFront, | |
> .checkboxFront | |
{ | |
// Afficher le coeur | |
opacity: 1; | |
} | |
} | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment