Faire un tutoriel de son application web avec Bootstrap Tour

Expliquer l’application aux utilisateurs

Il y a moultes façons de présenter une application et son fonctionnement aux utilisateurs.

xr7710_7-tips-for-creating-a-professional-powerpoint-presentation2x

La règle d’or de base veut que l’ergonomie porte le sens de l’application, mais quand tout est neuf, il est bien difficile de s’y repérer, même avec la meilleure ergonomie du monde.

On a de plus en plus souvent de nos jours, une petite introduction en douceur des mécanismes de l’outil, souvent via un petit tutoriel qui nous permet de comprendre comment cela fonctionne.

Des fois, ça peut-être une documentation écrite, parfois des vidéos, parfois autre chose, parfois rien.

Lire la suite

Rétrospective de la conférence Socrates France

Les 25 et 26 septembre dernier, j’ai assisté à la première édition de la déclinaison française de la conférence Socrates (@Socrates_FR). Nous étions 30 Craftsmens passionnés regroupés dans le magnifique château de Rochegude, situé dans le sud de la Drôme, près d’Orange.
2015_10_socrates_fr
Socrates est une « un-conférence » pour les développeurs sur 2 jours qui se différencie des autres conférences « classiques » du fait qu’elle est en mode open-space. Contrairement aux autres conférences où les organisateurs choisissent les speakeurs, le programme n’est pas déterminé à l’avance. Chaque participant apporte son expérience et ses connaissances qu’il peut partager comme bon le lui semble. Socrates rassemble des développeurs passionnés de TDD, Software Craftsmanship, DDD … La conférence est en anglais et reste assez agnostique d’un point de vue technique. Cette année, Java, C# et JavaScript étaient les langages les plus représentés

Lire la suite

Empêcher la fuite mémoire avec AngularJs et son $compile


Cette semaine, nous avons été confrontés à un problème particulier avec AngularJs.

Le navigateur affichait +500Mo de charge mémoire sur notre solution AngularJs, ce qui est bien trop avec un seul onglet.

En réalité, en observant les statistiques du nombre de watchers présents (avec ng-stat ou AngularJs Batarang) dans les différentes pages, nous avons découvert une fuite mémoire.

Chaque fois que nous cliquions sur un produit, 52 watchers s’ajoutaient aux déjà présents. Même comportement si nous revenions sur un produit sélectionné auparavant.

En réalité, la sélection d’un produit provoque un appel au serveur afin de récupérer le template destiné à être intégré dans un contrôle comprenant code html et directives éléments ou attributs AngularJs. Ce code sera donc interprété par le compile d’AngularJs.

Lire la suite

[MEETUP] Soft’it héberge le tout premier meetup dédié à AureliaJS autour d’un apéro

Auteur original, de notre ancien blog : Philippe Beroucry

Vous n’avez jamais entendu parler d’AureliaJS et vous n’êtes toujours pas parti en vacances ? Alors, Soft’it vous propose d’assister à un apéro autour de ce framework JavaScript très prometteur.

Ce premier meetup, organisé par Etienne Folio et Quentin Raynaud, permettra d’aborder le futur de ce meetup mais également :

  1. D’échanger autour d’Aurelia
  2. De discuter sur les différents frameworks ES6 actuellement disponibles
  3. De débattre d’une comparaison entre Angular2 vs Aurelia
… et bien d’autres choses.
Cet événement se déroulera ce mercredi 5 août à partir de 19h dans les locaux de Soft’it. Si vous souhaitez y participer (il reste encore des places), inscrivez-vous sur le meetup suivant :
A bientôt,
L’équipe Soft’it 

L’équipe Soft’it sera présente aux Microsoft TechDays 2015 : entre nouvelle ère et nouvelles technologies !

Quoi ? Vous n’avez jamais entendu parler des Techdays ? Non mais allo quoi ! Vous êtes des développeurs et vous n’avez jamais entendu parler de cet événement incontournable pour tout expert Microsoft !
Si tel est le cas, vous étiez sans doute sur une autre planète…

Une petite vidéo s’impose donc :

En effet, les TechDays de Microsoft (le 10, 11 et 12 février au Palais des Congrès, à Paris), donnent le ton sur l’avenir des nouvelles technologies tout en offrant également la possibilité de voir des démonstrations de nouveaux outils ou concepts aussi bien pour les développeurs que pour les décideurs.

Cette année, le thème –Ambiant Intelligence– sera principalement accès sur :

  • La mobilité
  • Le cloud
  • La Big Data
  • Le marchine Learning
  • Les objets connectés

Dès ce mardi (plus destiné au développeur), l’équipe de Soft’it va participer à un certain nombre de sessions techniques notamment sur des sujets encore inédits comme l’ASP .NET 5, l’Entity framework 7 ou bien encore les nouveautés d’ASP .NET MVC 6.

Par ailleurs, l’équipe tentera de vous faire participer au maximum à cet événement au travers de tweets, et plusieurs articles seront publiés dans les jours à venir.
Les membres de Soft’it présents seront (de gauche à droite – cliquez sur les noms pour accéder à leur Twitter): Marien Monnier, Pier-Lionel Sgard, Jérôme Veneziani, Philippe Gung, Laurent Jacques, Ikbal Benakila, Rémi Lesieur-Bridel, Cédric Burceaux, Emmanuelle Aboaf et Philippe Beroucry.

Normal
0

21

false
false
false

FR
X-NONE
X-NONE

/* Style Definitions */
table.MsoNormalTable
{mso-style-name: »Tableau Normal »;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent: » »;
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family: »Calibri »,sans-serif;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-fareast-language:EN-US;}

Enfin, pour cette année 2015, une grande nouvelle nouveauté ! 

Les TechDays, pour la première fois, seront accessibles aux
personnes sourdes et malentendantes via la vélotypie
.
La vélotypie est un
système de sous-titrage en temps réel projeté sur l’écran afin que tous
puissent lire ce qui est dit. Cela profite, non seulement aux personnes sourdes
et malentendantes, mais aussi à tous ceux qui n’arrivent pas à suivre ce qui
est dit pendant les conférences. 

Une des membres de l’équipe Soft’it, Emmanuelle Aboaf,
sourde de naissance, pourra bénéficier de ce système et suivre comme
tout le monde les conférences.
Soft’it remercie David Rousset et Microsoft
pour cette mise en place et salue l’initiative de rendre accessible l’événement
!

Vous trouverez une liste de sessions accessibles sur ce lien
http://blogs.msdn.com/b/davrous/archive/2015/02/03/liste-des-sessions-techdays-2015-accessibles-aux-sourds-et-malentendants.aspx

N’oubliez donc pas de revenir sur le blog pour avoir nos retours et vous faire partager au mieux cet événement incontournable.


window.twttr=(function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return;js=d.createElement(s);js.id=id;js.src= »https://platform.twitter.com/widgets.js »;fjs.parentNode.insertBefore(js,fjs);t._e=[];t.ready=function(f){t._e.push(f);};return t;}(document, »script », »twitter-wjs »));

Soft’it monte en compétence sur AngularJS !

Chez Soft’it, la connaissance est bien plus qu’un simple mot. En tenant compte aussi bien de notre Expertise .Net, Coaching qualité ou encore de nos formations, les collaborateurs de Soft’it se mettent régulièrement à jour en matière de nouvelles technologies.

Force est de constater que le nouveau framework JavaScript de Google (AngularJS) s’immisce dans tous les nouveaux projets Web actuels; l’équipe estime que cette technologie doit être impérativement maîtrisée par tous les membres pour garantir des applications Web de plus en plus robustes et puissantes.

Pour la toute première fois sur Paris, le site ng-workshop propose une formation AngularJS du 3 au 5 décembre incitant les développeurs à s’appliquer sur la qualité plus que sur la quantité dans leurs projets.
Pour vous donner un avant-goût des futurs articles que nous ferons autour d’AngularJS, nous aborderons durant la formation des sujets tels que  :

Construire et tester une
application
Communiquer avec un serveur backend
Sécuriser votre application
Internationaliser une application
AngularJS
Packager et déployer son application AngularJS

 Trois membres de l’équipe Soft’it vont participer à cette formation :

Bien évidemment, ces trois personnes se feront un plaisir de vous rédigez plusieurs articles sur cette formation pour vous donner l’envie de découvrir ce framework indispensable à l’avenir du développement Web 🙂

[MVC] Utilisation de jQuery DataTables en mode serveur

Note: le projet est disponible sur GitHub : https://github.com/MarienMonnier/softit-jquerydatatables-demo

Dans cet article, nous allons voir comment le plus simplement possible, vous allez pouvoir utiliser jQuery DataTables (version 1.10 minimum) en mode serveur, pour récupérer vos données via ASP.Net MVC 5.

Il existe déjà plusieurs projets qui montrent comment utiliser ASP.Net MVC avec jQuery DataTables, mais au final, dans tous les exemples que j’ai trouvé, ils utilisaient tous un custom IModelBinder pour pouvoir faire le binding des différentes propriétés avec un View Model. Sauf qu’en utilisant MVC 5 et jQuery DataTables 1.10 (et supérieur), ce custom binding n’est pas nécessaire, et il enlève une bonne épine du pied.

La mise en place d’une DataTables en mode serveur avec ASP.Net MVC va se faire en plusieurs étapes :

  1. Création des View Models
  2. Création de la vue
  3. Création du Controller et des services

Et parce qu’il est toujours intéressant de pouvoir ajouter des filtres personnalisés, nous finirons par :

  1. Ajout de filtres supplémentaires

Création des View Models

DataTables envoie et récupère des données sous un certain format qui lui est spécifique. À partir des informations fournies par la documentation, nous récréons d’abord les View Models.

Le View Model pour le résultat global :

public class DTResult<T>
{
    public int draw { getset; }
    public int recordsTotal { getset; }
    public int recordsFiltered { getset; }
    public List<T> data { getset; }
}

Et le View Model des paramètres qui sont envoyés par DataTables à la requête AJAX. La seule propriété qui ne fait pas partie de la requête est « SortOrder », qui est une propriété maison permettant de faire un tri sur nos données via la méthode d’extension SortBy<T> de l’objet IQueryable<T>.

public class DTParameters
{
    public int Draw { getset; }
    public DTColumn[] Columns { getset; }
    public DTOrder[] Order { getset; }
    public int Start { getset; }
    public int Length { getset; }
    public DTSearch Search { getset; }
    public string SortOrder
    {
        get
        {
            return Columns != null && Order != null && Order.Length > 0
                ? (Columns[Order[0].Column].Data + (Order[0].Dir == DTOrderDir.DESC ? " " + Order[0].Dir : string.Empty))
                : null;
        }
    }
}

Création de la vue

Dans le cadre de cet exemple, nous allons afficher une liste de produits de la base Northwind récupérés avec les différents appels AJAX de DataTables.

Tout d’abord la partie HTML (« bootstrapée »):

<div class="panel panel-default">
    <div class="panel-heading">Product Search</div>
    <table class="table table-striped table-hover table-bordered table-responsive" id="dt" width="100%">
        <thead>
            <tr>
                <th data-column="ID" data-order="desc">ID</th>
                <th data-column="Name">Name</th>
                <th data-column="UnitPrice">UnitPrice</th>
            </tr>
        </thead>
    </table>
</div>

Ensuite, la partie JavaScript qui fait appel à DataTables. Il n’y a rien de particulier dans ce code, c’est la configuration de base de DataTables pour :

  • faire les appels en mode serveur (processing: true et serverSide: true)
  • lui indiquer que la page à appeler est notre méthode GetData de notre HomeController
  • configurer les colonnes à afficher.
<script type="text/javascript">
    $(function() {
        var table = $('#dt');
        var dt = table.dataTable({
            ajax: {
                type: 'POST',
                url: '@Url.Action("GetData""Home")'
            },
            columns: [
                { data: 'ID' },
                { data: 'Name' },
                { data: 'UnitPrice' }
            ],
            order: [0, 'desc'],
            processing: true,
            serverSide: true,
            orderMulti: false
        });
    });
</script>

Création du Controller et des services

La table est maintenant configurée pour appeler l’action GetData du HomeController.

Notre contrôleur a une méthode GetData qui :

  • prend en paramètre le View Model DTParameters que nous avons écrit et qui contient tous les paramètres que DataTables nous envoie
  • fait appel à un service (GetProducts) pour récupérer les produits en fonction de ces paramètres
  • fait appel à un second service (Count) pour récupérer le nombre d’éléments suivant ces paramètres (pour la pagination)
  • retourne les données au format JSON telles qu’attendues par DataTables (un DTResult<Product>).
public JsonResult GetData(DTParameters dtModel)
{
    try
    {
        List<Product> data = new ProductService().GetProducts(dtModel.Search.Value, dtModel.SortOrder, dtModel.Start, dtModel.Length);
        int count = new ProductService().Count(dtModel.Search.Value);
        DTResult<Product> result = new DTResult<Product>
                            {
                                draw = dtModel.Draw,
                                data = data,
                                recordsFiltered = count,
                                recordsTotal = count
                            };
        return Json(result);
    }
    catch (Exception ex)
    {
        return Json(new { error = ex.Message });
    }
}

Et les méthodes de service associées :

public class ProductService
{
    private static readonly List<Product> Products;
 
    static ProductService()
    {
        Products = new List<Product>
                    {
                        new Product(1, "Chai", 18.0000m),
                        new Product(2, "Chang", 19.0000m),
                        // ...
                        new Product(76, "Lakkalikööri", 18.0000m),
                        new Product(77, "Original Frankfurter grüne Soße", 13.0000m)
                    };
    }
 
    public List<Product> GetProducts(string search, string sortOrder, int start, int length)
    {
        return FilterProducts(search).SortBy(sortOrder).Skip(start).Take(length).ToList();
    }
 
    public int Count(string search)
    {
        return FilterProducts(search).Count();
    }
 
    private IQueryable<Product> FilterProducts(string search)
    {
        IQueryable<Product> results = Products.AsQueryable();
 
        if (!string.IsNullOrWhiteSpace(search))
            results = results.Where(p => p.Name.Contains(search));
 
        return results;
    }
}

Les services sont plutôt simples :

  • une méthode pour récupérer une liste de produits suivant une recherche, un tri, et une pagination
  • une méthode qui permet de compter le nombre d’éléments suivant le filtre donné (pour que la pagination soit effective côté jQuery DataTables).

Nous avons à présent une démo fonctionnelle qui nous permet de lister les produits de manière paginée, de changer le nombre d’éléments par page, et de rechercher un produit par son nom :

Ajout de filtres supplémentaires

Il peut toujours être intéressant de passer des données supplémentaires à vos appels AJAX qui sont faits par DataTables, ne serait-ce que pour ajouter des filtres, passer un ID supplémentaire, etc…

Toutes ces données sont à ajouter dans le paramètre data de DataTables.

On va modifier un peu la vue et le JavaScript pour ajouter un panel de filtre sur nos prix minimum et maximum; et un bouton pour lancer la recherche.

<div class="panel panel-default">
    <div>...</div>
    <div class="panel-body">
        <div class="well">
            <div class="row">
                <div class="col-xs-4">
                    <label for="minPrice">Minimum Price</label>
                    <input type="text" name="minPrice" id="minPrice" value="" class="form-control" />
                </div>
                <div class="col-xs-4">
                    <label for="maxPrice">Maximum Price</label>
                    <input type="text" name="maxPrice" id="maxPrice" value="" class="form-control" />
                </div>
                <div class="col-xs-2">
                    <button id="search" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
                </div>
            </div>
        </div>
    </div>
    <table>...</table>
</div>

Nous passons les filtres dans la fonction data de DataTables, et rafraîchissons la table lorsque l’on clique sur le bouton de recherche :

var dt = table.dataTable({
    ajax: {
        type: 'POST',
        url: '@Url.Action("GetData""Home")',
        data: function(d) {
            d.MinPrice = $('#minPrice').val();
            d.MaxPrice = $('#maxPrice').val();
        }
    },
    columns: [ ... 
});
$('#search').click(function(e) {
    e.preventDefault();
    dt.fnDraw();
});

Nous avons maintenant une vue qui nous permet de sélectionner un prix minimum et maximum. Mettons à jour le Controller et les services pour prendre en compte ces nouvelles données.

Nous passons dans l’appel AJAX deux nouvelles propriétés (MinPrice et MaxPrice), que nous allons mettre dans une classe FilterViewModel très simple :

public class FilterViewModel
{
    public decimal? MinPrice { getset; }
    public decimal? MaxPrice { getset; }
}

Et nous faisons évoluer notre méthode GetData du Controller pour prendre aussi un FilterViewModel en paramètre, et passer les valeurs à nos deux méthodes de service :

public JsonResult GetData(DTParameters dtModelFilterViewModel filterModel)
{
    try
    {
        List<Product> data = new ProductService().GetProducts(dtModel.Search.Value, dtModel.SortOrder, dtModel.Start, dtModel.Length, filterModel.MinPrice, filterModel.MaxPrice);
        int count = new ProductService().Count(dtModel.Search.Value, filterModel.MinPrice, filterModel.MaxPrice);
        DTResult<Product> result = new DTResult<Product>
                            {
                                draw = dtModel.Draw,
                                data = data,
                                recordsFiltered = count,
                                recordsTotal = count
                            };
        return Json(result);
    }
    catch (Exception ex)
    {
        return Json(new { error = ex.Message });
    }
}

Faisons évoluer nos méthodes de service pour y ajouter un filtre sur le prix minimum et maximum :

public List<Product> GetProducts(string search, string sortOrder, int start, int lengthdecimal? minPrice, decimal? maxPrice)
{
    return FilterProducts(search, minPrice, maxPrice).SortBy(sortOrder).Skip(start).Take(length).ToList();
}
 
public int Count(string searchdecimal? minPrice, decimal? maxPrice)
{
    return FilterProducts(search, minPrice, maxPrice).Count();
}
 
private IQueryable<Product> FilterProducts(string searchdecimal? minPrice, decimal? maxPrice)
{
    IQueryable<Product> results = Products.AsQueryable();
 
    if (!string.IsNullOrWhiteSpace(search))
        results = results.Where(p => p.Name.Contains(search));
 
    if (minPrice.HasValue)
        results = results.Where(p => p.UnitPrice >= minPrice.Value);
 
    if (maxPrice.HasValue)
        results = results.Where(p => p.UnitPrice <= maxPrice.Value);
 
    return results;
}

Et voilà !

Nous avons maintenant une démo qui nous permet avec jQuery DataTables 1.10 de faire des requêtes serveur sur notre site MVC 5 en ajoutant des filtres personnalisés, tout cela en quelques minutes seulement.

Pour rappel, ce projet se trouve sous GitHub à l’adresse suivante : https://github.com/MarienMonnier/softit-jquerydatatables-demo

Et, comme je le signalais au début de l’article, il existe déjà plusieurs projets qui ont été faits pour MVC / jQuery DataTables; projets qui peuvent vous intéresser si vous utilisez des versions précédentes de MVC et/ou jQuery DataTables :