Skip to content

Instantly share code, notes, and snippets.

@dib258
Created January 12, 2018 23:32
Show Gist options
  • Save dib258/467417e362e5cf6cdecfb839fb53de9e to your computer and use it in GitHub Desktop.
Save dib258/467417e362e5cf6cdecfb839fb53de9e to your computer and use it in GitHub Desktop.
Vuejs component to show map + CRUD of institute / student
<template>
<div class="card my-3">
<div class="card-header d-flex">
<div class="pt-2">
<span
class="text mt-2"
v-show="!isEditing"
>
<a v-show="show" :href="'institute/'+institute.id">{{ institute.name }}</a>
<span v-show="!show">{{ institute.name }}</span>
</span>
<input
class="form-control"
v-show="isEditing"
v-model="institute.name"
v-on:keyup="edited = true"
placeholder="Institute name"
>
</div>
<div class="ml-auto">
<button
v-on:click="isEditing = true"
v-if="!isEditing"
class="btn btn-primary"
>
<i class="fa fa-pencil" aria-hidden="true"></i>
</button>
<button
v-on:click="updateInstitute()"
v-if="isEditing"
class="btn btn-success"
>
<i class="fa fa-check" aria-hidden="true"></i>
</button>
<button
v-show="show"
v-on:click="deleteInstitute()"
class="btn btn-danger ml-1"
>
<i class="fa fa-times" aria-hidden="true"></i>
</button>
<button v-on:click="createStudent()" class="btn btn-default ml-1">
Add <i class="fa fa-user" aria-hidden="true"></i>
</button>
<button
v-on:click="$emit('uploadfile', { element : institute.id })"
class="btn btn-default"
data-toggle="modal"
data-target="#uploadModal"
>
Import
<i class="fa fa-file-excel-o" aria-hidden="true"></i>
</button>
</div>
</div>
<div class="card-body">
<div class="row mb-2" v-if="isEditing">
<div class="col">
<input
class="form-control"
v-show="isEditing"
v-model="institute.address_number"
v-on:keyup="edited = true"
placeholder="Number"
>
</div>
<div class="col">
<input
class="form-control"
v-show="isEditing"
v-model="institute.address_street"
v-on:keyup="edited = true"
placeholder="Street name"
>
</div>
<div class="col">
<input
class="form-control"
v-show="isEditing"
v-model="institute.address_postal"
v-on:keyup="edited = true"
placeholder="Postal code"
>
</div>
<div class="col">
<input
class="form-control"
v-show="isEditing"
v-model="institute.address_city"
v-on:keyup="edited = true"
placeholder="City"
>
</div>
</div>
<div v-if="notYetCreatedUser.length">
<student
v-for="(student, index) in notYetCreatedUser"
v-bind:key="index + '-notcreated'"
v-bind:student="student"
v-on:studentdeleted="deleteStudent"
v-on:studentcreated="confirmStudentCreated"
></student>
</div>
<div v-if="notValidUser.length">
<h5 class="card-title">Invalid address user</h5>
<h6 class="card-subtitle mb-2 text-muted">You need to change the address for this student to be valid</h6>
<student
v-for="(student, index) in notValidUser"
v-bind:key="index + '-invalid'"
v-bind:student="student"
v-on:studentdeleted="deleteStudent"
v-on:studentcreated="confirmStudentCreated"
v-on:studentupdate="updateStudent"
></student>
</div>
<h5 class="card-title">Valid address user</h5>
<student
v-for="(student, index) in validUser"
v-bind:key="index + '-valid'"
v-bind:student="student"
v-on:studentdeleted="deleteStudent"
v-on:studentcreated="confirmStudentCreated"
v-on:studentupdate="updateStudent"
v-if="validUser.length"
></student>
<div v-else>
No valid student yet
</div>
</div>
</div>
</template>
<script>
// import Student from 'student';
export default {
props : ['institute', 'students', 'show'],
data () {
return {
// students : [],
isOneStudentInCreation : false,
isEditing : false
};
},
computed : {
notYetCreatedUser() {
return this.students.filter(function (student) {
return student.id == -1
});
},
notValidUser() {
return this.students.filter(function (student) {
return !student.is_valid && student.id != -1;
});
},
validUser() {
return this.students.filter(function (student) {
return student.is_valid && student.id != -1;
})
}
},
methods : {
updateInstitute() {
if (this.isEditing && this.edited) {
axios
.put('/institute/'+this.institute.id, {
name : this.institute.name,
address_number : this.institute.address_number,
address_street : this.institute.address_street,
address_postal : this.institute.address_postal,
address_city : this.institute.address_city,
})
.then(function (response) {
this.isEditing = false;
this.edited = false;
console.log('[Institute.vue] updateInstitute.then :', response.data);
this.institute.latitude = response.data.latitude;
this.institute.longitude = response.data.longitude;
this.$emit('instituteupdate', {
institute : this.institute,
students : this.students
});
}.bind(this))
.catch(error => console.log('[Institute.vue] updateInstitute.catch : ', error));
} else {
this.isEditing = false;
}
},
deleteInstitute() {
if (confirm('Are you sure you want to delete the Institute ?\nAll the students inside will be deleted too !')) {
axios
.delete('/institute/'+this.institute.id)
.then(function (response) {
console.log('[Institute.vue] deleteInstitute.then : ', response.data.message);
this.$emit('institutedelete', {
element: this.institute
});
}.bind(this))
.catch(error => console.log('[Student.vue] deleteInstitute.catch : ', error));
}
},
// Student
createStudent() {
if (!this.isOneStudentInCreation) {
this.isOneStudentInCreation = true;
this.students.push({
id: -1,
firstname: '',
lastname: '',
address_city: '',
address_number: '',
address_postal: '',
address_street: '',
is_valid: 1,
latitude: 0,
longitude: 0,
transport_mode: '',
institute_id: this.institute.id
});
} else {
// scroll to the current student in creation
// or shake the current student in creation
}
},
confirmStudentCreated(element) {
var studentNew = element.element
console.log('[Institute.vue] confirmStudentCreated : ', studentNew, this.students);
var student = this.students.filter(function (element) {
if (element.id == -1 || element.id == studentNew.id) {
return element;
}
}.bind(studentNew));
console.log('[Institute.vue] confirmStudentCreated : found student', student);
if (student.length > 0) {
var id = this.students.indexOf(student[0]);
// Remove the current new student
this.students.splice(id, 1);
// this.students[id] = studentNew;
this.isOneStudentInCreation = false;
// Emit to the parent to let him add the new student
this.$emit('studentcreate', {
institute : this.institute,
student : studentNew
})
} else {
console.log('[Institute.vue] confirmStudentCreated.else : error student new not found');
}
},
updateStudent(element) {
var studentNew = element.element;
console.log('[Institute.vue] updateStudent : ', studentNew);
var student = this.students.filter(function (element) {
if (element.id == studentNew.id) {
return element;
}
});
console.log('[Institute.vue] updateStudent : found student', student);
// if (student.length > 0) {
var id = this.students.indexOf(student[0]);
this.students.splice(id, 1);
// this.students[id] = studentNew;
console.log('[Institute.vue] updateStudent.if : found student');
this.$emit('studentupdate', {
institute : this.institute,
student : studentNew
})
// Redo the sort between good and invalid user (or it'll be automatic after the correct update of the new student data)
// } else {
// console.log('[Institute.vue] updateStudent.else : error student not found');
// }
},
deleteStudent(element) {
var student = element.element;
var id = this.students.indexOf(student);
if (id > -1) {
this.$emit('studentdelete', {
institute : this.institute,
student : student
})
this.students.splice(id, 1);
} else {
console.log('[Institute.vue] deleteStudent.else : error finding student to delete');
}
}
},
created() {
console.log('[Institute.vue] created : ',this.institute);
// Retrieve only the id and let the Student component grab it's informations
// More request but otherwise how to have parent / child same information
// Since I create an empty user in the institute array
// Then the update of the data happen in the child (Student component)
// ???
// axios
// .get('/institute/'+this.institute.id+'/student')
// .then((response) => {
// this.students = response.data;
// });
}
}
</script>
@extends('layouts.app')
@section('content')
<div class="container">
<school
v-bind:institutes="{{ json_encode($institutes) }}"
v-bind:schoolid="{{ $schoolId }}"
v-bind:show="true"
v-bind:publicpath="{{ json_encode(asset('')) }}"
></school>
</div>
@endsection
<template>
<div>
<div id="mapdiv" class="my-3"></div>
<StudentMap
v-for="(tuple, index) in database"
v-bind:key="index"
v-bind:map="map"
v-bind:tuple="tuple"
v-bind:publicpath="publicpath"
></StudentMap>
<!-- v-bind:institute="tuple.institute" -->
<!-- v-bind:students="tuple.students" -->
</div>
</template>
<script>
import StudentMap from './StudentMap.vue';
export default {
props : ['database', 'publicpath'],
data() {
return {
map : null,
};
},
watch : {
database () {
this.$forceUpdate();
console.log('[MapBox.vue] watch.database : Detected a change in the database');
}
},
created() {
/* Minimum Zoom 0 , Maximum Zoom 20 */
/* Creation of the OpenStreetMap */
var oMapCenter =
{
center: [50.820008, 4.368169],
zoom: 11
}
var oTileSettings =
{
maxZoom: 18,
minZoom: 12,
id: 'mapbox.streets',
accessToken: document.head.querySelector('meta[name="mapbox-token"]').content
}
// Why the observer database.length is empty, but contains the 3 tuples ?
// this.database.forEach(function (tuple) {
// }.bind(this));
this.$nextTick(function () {
this.map = L.map('mapdiv', oMapCenter);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', oTileSettings).addTo(this.map);
L.control.scale().addTo(this.map);
}.bind(this));
},
components : {
StudentMap
}
}
</script>
<style lang="scss">
#mapdiv {
height: 600px;
}
.leaflet-bottom.leaflet-right {
/* Make the Attributions disappear from left bottom border */
bottom: -20px !important;
}
.leaflet-left {
.leaflet-control {
.leaflet-control-scale-line {
&:first-child {
background-color: rgba(255, 255, 255, 0);
}
&:last-child {
display: none;
}
}
}
}
</style>
<template>
<div>
<mapbox
v-bind:database="database"
v-bind:publicpath="publicpath"
></mapbox>
<div v-show="!show">
<a :href="publicpath" v-show="!show" class="btn btn-default">
<i class="fa fa-chevron-left" aria-hidden="true"></i> Back
</a>
</div>
<div v-show="show" class="text-right">
<button v-on:click="createInstitute()" class="btn btn-default my-3">Add Institution</button>
</div>
<div class="card" v-show="isOneInstituteInCreation">
<div class="card-header d-flex">
<div class="pt-2">Create a new Institute</div>
<div class="ml-auto">
<button v-on:click="storeInstitute()" class="btn btn-success"><i class="fa fa-check"></i></button>
<button v-on:click="isOneInstituteInCreation = false; edited = false;" class="btn btn-danger"><i class="fa fa-times"></i></button>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<input
class="form-control"
v-model="newInstitute.name"
v-on:keyup="edited = true"
placeholder="Name"
>
</div>
<div class="col">
<input
class="form-control"
v-model="newInstitute.address_number"
v-on:keyup="edited = true"
placeholder="Number"
>
</div>
<div class="col">
<input
class="form-control"
v-model="newInstitute.address_street"
v-on:keyup="edited = true"
placeholder="Street name"
>
</div>
<div class="col">
<input
class="form-control"
v-model="newInstitute.address_postal"
v-on:keyup="edited = true"
placeholder="Postal code"
>
</div>
<div class="col">
<input
class="form-control"
v-model="newInstitute.address_city"
v-on:keyup="edited = true"
placeholder="City"
>
</div>
</div>
</div>
</div>
<institute
v-for="(element, index) in database"
v-bind:key="index"
v-bind:institute="element.institute"
v-bind:students="element.students"
v-bind:show="show"
v-on:uploadfile="showModal"
v-on:institutedelete="deleteInstitute"
v-on:instituteupdate="updateInstitute"
v-on:studentcreate="addStudent"
v-on:studentupdate="updateStudent"
v-on:studentdelete="deleteStudent"
></institute>
<div class="modal" v-show="isModalShowed" :class="{ in: isModalShowed }" id="uploadModal" tabindex="-1" role="dialog" aria-labelledby="uploadModal" aria-hidden="true">
<form id="uploadForm" :action="'http://goodmap.test/institute/'+uploadInstituteId+'/uploadExcel'" method="post" enctype="multipart/form-data">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Upload excel file</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<input type="hidden" name="_token" :value="csrf">
<input class="form-control" type="file" name="excel">
<!-- <label class="btn btn-default">
<span class="btn btn-primary">Browse file</span> <input type="file" name="excel" hidden>
</label> -->
</div>
<div class="modal-footer text-right">
<button type="submit" class="btn btn-primary">Upload file</button>
</div>
</div>
</div>
</form>
</div>
</div>
</template>
<script>
export default {
props : ['institutes', 'schoolid', 'show', 'publicpath'],
data() {
return {
isOneInstituteInCreation : false,
edited : false,
newInstitute : {
id: -1,
name: '',
address_city: '',
address_number: '',
address_postal: '',
address_street: '',
latitude: 0,
longitude: 0,
school_id: this.schoolId
},
uploadInstituteId : 0,
isModalShowed : false,
csrf : document.head.querySelector('meta[name="csrf-token"]').content,
database: []
};
},
methods : {
showModal(element) {
console.log('[School.vue] showModal : called !', element.element);
// this.isModalShowed = true;
this.uploadInstituteId = element.element;
},
createInstitute() {
if (!this.isOneInstituteInCreation) {
this.isOneInstituteInCreation = true;
this.newInstitute = {
id: -1,
name: '',
address_city: '',
address_number: '',
address_postal: '',
address_street: '',
latitude: 0,
longitude: 0,
school_id: this.schoolid
};
} else {
// scroll to the current student in creation
// or shake the current student in creation
}
},
storeInstitute() {
if (this.isOneInstituteInCreation && this.edited) {
axios
.post('/institute', {
name : this.newInstitute.name,
address_number : this.newInstitute.address_number,
address_street : this.newInstitute.address_street,
address_postal : this.newInstitute.address_postal,
address_city : this.newInstitute.address_city,
school_id : this.schoolid
})
.then(function (response) {
// this.institutes.push(response.data.institute);
this.database.push({
institute : response.data.institute,
students : []
});
console.log('[School.vue] storeInstitute.if.then : '+response.data.id);
this.isOneInstituteInCreation = false;
this.edited = false;
}.bind(this))
.catch(error => console.log('[School.vue] storeInstitute.if.catch : '+error));
} else {
this.isOneInstituteInCreation = false;
this.edited = false;
}
},
updateInstitute(element) {
var institute = element.institute;
var students = element.students
for (var i = 0; i < this.database.length; i++) {
if (this.database[i].institute.id == institute.id) {
this.database.splice(i, 1);
this.database.push({
institute : institute,
students : students
});
// this.database[i].institute = institute;
this.$forceUpdate();
console.log('[School.vue] updateInstitute.if : ', this.database);
}
}
},
deleteInstitute(element) {
var institute = element.element;
console.log('[School.vue] deleteInstitute : print institute');
console.log(institute);
for (var i = 0; i < this.database.length; i++) {
if (this.database[i].institute.id == institute.id) {
// this.database.splice(i, 1);
console.log('[School.vue] deleteInstitute.if.beforeDelete : ', this.database);
Vue.delete(this.database, i);
// this.$forceUpdate();
console.log('[School.vue] deleteInstitute.if.afterDelete : ', this.database);
}
}
// var id = this.institutes.indexOf(institute);
// console.log('[School.vue] deleteInstitute.id : '+id);
// if (id > -1) {
// this.institutes.splice(id, 1);
// this.$forceUpdate()
// console.log('[School.vue] deleteInstitute.if : ', this.institutes);
// } else {
// console.log('[School.vue] deleteInstitute.else : error finding institute to delete');
// }
},
addStudent(element) {
for (var i = 0; i < this.database.length; i++) {
if (this.database[i].institute.id == element.institute.id) {
this.database[i].students.push(element.student);
this.$forceUpdate();
console.log('[School.vue] addStudent.if : ', this.database[i].students);
}
}
},
updateStudent(element) {
console.log('[School.vue] updateStudent : ', element.institute, element.student);
for (var i = 0; i < this.database.length; i++) {
if (this.database[i].institute.id == element.institute.id) {
// for (var j = 0; j < this.database[i].students.length; j++) {
// if (this.database[i].students[j].id == element.student.id) {
// this.database[i].students[j] = element.student;
// this.database[i].students.splice(j, 1);
this.database[i].students.push(element.student);
this.$forceUpdate();
console.log('[School.vue] updateStudent.if : found ', this.database[i].students);
// }
// }
}
}
},
deleteStudent(element) {
for (var i = 0; i < this.database.length; i++) {
if (this.database[i].institute.id == element.institute.id) {
for (var j = 0; j < this.database[i].students.length; j++) {
if (this.database[i].students[j].id == element.student.id) {
this.database[i].students.splice(j, 1);
this.$forceUpdate()
console.log('[School.vue] deleteStudent.if : ', this.database[i].students);
}
}
}
}
}
},
mounted() {
this.$nextTick(function () {
console.log('[School.vue] created : ', this.institutes.length);
// For each institute we make an ajax request to retrieve is students
for(var i = 0; i < this.institutes.length; i++) {
console.log('[School.vue] created : ', this.institutes[i]);
axios
.get('/institute/'+this.institutes[i].id+'/student')
.then(function (response) {
for (var j = 0; j < this.institutes.length; j++) {
if (this.institutes[j].id == response.data.instituteid) {
console.log('[School.vue] created.then : ', this.institutes[j]);
this.database.push({
institute : this.institutes[j],
students : response.data.students
});
}
}
}.bind(this));
}
}.bind(this));
}
}
</script>
<template>
<div class="row my-2 border p-2 student">
<div class="col-1">
<span
class="text mt-2"
v-show="!isEditing"
>
{{ student.firstname }}
</span>
<input
class="form-control"
v-show="isEditing"
v-model="student.firstname"
v-on:keyup="edited = true"
placeholder="Firstname"
>
</div>
<div class="col-1">
<span
class="text mt-2"
v-show="!isEditing"
>
{{ student.lastname }}
</span>
<input
class="form-control"
v-show="isEditing"
v-model="student.lastname"
v-on:keyup="edited = true"
placeholder="Lastname"
>
</div>
<div class="col-1">
<span
class="text mt-2"
v-show="!isEditing">
{{ student.address_number }}
</span>
<input
class="form-control"
v-show="isEditing"
v-model="student.address_number"
v-on:keyup="edited = true"
placeholder="Number"
>
</div>
<div class="col-2">
<span
class="text mt-2"
v-show="!isEditing">
{{ student.address_street }}
</span>
<input
class="form-control"
v-show="isEditing"
v-model="student.address_street"
v-on:keyup="edited = true"
placeholder="Street name"
>
</div>
<div class="col-2">
<span
class="text mt-2"
v-show="!isEditing">
{{ student.address_postal }}
</span>
<input
class="form-control"
v-show="isEditing"
v-model="student.address_postal"
v-on:keyup="edited = true"
placeholder="Postal code"
>
</div>
<div class="col-2">
<span
class="text mt-2"
v-show="!isEditing">
{{ student.address_city }}
</span>
<input
class="form-control"
v-show="isEditing"
v-model="student.address_city"
v-on:keyup="edited = true"
placeholder="City"
>
</div>
<div class="col-2">
<span
class="text mt-2 badge"
:class="colorForTransportation(student.transport_mode)"
v-show="!isEditing">
{{ student.transport_mode }}
</span>
<select
class="form-control"
v-show="isEditing"
v-model="student.transport_mode"
v-on:change="edited = true"
>
<option disabled value="">Transport</option>
<option
v-for="(transport, index) in transportation_mode"
v-bind:key="index"
v-bind:value="transport.value"
>
{{ transport.text }}
</option>
</select>
</div>
<div class="col-1 d-flex">
<button v-show="!isEditing" v-on:click="isEditing = true" class="btn btn-primary"><i class="fa fa-pencil" aria-hidden="true"></i></button>
<button v-show="isEditing" v-on:click="updateStudent()" class="btn btn-success"><i class="fa fa-check" aria-hidden="true"></i></button>
<button v-on:click="deleteStudent()" class="btn btn-danger ml-1"><i class="fa fa-times" aria-hidden="true"></i></button>
</div>
</div>
</template>
<script>
export default {
props : ['student'],
data () {
return {
isNew : false,
isEditing : false,
edited : false,
transportation_mode : [
{ text: 'Pied', value: 'pied', color : 'vert'},
{ text: 'Velo', value: 'velo', color : 'bleu'},
{ text: 'Moto', value: 'moto', color : 'rouge'},
{ text: 'Voiture', value: 'voiture', color : 'rouge'},
{ text: 'Covoiturage', value: 'covoiturage', color : 'violet'},
{ text: 'Bus', value: 'bus', color : 'orange'},
{ text: 'Tram', value: 'tram', color : 'orange'},
{ text: 'Train', value: 'train', color : 'orange'},
]
};
},
methods : {
colorForTransportation(value) {
var elm = this.transportation_mode.filter(function (transport) {
if ( transport.value == value) return transport;
});
if (elm.length > 0) {
return elm[0].color;
}
},
updateStudent() {
if (this.isEditing && this.edited) {
if (this.isNew) {
console.log('[Student.vue] updateStudent.if : is new');
axios
.post('/student', {
firstname : this.student.firstname,
lastname : this.student.lastname,
address_number : this.student.address_number,
address_street : this.student.address_street,
address_postal : this.student.address_postal,
address_city : this.student.address_city,
transport_mode : this.student.transport_mode,
institute_id : this.student.institute_id
})
.then(function (response) {
this.student.id = response.data.id;
this.student.is_valid = response.data.is_valid;
this.student.latitude = response.data.latitude;
this.student.longitude = response.data.longitude;
console.log('[Student.vue] updateStudent.if.then : '+response.data.id);
this.isEditing = false;
this.isNew = false;
this.edited = false;
this.$emit('studentcreated', {
element : this.student
});
}.bind(this))
.catch(error => console.log('[Student.vue] updateStudent.if.catch : '+error));
} else {
console.log('[Student.vue] updateStudent.else : is not new');
axios
.put('/student/'+this.student.id, {
firstname : this.student.firstname,
lastname : this.student.lastname,
address_number : this.student.address_number,
address_street : this.student.address_street,
address_postal : this.student.address_postal,
address_city : this.student.address_city,
transport_mode : this.student.transport_mode
})
.then(function (response) {
this.isEditing = false;
this.edited = false;
// Retrieve is address is valid
console.log('[Student.vue] updateStudent.else.then : '+response.data.is_valid);
this.student.is_valid = response.data.is_valid;
this.student.latitude = response.data.latitude;
this.student.longitude = response.data.longitude;
this.$emit('studentupdate', {
element : this.student
});
}.bind(this))
.catch(error => console.log('[Student.vue] updateStudent.else.catch : '+error));
}
} else {
// If nothing has been changed we do not sent modifications
this.isEditing = false;
}
},
deleteStudent() {
if (!this.isNew) {
if (confirm('Are you sure you want to delete this student ?')) {
axios
.delete('/student/'+this.student.id)
.then(function (response) {
console.log('[Student.vue] deleteStudent.then : '+response.data.message);
this.$emit('studentdeleted', {
element: this.student
});
}.bind(this))
.catch(error => console.log('[Student.vue] deleteStudent.catch : ' +error));
}
} else {
this.$emit('studentdeleted', {
element: this.student
});
}
}
},
created() {
if (this.student.id == -1) {
this.isNew = true;
this.isEditing = true;
}
}
}
</script>
<style lang="scss">
.student {
span {
display : inline-block;
}
.badge {
padding: 9px;
border-radius: 82px;
color: #FFFFFF;
}
.orange {
background-color : #F08707;
}
.bleu {
background-color : #1895D3;
}
.violet {
background-color : #B383AF;
}
.rouge {
background-color : #ff5b5b;
}
.jaune {
background-color : #f9c851;
}
.vert {
background-color : #10c469;
}
}
</style>
<template>
<div></div>
</template>
<script>
export default {
props: ['map', 'tuple', 'publicpath'],
data() {
return {
oSmallCircleParams : {
color: 'blue', // Stroke
weight: '5', // Stroke
opacity: '0,3', // Stroke
stroke: false, // stroke
film: true,
fillColor: 'blue',
fillOpacity: 0.3,
radius: 500
// clickabe: true [ If you want to click ]
// className : 'NameOfClass' [ If you want to give it a class ]
},
oBigCircleParams : {
color: 'green', // Stroke
weight: '5', // Stroke
opacity: '0,2', // Stroke
stroke: false, // stroke
film: true,
fillColor: 'green',
fillOpacity: 0.2,
radius: 2000
// clickabe: true [ If you want to click ]
// className : 'NameOfClass' [ If you want to give it a class ]
},
instituteIcon : L.icon(
{
iconUrl: this.publicpath+'icons/school.svg',
iconSize: [50, 50], // Icon Dimension
iconAnchor: (0, 0), // Position Icon
popupAnchor: [-3, -76] // Popup Anchor Position from Icon
}
),
veloIcon : L.icon(
{
iconUrl: this.publicpath+'icons/velo.svg',
iconSize: [15, 15], // Icon Dimension
iconAnchor: (0, 0), // Position Icon
popupAnchor: [-3, -76] // Popup Anchor Position from Icon
}
),
motoIcon : L.icon(
{
iconUrl: this.publicpath+'icons/moto.svg',
iconSize: [15, 15], // Icon Dimension
iconAnchor: (0, 0), // Position Icon
popupAnchor: [-3, -76] // Popup Anchor Position from Icon
}
),
voitureIcon : L.icon(
{
iconUrl: this.publicpath+'icons/voiture.svg',
iconSize: [15, 15], // Icon Dimension
iconAnchor: (0, 0), // Position Icon
popupAnchor: [-3, -76] // Popup Anchor Position from Icon
}
),
piedIcon : L.icon(
{
iconUrl: this.publicpath+'icons/pied.svg',
iconSize: [15, 15], // Icon Dimension
iconAnchor: (0, 0), // Position Icon
popupAnchor: [-3, -76] // Popup Anchor Position from Icon
}
),
covoiturageIcon : L.icon(
{
iconUrl: this.publicpath+'icons/covoiturage.svg',
iconSize: [15, 15], // Icon Dimension
iconAnchor: (0, 0), // Position Icon
popupAnchor: [-3, -76] // Popup Anchor Position from Icon
}
),
tramIcon : L.icon(
{
iconUrl: this.publicpath+'icons/tram.svg',
iconSize: [15, 15], // Icon Dimension
iconAnchor: (0, 0), // Position Icon
popupAnchor: [-3, -76] // Popup Anchor Position from Icon
}
),
trainIcon : L.icon(
{
iconUrl: this.publicpath+'icons/train.svg',
iconSize: [15, 15], // Icon Dimension
iconAnchor: (0, 0), // Position Icon
popupAnchor: [-3, -76] // Popup Anchor Position from Icon
}
),
busIcon : L.icon(
{
iconUrl: this.publicpath+'icons/bus.svg',
iconSize: [15, 15], // Icon Dimension
iconAnchor: (0, 0), // Position Icon
popupAnchor: [-3, -76] // Popup Anchor Position from Icon
}
),
arrayIcon : null,
layerGroup : null,
};
},
methods : {
addSchoolAndRadius(institute) {
console.log('[MapBox.vue] addSchoolAndRadius : begin');
/* Creation of Circles */
// Radius are in Meters
var school = [institute.latitude, institute.longitude];
var oSmallCircle = L.circle((school), this.oSmallCircleParams).addTo(this.layerGroup);
var oBigCircle = L.circle((school), this.oBigCircleParams).addTo(this.layerGroup);
/* Creation of Popups in already created circle */
var sBigCirclePopup = "Distance parcourable à vélo (rayon de 4km autour de l'école)";
oBigCircle.bindPopup(sBigCirclePopup);
/* Creation of Marker with Institutes Image */
L.marker( (school), {icon: this.instituteIcon} ).addTo(this.layerGroup);
},
addStudents(students) {
console.log('[MapBox.vue] addStudents : begin');
students.forEach(function (student) {
if (student.is_valid && student.id != -1) {
var user = [student.latitude, student.longitude];
console.log('[MapBox.vue] addStudents.forEach : ', student.transport_mode);
console.log('[MapBox.vue] addStudents.forEach.arrayIcon : ', this.arrayIcon);
// TODO : Deterimene student.transport and apply
L.marker( (user), {icon: this.arrayIcon[student.transport_mode]} ).addTo(this.layerGroup);
}
}.bind(this));
},
eraseCurrentMapLayers() {
// this.map.clearLayers();
this.layerGroup.clearLayers();
// this.layerGroup.eachLayer(function (layer) {
// console.log('[StudentMap.vue] eraseCurrentMapLayers : ', layer);
// this.layerGroup.removeLayer();
// }.bind(this));
}
},
watch : {
tuple(newTuple) {
console.log('[StudentMap.vue] : watch.tuple : newTuple');
this.addSchoolAndRadius(newTuple.institute);
this.addStudents(newTuple.students);
}
// institute : function (newInstitute) {
// console.log('[StudentMap.vue] : watch.institute : newInstitute');
// this.addSchoolAndRadius(newInstitute);
// this.addStudents(this.students);
// },
// students : function (newStudents) {
// console.log('[StudentMap.vue] : watch.students : newStudents');
// this.eraseCurrentMapLayers();
// this.addSchoolAndRadius(this.institute);
// this.addStudents(newStudents);
// }
},
created() {
this.arrayIcon = {
"pied" : this.piedIcon,
"velo" : this.veloIcon,
"moto" : this.motoIcon,
"voiture" : this.voitureIcon,
"covoiturage" : this.covoiturageIcon,
"bus" : this.busIcon,
"tram" : this.tramIcon,
"train" : this.trainIcon,
}
this.layerGroup = L.layerGroup().addTo(this.map);
// console.log('[MapBox.vue] created : database size', this.database.length);
// console.log('[MapBox.vue] created : database content', this.database);
this.addSchoolAndRadius(this.tuple.institute);
this.addStudents(this.tuple.students);
}
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment