Un système de grille fluide basé sur LESS

Voici venir , une mixin LESS destinée à vous aider à générer dans votre CSS une grille fluide à tous points de vue : au sens propre du terme bien sûr, mais aussi bien dans son paramétrage que dans son emploi.

La mixin s'utilise de la manière suivante :

.greed(12, 10px); // nombre maximal de colonnes (défaut : 12), taille des gouttières (défaut : 0)

Et voici un exemple de grille en HTML :

<div class="greed">
<div class="row-4">
<div class="col-1"></div> <!-- 25% -->
<div class="col-3"></div> <!-- 75% -->
</div>
<div class="row-12">
<div class="col-1"></div> <!-- 8.3333333333 % -->
<div class="col-11"></div> <!-- 91.6666666667 % -->
</div>
</div>

Apprenez-en plus et contribuez au projet (si vous le voulez) sur la page GitHub de celui-ci !

Gérez vos environnements dans vos projets PHP 5.3+

J'ai le plaisir de vous présenter Environ, un petit pour PHP 5.3 ou supérieur, qui vous permettra de jongler facilement entre vos différents environnements (développement, tests, production...) tout en détectant automatiquement lequel est actif et quelles sont les actions à mener en conséquence (par exemple, l'ouverture d'une connexion à une base de données différente, ou encore l'activation de fonctionnalités de debug).

Celui-ci suit bien évidemment la norme PSR-2 et peut être installé facilement via Composer. Apprenez-en davantage en vous rendant sur la page GitHub du projet, sur laquelle vous aurez également l'occasion de collaborer si vous le souhaitez (sombres analogies mises à part) !

Utiliser Typeahead.js de Twitter dans une application AngularJS

Si vous avez tenté d'utiliser le plugin JavaScript d'autocomplétion de Twitter, baptisé Typeahead.js, au sein d'une directive dans votre application AngularJS, d'une façon similaire à celle-ci :

angular.module('myDirectives', [])
.directive('initTypeahead', function() {
return function(scope, element, attrs) {
element.typeahead({
// ...
});
};
});

...vous avez peut-être eu la désagréable surprise de constater que lors de la sélection d'une valeur par l'utilisateur, la variable du $scope Angular définie en tant que modèle de l'input sur lequel vous avez appliqué la directive précédente ne se mettait pas correctement à jour, conservant pour toute valeur les quelques lettres saisies au préalable.

Typeahead mettant à notre disposition des évènements JavaScript permettant de détecter ladite sélection, le réflexe primordial et naïf (c'est du vécu) sera d'appliquer manuellement un $scope.apply() dans le listener adéquat :

angular.module('myDirectives', [])
.directive('initTypeahead', function() {
return function(scope, element, attrs) {
element.typeahead({
// ...
}).on('typeahead:selected typeahead:autocompleted', function() {
scope.$apply();
});
};
});

Hélas, le souci étant bien localisé dans l'actualisation du $scope depuis la vue (et non l'inverse), ceci se révèlera insuffisant pour appliquer la bonne valeur depuis le DOM, avec lequel nous serons obligés d'interagir :

angular.module('myDirectives', [])
.directive('initTypeahead', function() {
return function(scope, element, attrs) {
element.typeahead({
// ...
}).on('typeahead:selected typeahead:autocompleted', function(data) {
scope[element.data('ng-model')] = data.target.value;
scope.$apply();
});
};
});

Cette astuce vous évitera une imbrication plus profonde (passant par exemple par l'écriture d'un service dédié au sein de votre application), ce qui se traduira par un précieux gain de temps si vous n'utilisez cette librairie que pour répondre à un besoin ponctuel.

Un plugin jQuery pour passer facilement un formulaire en AJAX

Je viens d'achever le développement de Tao, un permettant de modifier facilement le comportement d'un formulaire HTML. En effet, un simple appel du plugin suffit pour donner à ce formulaire la capacité de se soumettre via AJAX, en utilisant les éléments et attributs présents à l'origine. Le plugin accepte les mêmes options que la méthode ajax() de jQuery, ce qui est notamment utile pour la définition des callbacks.

Plus d'info sur la page GitHub du projet, sur laquelle vous pouvez aussi commenter et/ou forker si le coeur vous en dit !

De l'utilisation d'AngularJS avec un formulaire qui sera soumis au serveur

Le framework frontend JavaScript MVC AngularJS a l'avantage d'être pensé de façon à pouvoir être utilisé uniquement sur un module donné, au lieu d'englober la totalité de l'application sur laquelle il est utilisé. Il est donc très pratique de s'en servir pour renforcer un élément complexe dans votre projet (comme un moteur de recherche devant interfacer une API JSON, par exemple). Néanmoins, il est parfois nécessaire de ruser un peu pour contourner son comportement lorsque le formulaire HTML que vous alimentez joyeusement à l'aide d'AngularJS est tout de même destiné à être envoyé côté serveur.

Tout d'abord, il faut savoir qu'AngularJS bloque automatiquement la soumission "classique" d'un formulaire sous son joug , sauf si celui-ci dispose d'un attribut action. Mais qu'en est-il si vous souhaitez déléguer la gestion du formulaire à AngularJS sous certaines conditions, ou plutôt jusqu'à un certain point ? Je pense notamment à la validation, un point que le framework gère très bien, mais pour lequel il peut être sympathique d'avoir un moyen de lui demander de nous rendre la main quand sa tâche est accomplie.

Il y a plusieurs solutions envisageables ; de mon côté, je privilégie la suivante, qui est limpide et facilement réutilisable. Voici la balise d'ouverture du formulaire :

<form method="POST" data-target="/my-action.html" data-ng-submit="submit()">

Notez l'attribut personnalisé data-target qui vient remplacer l'action, ainsi que le listener pour l'évènement de soumission. Voici la méthode appelée par ce dernier, qui pour notre exemple se situe directement dans notre contrôleur :

$scope.submit = function() {
var $form = $element.find('form'); // à ajuster
if (/* insérez ici vos conditions */) {
$form.attr('action', $form.data('target')).submit(); // le formulaire sera désormais soumis de manière classique
}
};

Simplissime, non ? D'aucuns souligneront que procéder ainsi équivaut à un viol potentiel (pour toi, Google) du principe de base d'AngularJS qui interdit toute manipulation du DOM dans un contrôleur. À mes yeux, il s'agit plus d'un tour de passe-passe qu'autre chose, mais c'est vous qui voyez.

...d'autant que transformer ce code en une directive ne représente pas un obstacle insurmontable.

moi du Futur

Un autre point qui peut être surprenant lors des premiers pas avec AngularJS concerne la façon dont celui-ci remplit les select. En effet, aucun contrôle n'est possible sur l'attribut value des éléments option générés par la directive correspondante, à savoir ngOptions. Plutôt que de chercher un chemin de traverse compliqué, faisons preuve d'astuce :

<!-- Ne faites pas : -->
<select name="my_key" ng-model="myModel" ng-options="select o.label for o in myOptions"></select>

<!-- Mais faites plutôt : -->
<select ng-model="myModel" ng-options="select o.label for o in myOptions"></select>
<input type="hidden" name="my_key" value="{{ myModel }}" />

Ceci vous permet de gérer indépendamment le select et la valeur correspondante qui sera envoyée au serveur.