jQuery UI DatePicker : désactiver certains jours de la semaine

Posté par seiyar81 le 28 janvier 2014 | Laisser un commentaire (3)
jQuery UI DatePicker

jQuery UI propose bon nombre de widgets très utiles lorsqu’on développe des applications Web dynamiques.
Parmis ces derniers le DatePicker, ou calendrier, qui propose plusieurs options de configuration très précises.

Prenons par exemple le cas suivant : le client pour qui vous développez une application de réservation de restaurants vous informe que tous les réservations ne sont pas possibles les lundis et jeudis.

Et bien pas de problèmes, la fonction beforeShowDay permet de pré-filtrer chaque date et de définir si elle est sélectionnable ou pas.
Ce qui donne dans notre cas :


	jQuery(document).ready(function() {
		jQuery("#calendar").datepicker({
			beforeShowDay: function (date) {
				if (date.getDay() == 1 || date.getDay() == 4) { // La semaine commence à 0 = Dimanche
					return [false, ''];
				} else {
					return [true, ''];
				}
			}
		});
	});

Et voilà c’est tout simple.

On peut également utiliser la même méthode pour supprimer certaines semaines ou mois de l’année (vacances par exemple) :


	jQuery(document).ready(function() {
		jQuery("#calendar").datepicker({
			beforeShowDay: function (date) {
				if (date.getMonth() == 6 || date.getMonth() == 7) { // Mois Juillet et Août
					return [false, ''];
				} else {
					return [true, ''];
				}
			}
		});
	});

Si vous souhaitez par contre mettre une date minimum, utilisez plutôt l’option minDate :


	jQuery(document).ready(function() {
		jQuery("#calendar").datepicker({
			minDate: new Date(2014, 1 - 1, 1)
		});
	});

A vos claviers !

Catégorie: Développement Web, Javascript | Laisser un commentaire (3)

Java : sérialisation personnalisée de ses objets en JSON avec Flexjson

Posté par seiyar81 le 16 janvier 2014 | Laisser un commentaire (0)
JSON - Flexjson

Si vous travaillez sur des applis Web et Java et que vous vous retrouvez à devoir sérialiser vos données en JSON, il y a de fortes chances pour que vous utilisiez la bibliothèque Flexjson.

Les fonctionnalités de sérialisation sont puissantes et permettent par exemple de sériliaser un objet en profondeur.

Un exemple plutôt simple :


public class Yriase {
	
	private String name;

	public Yriase {
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

}


public static void main(String[] args) {

	Yriase y = new Yriase();
	y.setName( "yriase" );

	System.out.println( new JSONSerializer().exclude("*.class").serialize(yriase) );

}

Devrait vous renvoyer la chaîne suivante :

{
	name: "yriase"
}

Imaginons maintenant un cas un peu plus complexe. Vous avez créé une classe, et vous vous attendez à ce que les objets soient formattés d’une façon bien définie.
Pas de chance vous tombez dans le cas où le formattage par défaut de Flexjson ne vous convient pas.

Aucun problème, la bibliothèque vous offre la possibilité de définir vos propres Transformer pour vos données.

Prenons la classe template suivante :


public class Pair<String, Integer> {
	private String key;
	private Integer value;
    
	public Pair() {
	}
    
	public Pair(String k, Integer v) {
		this.key = k;
		this.value = v;
	}
    
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public Integer getValue() {
		return value;
	}
	public void setValue(Integer value) {
		this.value = value;
	}
}

Le formattage par défaut donnera ceci :

{
	key: "keyname",
	value: 10
}

Or on préfèrerait avoir le formattage suivant :

[ "keyname", 10 ]

Et bien il suffit d’implémenter une classe qui étends AbstractTransformer.
Voici donc la solution au problème :


public class PairTransformer extends AbstractTransformer {
	
	@Override
	public void transform(Object object) {
		Pair<String, Integer> p = (Pair<String, Integer>) object;
		
		getContext().writeOpenArray();
		
		getContext().writeQuoted( p.getKey());
		
		getContext().writeComma();
		
		getContext().write( String.valueOf(p.getValue()) );
		
		getContext().writeCloseArray();
	}
	
}

Et pour terminer il nous faut précisier lors de la sérialisation que l’on a un Transformer customisé :


JSONSerializer serializer = new JSONSerializer();
serializer.transform(new PairTransformer(), 	new Pair<String,Integer>().getClass());

Le tour est joué !

Catégorie: Développement Web, Java | Laisser un commentaire (0)

Remplir un formulaire avec jQuery

Posté par seiyar81 le 7 janvier 2014 | Laisser un commentaire (0)
jQuery Populate

Lorsque vous developpez une application Web, disons en PHP par exemple et que vous devez assigner vous-même les valeurs aux champs d’un formulaire, le mélange HTML/PHP peut vite s’avérer indigeste.

Si vous disposez de données JSON, ou de la possibilité de formater des données dans ce format, pour remplir votre formulaire, alors le plugin jQuery Populate devrait répondre à tous vos besoins.

Imaginons le formulaire HTML suivant :

	

Vous récupérez un jeu de données JSON via une requête AJAX ou bien directement formaté dans la page du type :

  var data = {

		name: "Yriase",

		type: ["0","2"],

		valider: false,

		comment: "Commentaire plus long"

	}

Grâce à Populate vous n’avez plus qu’à réaliser l’appel suivant :


	$('form["myform"]').populate(data);

Et le tour est joué !

Catégorie: Développement Web, Javascript | Laisser un commentaire (0)

Du nouveau à venir dans les offres de Giganews

Posté par seiyar81 le 17 novembre 2013 | Laisser un commentaire (0)
728x90a

Giganews a modifié ses offres Jeudi et pour le bien de tous puisque les tarifs sont en baisse !

Les tarifs des offres Diamond et Platinium baissent en effet de 5$ ce qui nous amènent à 20$ pour l’offre Platinium et 30$ pour l’offre Diamond. Les 3 premiers mois de cette dernière restant à -50% soit 15$.

Les deux offres procurent un accès illimité aux newsgroup avec une rétention binaire qui atteint aujourd’hui 1930 jours, le tout chiffré en SSL 256bits.
Les offres divergent ensuite avec les services ajoutés :

Platinium Diamond
20 connections 50 connections
5 Go de stockage Dump Truck 30 Go de stockage Dump Truck
VyprVPN Basic :
1 connection, PPTP
VyprVPN Pro :
2 connections, PPTP, L2TP/IPsec, OpenVPN, NAT Firewall

Sachez enfin que Mimo, le logiciel d’accès aux Newsgroup, est maintenant inclus avec toutes les offres.

Rendez-vous dans 70 jours donc pour fêter les 2000 jours de rétention binaire !

Catégorie: Geek, Internet, Newsgroup | Laisser un commentaire (0)

Initialiser une std::map avec C++11

Posté par seiyar81 le 17 novembre 2013 | Laisser un commentaire (0)
C++11

Une petite astuce, si l’on peut appeler ça comme ça, sur l’utilisation des maps en C++11. Cette nouvelle version du langage a en effet introduit les initializer_list et le principe de l’uniform initialization.
Je ne détaillerai pas plus en détails les méchanismes ni les possibilités apportées par ces fonctionnaliés mais je vous conseille de vous y intéresser dans un premier temps sur Wikipédia.

Imaginons que vous disposez d’une map à initialiser sur plusieurs niveaux, voilà ce que vous pouvez maintenant faire avec les nouveaux principes évoqués ci dessus :

std::map<int, std::map<int, int>> my_map = {
    {1, 
			{
				{2, 3}
			}
		}
};

Vous gagnez ainsi de nombreuses lignes à écrire et sans y perdre en visibilité.

Catégorie: C++ | Laisser un commentaire (0)

FullCalendar : chargement et mise à jour des évènements dans une base de données

Posté par seiyar81 le 7 août 2013 | Laisser un commentaire (7)

Pour faire suite au précédent article présentant le plugin FullCalendar, nous allons voir comment charger des évènements depuis une base de données pour peupler notre calendrier et ensuite comment les mettre à jour.

Nous allons pour cela mettre en place un calendrier avec affichage simple (mois/semaine/jour) sur notre page web :


<html>
<head>
<link href='fullcalendar/fullcalendar/fullcalendar.css' rel='stylesheet' />
<link href='fullcalendar/fullcalendar/fullcalendar.print.css' rel='stylesheet' media='print' />
<script src='fullcalendar/jquery/jquery.min.js'></script>
<script src='fullcalendar/jquery/jquery-ui.min.js'></script>
<script src='fullcalendar/fullcalendar/fullcalendar.js'></script>

<style>

	body {
		margin-top: 40px;
		text-align: center;
		font-size: 14px;
		font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
		}

	#calendar {
		width: 900px;
		margin: 0 auto;
		}

</style>
</head>
<body>
<div id='calendar'></div>
</body>
</html>

Côté serveur, il va nous falloir une base de données, forcément, avec une table pour stocker les évènements pouvant ressembler à ceci :



--
-- Table structure for table `event`
--

CREATE TABLE IF NOT EXISTS `event` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(55) NOT NULL,
  `start` datetime NOT NULL,
  `end` datetime DEFAULT NULL,
  `allDay` tinyint(1) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

On va ensuite ajouter le code Javascript pour charger et mettre à jour les évènements :


    $(document).ready(function() {
	
        function updateEvent(event,dayDelta,minuteDelta,allDay)
        {
            $.ajax({ 'url': 'ajax.php?action=update', 'type': 'POST', 
                'data': {'id':event.id, 'dayDelta': dayDelta, 'minuteDelta': minuteDelta, 'allDay': allDay},
                success: function(data) {
                    if(data.error)
                        alert(data.error);
                },
                error: function(data) {
                   alert('Une erreur est survenue.'); 
                }
            });
        }
		
				$('#calendar').fullCalendar({
            header: {
    					left: 'prev,next today',
							center: 'title',
							right: 'month,agendaWeek,agendaDay'
						},
            editable: true,
            eventSources: [
                'ajax.php?action=get'
            ],
            eventDrop: function(event,dayDelta,minuteDelta,allDay,revertFunc) {    
                if (!confirm("Valider la modification ?")) {
                    revertFunc();
                } else {
                    updateEvent(event,dayDelta,minuteDelta,allDay);
                }
            },
            eventResize: function(event,dayDelta,minuteDelta,revertFunc) {
                if (!confirm("Valider la modification ?")) {
                    revertFunc();
                } else {
                    updateEvent(event,dayDelta,minuteDelta,0);
                }
            }
		});
		
	});

On note donc que le paramètre d’initialisation eventSources indique au calendrier une (ou plusieurs) url à interroger pour charger les évènements.
Le résultat attendu étant un tableau au format JSON.
Les callbacks eventDrop et eventResize sont appellés dès qu’un évènement est modifié sur le calendrier.
Si l’utilisateur valide l’action, alors on appelle la fonction updateEvent qui enverra la requête d’update au serveur.
Les paramètres dayDelta, minuteDelta et allDay correspondent aux modifications apportées à l’évènement.

Pour fournir ce tableau c’est très simple.
On va créer une page PHP pour recevoir et traiter les requêtes AJAX :


    $dsn = 'mysql:dbname=fullcalendar;host=127.0.0.1';
    $user = 'root';
    $password = 'root';

    if(isset($_GET['action']))
    {
        switch($_GET['action'])
        {
            case 'get':
                try {
                    $db = new PDO($dsn, $user, $password);
                    
                    $sql = 'SELECT * FROM event';
                    $events = array();
                    
                    foreach ($db->query($sql) as $row) {
                        $events[] = $row;
                    }
                    
                    echo json_encode($events);
                    
                } catch (PDOException $e) {
                    echo json_encode(array('error' => 'Connection failed: ' . $e->getMessage()));
                }                
                break;
            default:
                break;
        }
    }
    

Très simple donc, on contrôle l’action reçue en paramètre, si c’est get alors on renvoit un tableau contenant les évènement stockés dans la base de données.
Un simple json_encode des évènements suffit.

Avec ce code on possède donc un calendrier affichant nos évènements.
Pour maintenant mettre à jour nos évènements en base de données, il faut juste ajouter l’action update côté serveur :


case 'update':
  try {
    $db = new PDO($dsn, $user, $password);
    
    $query = $db->query('SELECT * FROM event WHERE id = ' . $_POST['id']);
    $event = $query->fetch(PDO::FETCH_ASSOC);
    
    // Mise a jour de la date
    $diff = calculateDiff($_POST['dayDelta'], $_POST['minuteDelta']);
    
    $newStart = DateTime::createFromFormat('Y-m-d H:i:s', $event['start']);
    $newStart->modify($diff);
    
    $newEnd = DateTime::createFromFormat('Y-m-d H:i:s', $event['end']);
    $newEnd->modify($diff);
    
    $sql = 'UPDATE event SET start = "'.$newStart->format('Y-m-d H:i:s').'",
    end = "'.$newEnd->format('Y-m-d H:i:s').'",
    allDay = "'.$_POST['allDay'].'"
    WHERE id = ' . $_POST['id'];
    $row = $db->query($sql);
    
    echo json_encode(array('updated' => true));
  
  } catch (PDOException $e) {
    echo json_encode(array('error' => 'Db error : ' . $e->getMessage()));
  } catch (Exception $e) {
    echo json_encode(array('error' => $e->getMessage()));
  }       
break;

Le traitement est assez simple, on utilise la classe DateTime pour calculer les changements de dates avec sa méthode modify et deux fonctions que l’on va utiliser pour transformer les dayDelta et minuteDelta en chaîne compréhensible par DateTime :


	function pluralize($string) 
  {
      preg_match("|^([0-9]+)(.*)|",$string,$matched);
      if($matched[1] > 1) {
          return number_format($matched[1]) . $matched[2] . 's';
      }
      return $string;
  }

  function calculateDiff($dayDelta, $minuteDelta)
  {
      if($dayDelta != 'null' && $dayDelta != '0') {
          if($dayDelta < 0)
              $diff = "-".pluralize(abs(intval($dayDelta))." day");
          else if($dayDelta > 0)
              $diff = "+".pluralize(intval($dayDelta)." day");
      }
      else
          $diff = "";

			if($minuteDelta != 'null' && $minuteDelta != '0') {
          if($minuteDelta < 0)
              $diff .= "-".pluralize(abs(intval($minuteDelta))." minute");
          else
              $diff .= "+".pluralize(intval($minuteDelta)." minute");
      }
        
      return $diff;
  }

Ces fonctions vont par exemple transformer dayDelta = +2 : +30 en la chaîne "+2 days"

Et voilà on a maintenant un calendrier affichant nos propres évènements et les enregistrant en base de données.

Catégorie: Développement Web, Javascript | Laisser un commentaire (7)

Prestashop Advanced Sitemap : mises à jours GitHub

Posté par seiyar81 le 31 juillet 2013 | Laisser un commentaire (5)

Une news rapide pour signaler que le module est passé en version 1.4.5.2 suite à quelques mises à jour.
S’il n’y a pas de grosses nouvelles fonctionnalités, il y a toutefois une nouvelle présentation et mise en page, mais surtout un bloc affichant les dernières versions disponibles au téléchargement ainsi que les dernières mises à jour du module sur GitHub.
Le meilleur moyen donc de se tenir informé des modifications apportées au module et de voir si’ l’on est à jour.

N’hésitez donc pas à soumettre vos idées pour les prochaines versions du module.

Pour télécharger le module direction GitHub.

Catégorie: Développement Web, PHP | Laisser un commentaire (5)

Giganews : 1800 jours de rétention et un point sur les offres

Posté par seiyar81 le 19 juillet 2013 | Laisser un commentaire (0)
728x90a

Un petit point s’impose alors que l’offre Newsgroup de Giganews vient de dépasser les 1800 jours de rétention binaires (1809 exactement aujourd’hui) et 3679 jours de rétention texte.

Ce qui donne respectivement 5 et 10 ans tout de même !

Pour l’occasion voici un petit récapitulatif des offres en cours de Giganews, avec l’accès aux différents services additionnels comme VyprVPN et DumpTruck.

Offre Quota Rétention Connexions Sécurité Services Prix
Diamond Illimité 1809j 50 256bits SSL DumpTruck 30Go
VyprVPN
Mimo
17.49$/mois (3 mois) puis 34.99$/mois
soit 13.33€/mois puis 26.68€/mois
Platinium Illimité 1809j 20 256bits SSL DumpTruck 5Go 24.99$/mois
soit 19.05€/mois
Silver 50Go / mois 1809j 20 256bits SSL DumpTruck 5Go 14.99$/mois
soit 11.43€/mois
Bronze 10Go / mois 1809j 20 256bits SSL DumpTruck 5Go 9.99$/mois
soit 7.61€/mois
Pearl 5Go / mois 30j 20 256bits SSL DumpTruck 5Go 4.99$/mois
soit 3.80€/mois

Il y en a donc pour toutes les bourses et les détenteurs d’un abonnement Diamond seront bien récompensés puisque l’ajout d’un service de VPN et de 30 Go de stockage dans le Cloud se révèle plutôt intéressant.
En effet un abonnement VPN à un service externe (et de qualité) va coûter dans les 5€.

Pour le stockage Cloud tout dépendra du service choisi.
Par exemple Dropbox vous proposera 100Go pour 10$/mois, et Google la même chose pour 5$. Toutefois avec DumpTruck vous êtes assurés que vos données privées sont protégées et pas monétisées.

Vous devriez donc trouver votre bonheur sans problème parmis les offres Giganews.

Catégorie: Geek, Internet, Newsgroup | Laisser un commentaire (0)

Des div toujours visibles avec Sticky, un plugin jQuery

Posté par seiyar81 le 5 juillet 2013 | Laisser un commentaire (1)
Sticky

Lorsqu’on développe des sites ou applications Web, on peut être amenés à vouloir garder une partie de la page toujours visible lorsqu’on scroll.
Que ce soit pour un effet esthétique ou pour une question de praticité comme avec une barre d’actions ou un menu de navigation par exemple.

Plusieurs manières existent pour réaliser cet effet, mais je parlerai ici d’un plugin jQuery : Sticky.

Ci-dessous un petit exemple d’un header toujours visible :

  Sticky
  
  
  
  

  
  

Une première div qui va disparaître.

Une deuxième div qui va disparaître.

Une troisième div qui va disparaître.

Nous centrons donc notre header en CSS et nous indiquons ensuite à Sticky via la propriété center:true que l’on souhaite qu’il reste centré une fois collé en haut de la page.

Sticky est léger et configurable via 5 options :

  • topSpacing: Pixels entre le haut de la page et le haut de l’élément
  • bottomSpacing: Pixels entre le bas de la page et le bas de l’élément
  • className: Classe CSS ajouté à l’élément et à son wrapper quand il est collé
  • wrapperClassName: Classe CSS ajouté au wrapper
  • getWidthFrom: Sélecteur d’un élément utilisé pour régler la largeur fixe de l’élément collé

Libre à vous d’utiliser le CSS que vous souhaitez pour placer/dessiner votre élément.

Pour récupérer le plugin ou y contribuer, direction Github.

Catégorie: Développement Web, Javascript | Laisser un commentaire (1)

Prestashop Advanced Sitemap: v1.4.4 et CRON

Posté par seiyar81 le 15 juin 2013 | Laisser un commentaire (2)

Suite aux nombreuses demandes reçues en ce sens, j’ai modifié le plugin pour y ajouter une fonction CRON afin qu’il puisse être lancé automatiquement depuis n’importe quel service CRON.

Vous devrez d’abord créer une clé de sécurité via l’interface d’administration du plugin, ceci pour éviter que n’importe qui puisse faire appel au service.
Ensuite vous pourrez appeler le module via cette adresse :

[URL de la BOUTIQUE]/modules/gadvsitemap/cron.php?mode=cron&secure_key=[CLE de SECURITE]

Concernant les services CRON, si vous disposez d’un serveur sous Linux avec l’accès à crontab la configuration suivante suffira :

crontab -e
0 0 * * * wget [URL COMPLETE] 1>/dev/null 2>&1

Sinon vous pouvez faire appel à un service externe tel que :
webcron, cronless.com, easycron.com, ousetcronjob.com.

Pour télécharger la nouvelle version du module ça se passe sur GitHub.

Catégorie: Développement Web, Internet, PHP | Laisser un commentaire (2)