[PouchDb] [Cloudant] [Vue.js]Un premier Formulaire avec la Technologie Cloud d’Ibm.

pouchcloudanttéléchargé

Introduction


Une base de données hébergée dans le cloud permet, entre autre, les avantages suivants : Synchro temps réel entre les navigateurs, réplication de bdd, bases de données gigantesques, Recherche avancée avec Elastic Search(indexation…), Map reduce … Bref, ici on va seulement déjà faire tourner une base de donnée CouchDb, avec la librairie additionnelle PushDb qui prends le relais en local au cas ou le matériel perde la connexion.

L’interface Homme Machine tourne en html 5  avec le framework Front-End vue.js et la librairie Bootstrap vue v4.0, du coup on a encore besoin d’un bon vieux serveur apache, sur free.fr, par exemple … Pour cet exo, pas de test tablette, seulement du  22 pouces.

lapin.jpg « Et pourquoi que tu fais un exercice comme ça, petit jojo ? « 

Parce que, selon la doc, PouchDb permet d’envisager la création d’applications complexes synchronisées, sur tablettes, qui résistent au mode offline, tout cela avec la syntaxe js, toujours relativement simple et cohérente, surtout avec le framework vue.js.

De plus, en 2016 J’avais déjà expérimenté AngularJs + Firebase et ç’était vraiment trop bon avec le 3 way binding, seulement le défaut de Firebase est qu’il est exclusivement hébergé online, alors que couchDb peut être installé sur des serveurs persos, et tourne avec jquery, node.js, et SURTOUT en mode no-serveur, avec pourtant une authentification, car c’est aussi un serveur web ! Ce qui signifie se passer de code serveur , et ça pour les pré-maquettes, c’est seulement génial, quoi , petit ! ( C’est l’activation de CORS sur cloudant qui va nous permettre cela (Cross site connection enabler)

lapin2.jpg « Ouf, ca va, je suis rassuré maintenant, grouinch, galop.. galop . »

Pourquoi IBM Cloudant ?


Aws et Google Cloud demandent la carte bleue, par contre Ibm Cloudant est gratuit pour l’instant, en tout cas ça marche bien, avec juste des limitations de connexion.

Pour la méthode, ben, ne pas prendre peur, créer son compte ibm cloudant, puis créer sa base noSql de type cloudant. Je n’ai pas le temps d’expliquer ça là. Il faut juste choisir une base de données couchDb bien sur.

cloudant.jpg

Ensuite il y a  choses importantes à faire pour cet exo :

  1. Générer les données d’identification, qui va permettre à notre app HTML de se connecter à la base couchDb :cloudant2.jpg

2. Activer CORS afin que l’on se serve de couchDb directement à partir du front end en JS  (Bien sur, ce n’est pas safe, pour l’instant,( hi hi )!

cors

 lapin4.jpg « Bon ça y est , c’est fini ?  groinch « 

La Micro App


On va élaborer un humble formulaire repris de ce post, qui nous permet d’entrer un email, une plaque d’immatriculation, et une marque, un peu à la manière de l’ANTS . bref c’est pour entrer un véhicule dans une bdd noSql couchDb

Le temps global de dev est approximativement de 30- 45 minutes , parce qu’on découvre, mais bien sur, ça se réduira ensuite.

Pour l’instant, pas d’authentification couchDb, on commence simple … L’update n’est pas là non plus …

PouchDb


pouchDb est vraiment trop intéressant, en effet c’est ,pour résumer au maximum et approximativement,  une réplique locale de la base de données couchDb, qui attends puis synchronise automatiquement en cas de coupure réseau. Autrement dit, quelque chose d’extrêmement intéressant  pour le matos mobile !

Tester le super formulaire… one Agaaain


Je l’ai mis sur free : http://nicolas.huleux.free.fr/pouchdb/indexvuepouch.html

puhhh

Le Manifest pour forcer la mise en cache


Se renseigner sur l’ajout de Manifest dans la balise HTML , qui force la mise en cache d’une app web … Je l’ai mise sans plus d’analyse pour l’instant.

Le fichier Index.html


Il charge les libs en début et fin de script.

Il charge donc également le fichier app.js qui contient notre code vue.js

Dans le HTML , on voit les champs input, et la liste des automobiles qui provient de couchDb .

<html manifest="example.appcache">
	<head>
	<meta http-equiv="X-UA-Compatible" content="IE=8" />
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Exo pouchdb</title>
        
		<!------------------------------------------------------------ CHARGEMENT DES LIBRAIRIES ------------------------------------------------>
		
		<!-- Bootstrap et Bootstrap vue. -->
		<link type="text/css" rel="stylesheet" href="bootstrapvue/bootstrap.min.css" />
		<link type="text/css" rel="stylesheet" href="bootstrapvue/bootstrap-vue.css" />
		<script src="bootstrapvue/vue.js"></script>
		<script src="bootstrapvue/polyfill.min.js"></script>
		<script src="bootstrapvue/bootstrap-vue.js"></script>
		
		<!-- JQuery. -->
		<script src="js/jquery.min.js"></script>
		<!-- PouchDb. -->
		<script src="js/pouchdb.min.js"></script>
		<!-- Vuepouch plug in.  https://github.com/sadick254/vuepouch -->
		<script src="js/vuepouch.js"></script>
		

		
		<!------------------------------------------------------- FIN DE CHARGEMENT DES LIBRAIRIES ------------------------------------------------->
	</head>

<!-- La page HTML générale -->

<body style="background-color:tan" >
	<div id="app"  >
	<div class="row" style="margin:5%">
		<div class="card " style="width:50%;">
			<div class="card-header">
				<h5 class="card-title">Formulaire</h5>
			</div>
			<div class="card-body">
				<b-form @submit="onSubmit" @reset="onReset" v-if="show">
					<b-form-group id="exampleInputGroup1" label="Votre email:" label-for="exampleInput1" description="Nous ne partageons pas votre email avec quelqu'un.">
						<b-form-input id="exampleInput1" type="email" v-model="form.email" required placeholder="Entrez l'email"> </b-form-input>
					</b-form-group>
					<b-form-group id="exampleInputGroup2" label="La plaque de votre véhicule:" label-for="exampleInput2">
						<b-form-input id="exampleInput2" type="text" v-model="form.plaque" required placeholder="Entrez la plaque d'immatriculation"> </b-form-input>
					</b-form-group>
					<b-form-group id="exampleInputGroup3" label="La marque:" label-for="exampleInput3">
						<b-form-select id="exampleInput3" :options="marques" required v-model="form.marque"> </b-form-select>
					</b-form-group>
					<b-form-group id="exampleGroup4">
						<b-form-checkbox-group v-model="form.checked" id="exampleChecks">
							<b-form-checkbox value="email">Envoyez moi un email</b-form-checkbox>
							<b-form-checkbox value="sms">Envoyez moi un SMS</b-form-checkbox>
						</b-form-checkbox-group>
					</b-form-group>
					<div align="right">
						<b-button type="submit" variant="primary">Enregistrer</b-button>
						<b-button type="reset" variant="danger">Reset</b-button>
					</div>
				</b-form>
			</div>
			<div class="card-footer"></div>
		</div>
		<div class="card " style="width:50%;">
			<div class="card-header">
				<h5 class="card-title">Liste</h5>
			</div>
			<div class="card-body">
				<ul>
					<li v-for="a in  automobiles">{{a.email}}-{{a.plaque}}-{{a.marque}}</li>
				</ul>
			</div>
			<div class="card-footer"></div>
		</div>
	</div>
</body>

<!-- Chargement de l'app -->
<script src="js/app.js"></script>
<!-- Css perso -->
<link type="text/css" rel="stylesheet" href="style.css" />

Le fichier APP.JS


On instantie notre objet vue, et on peut voir qu’il y a un objet pouchDb qui permet de spécifier la base locale pouchDb et la base online couchDb.

C’est grâce à vuepouch (https://github.com/sadick254/vuepouch ), la petite librairie de sadick254 dédiée au pilotage de pouchdb par vue.js, qu’on peut faire ça facilement. Il existe une autre lib plus grosse à tester ces jours ci : https://github.com/QurateInc/vue-pouch-db — (Note : en effet, la synchro n’est pas globale pour l’instant avec cette petite lib, epxlication dans la conclusion.)

Dans la méthode ajouterAutomobile(), on voit qu’on se sert de $pouchdbRefs qui nous permet d’ajouter les automobiles à la base de données pouchDb Locale qui synchronise ensuite avec la base de données couchDb Online.

var app = new Vue({
	el: "#app",
	data() {
		return {
			form: {
				email: '',
				plaque: '',
				marque: null,
				checked: []
			},
			marques: [{
				text: 'Selectionnez',
				value: null
			}, 'Peugeot', 'Renault', 'Citroen', 'Ds'],
			show: true,
			personnes:[]
		}
	},
	pouchdb: {
		vehicules: {
		  localDB: "vehicules",
		  remoteURL: "https://xxxxxxxx-be6e-42d6-b914-d0ecae937981-bluemix:8eeedbe180c1ce90cdc3ae37b9e74af7368b21a37b531aae819929d3405c7d22@1c54473b-be6e-42d6-b914-d0ecae937981-bluemix.cloudant.com/vehicules"
		}
	},
	computed: {
		automobiles() {
		  return this.vehicules.automobiles
		},
		camions() {
		  return this.vehicules.camions
		}
	},
	methods: {
		onSubmit(evt) {
					evt.preventDefault();
					this.ajouterAutomobile(this.form);
				},
		onReset(evt) {
			evt.preventDefault();
			/* Reset our form values */
			this.form.email = ''; 
			this.form.plaque = '';
			this.form.marque = null;
			this.form.checked = [];
			/* Trick to reset/clear native browser form validation state */
			this.show = false;
			this.$nextTick(() => {
				this.show = true
			});
		},
		ajouterAutomobile(form) {
			this.$pouchdbRefs.vehicules.put('automobiles',form)
		},
		addPassenger () {
			this.$pouchdbRefs.vehicules.put('camions', /*your data*/)
		} 
	}
})

 Conclusion


On voit qu’on peut désormais, en activant CORS, écrire directement dans la base couchDb.

Si l’on perds l’accès à couchDb et qu’on continue à enregistrer des véhicules, mes petits essais sommaires ont montré que pouchDb attends la reconnexion, puis exécute une à une les requêtes sur la base online (Dans la console, on les voit passer).

Cependant, subsiste un problème, en effet, Contrairement à Firebase+AngularJs, la synchronisation n’est pas temps réelle, c’est à dire que si j’ouvre 2 navigateurs différents, et que j’entre une info dans l’un, je ne la vois pas apparaitre automatiquement dans l’autre (il faut alors appuyer sur F5), c’est donc ce que l’on va tenter de corriger avec l’utilisation du module https://github.com/QurateInc/vue-pouch-db qui semble corriger ce problème.

En effet, pas envie de mettre un timer qui recharge couchDb à intervalle régulière, je pense que le module vue-pouch-db doit le gérer automatiquement.

Publicités

[Vue.js] Controler les champs d’un formulaire avec vue.js, puis les colorer si erreur avec bootstrap-vue.js

téléchargé.jpg

Introduction


Exemple de controle de champs avec vue.js, puis coloration des champs en erreur, avec bootstrap vue .

Etape un : Un formulaire pour app one page (pas de submit )


Tester le code ici .


<html>
	<head>
	<meta http-equiv="X-UA-Compatible" content="IE=8" />
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Exo Vue.Js</title>
        
		<!------------------------------------------------------------ CHARGEMENT DES LIBRAIRIES ------------------------------------------------>
        
		<script src="js/vue.min.js"></script>
		
		<!------------------------------------------------------- FIN DE CHARGEMENT DES LIBRAIRIES ------------------------------------------------->
	</head>

<!-- La page HTML générale -->
<body >
	<form id="app" >
  
  <p v-if="errors.length">
    <b>Corrigez les erreurs suivantes:</b>
    <ul>
      <li v-for="error in errors">{{ error }}</li>
    </ul>
  </p>
  {{success}}
  <p>
    <label for="name">Nom<label>
    <input type="text" v-model="nom" >
  </p>

  <p>
    <label for="age">Age<label>
    <input type="number" v-model="age" min="0">
  </p>

  <p>
    <label for="film">Film favori<label>
    <select  v-model="film">
      <option>Star Wars</option>
      <option>Vanilla Sky</option>
      <option>Atomic Blonde</option>
    </select>
  </p>

  <p  >
    <button type="button" v-on:click="checkForm()" style="float: right;">   ok </button>
  </p>

</form>
</body>

Le code vue.js :

const app = new Vue({
  el:'#app',
  data:{
    errors:[],
    nom:null,
    age:null,
    film:null,
	success:null
  },
  methods:{
    checkForm:function(e) {

     this.errors = [];
      if(!this.nom){
		this.errors.push("le nom est requis.");
		return false;
      };
      if(!this.age ){
		this.errors.push("L'age est requis.") ;
		return false;
	  };
	  if(this.age < 18){
		this.errors.push("L'age est trop bas.") ;
		return false;
	  };

	  this.success = ' Vous avez correctement rempli le formulaire ';
    }
  }
})

Les CSS :

input[type=text], select {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    display: inline-block;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

input[type=number], select {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    display: inline-block;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

input[type=submit] {
    width: 100%;
    background-color: #4CAF50;
    color: white;
    padding: 14px 20px;
    margin: 8px 0;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

input[type=submit]:hover {
    background-color: #45a049;
}

div {
    border-radius: 5px;
    background-color: #f2f2f2;
    padding: 20px;
}

Etape 2 : On veut colorer les champs ou la personne s’est trompé ..

Tester le code ici.

Il faut alors utiliser bootstrap vue :

 

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
	<link type="text/css" rel="stylesheet" href="bootstrapvue/bootstrap.min.css" />
	<link type="text/css" rel="stylesheet" href="bootstrapvue/bootstrap-vue.css" />
	<script src="bootstrapvue/vue.js"></script>
	<script src="bootstrapvue/polyfill.min.js"></script>
	<script src="bootstrapvue/bootstrap-vue.js"></script>
</head>

<body>
	<div id="app">
		<div class="card " style="width: 18rem;">
			<b-form @submit="onSubmit" @reset="onReset" v-if="show">
				<b-form-group id="exampleInputGroup1" label="Email address:" label-for="exampleInput1" description="We'll never share your email with anyone else.">
					<b-form-input id="exampleInput1" type="email" v-model="form.email" required placeholder="Enter email"> </b-form-input>
				</b-form-group>
				<b-form-group id="exampleInputGroup2" label="Your Name:" label-for="exampleInput2">
					<b-form-input id="exampleInput2" type="text" v-model="form.name" required placeholder="Enter name"> </b-form-input>
				</b-form-group>
				<b-form-group id="exampleInputGroup3" label="Food:" label-for="exampleInput3">
					<b-form-select id="exampleInput3" :options="foods" required v-model="form.food"> </b-form-select>
				</b-form-group>
				<b-form-group id="exampleGroup4">
					<b-form-checkbox-group v-model="form.checked" id="exampleChecks">
						<b-form-checkbox value="me">Check me out</b-form-checkbox>
						<b-form-checkbox value="that">Check that out</b-form-checkbox>
					</b-form-checkbox-group>
				</b-form-group>
				<b-button type="submit" variant="primary">Submit</b-button>
				<b-button type="reset" variant="danger">Reset</b-button>
			</b-form>
		</div>
	</div>
</body>

Le code vue :

var app = new Vue({
		el: '#app',
		data() {
			return {
				form: {
					email: '',
					name: '',
					food: null,
					checked: []
				},
				foods: [{
					text: 'Select One',
					value: null
				}, 'Carrots', 'Beans', 'Tomatoes', 'Corn'],
				show: true
			}
		},
		methods: {
			onSubmit(evt) {
				evt.preventDefault();
				alert(JSON.stringify(this.form));
			},
			onReset(evt) {
				evt.preventDefault();
				/* Reset our form values */
				this.form.email = '';
				this.form.name = '';
				this.form.food = null;
				this.form.checked = [];
				/* Trick to reset/clear native browser form validation state */
				this.show = false;
				this.$nextTick(() => {
					this.show = true
				});
			}
		}
	})

Les CSS :

	.card {
		margin: 0 auto;
		/* Added */
		float: none;
		/* Added */
		margin-bottom: 10px;
		/* Added */
		margin-top: 5%;
	}

#45a049, #4caf50, #ccc, #f2f2f2

[Vue.Js ] Choisir des personnes dans une liste, puis les transférer dans une autre

téléchargé.jpg

Introduction


Choisir des personnes ( Des objets JSON …) dans un tableau d’objet JSON, puis les copier dans un autre tableau d’objets JSON, quand on clique sur un bouton .

On voit là que vue.js structure bien et rends la réalisation d’ un truc de ce genre méga facile, fait en 3 minutes !! Pour l’instant, c’est comme du angularJs, mais en plus structuré !

Tester le code en temps réel


Cliquer ici !

Le code :


La vue HTML :

<html>
	<head>
	<meta http-equiv="X-UA-Compatible" content="IE=8" />
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Exo Vue.Js</title>
        
		<!------------------------------------------------------------ CHARGEMENT DES LIBRAIRIES ------------------------------------------------>
        
		<!-- development version, includes helpful console warnings -->
		<script src="js/vue.min.js"></script>
		
		<!------------------------------------------------------- FIN DE CHARGEMENT DES LIBRAIRIES ------------------------------------------------->
	</head>

<!-- La page HTML générale -->
<body >
	<div id="example-1">
		Liste générale
		<ul >
		  <li v-for="p in personnes">
			<button  v-on:click="choisir(p)" >+</button> {{ p.nom }} 
		  </li>
		</ul>
		
		Liste des personnes choisies
		<ul >
		  <li v-for="c in personnesChoisies">
			{{ c.nom }} 
		  </li>
		</ul>
	</div>
</body>

Le code vue.js :

<!-- Vue.Js -->

var example1 = new Vue({
  el: '#example-1',
  data: {
    personnes: [
      { nom: 'Philippe' },
      { nom: 'Jalok' },
	   { nom: 'William' },
	    { nom: 'Kamel' },
    ],
	personnesChoisies:[]
  },
  methods: {
	choisir: function(p){

		// Etape 1 : on supprime la personne choisie de la liste générale
		this.personnes.splice(
		  this.personnes.indexOf(p), 1
		);

		// Etape 2 : On l'ajoute à la liste des personnes choisies
		this.personnesChoisies.push({ nom:p.nom }); // Ajout à la liste des personnes choisies
	}
  }

})