Skip to content

Instantly share code, notes, and snippets.

@zouloux
Created March 17, 2014 13:43
Show Gist options
  • Save zouloux/9599393 to your computer and use it in GitHub Desktop.
Save zouloux/9599393 to your computer and use it in GitHub Desktop.
RadioComponent Solid
<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