diff --git a/src/components/Dropdown.vue b/src/components/Dropdown.vue
index f5b41ba9ad3d0163df9e1b714ca34615d034b9e8..0ed967ec07be3ca51a32c2656e9731c682371acb 100644
--- a/src/components/Dropdown.vue
+++ b/src/components/Dropdown.vue
@@ -16,8 +16,9 @@
       @input="handelInput"
       v-on:keyup.enter="select(0)"
       v-model="input"
+      :placeholder="placeholder"
     />
-    <div class="default text">{{ selected }}</div>
+    <!-- <div class="default text">{{ selected }}</div> -->
     <i
       :class="['dropdown icon', { clear: search && selected }]"
       @click="clear"
@@ -42,7 +43,7 @@
 export default {
   name: "Dropdown",
 
-  props: ["options", "selected", "disabled", "search"],
+  props: ["options", "selected", "disabled", "search", "placeholder"],
 
   computed: {
     processedOptions: function () {
@@ -60,6 +61,7 @@ export default {
     return {
       isOpen: false,
       input: "",
+    //  placeholder: "Choisissez une couche",
     };
   },
   methods: {
@@ -67,11 +69,12 @@ export default {
       this.isOpen = !this.isOpen;
     },
     select(index) {
-      this.input = "";
       setTimeout(() => {
         this.isOpen = false; // * quick & dirty, car toggle dropdown est rappelé plusieurs fois aileurs, à creuser...
       }, 500);
       this.$emit("update:selection", this.options[index]);
+      this.input = "";
+     // this.placeholder = this.selected;
     },
     searchOptions(options) {
       return options.filter((el) =>
@@ -96,6 +99,7 @@ export default {
 
   created() {
     window.addEventListener("mousedown", this.clickOutsideDropdown);
+  //  if (this.selected) this.placeholder = this.selected;
   },
 
   beforeDestroy() {
diff --git a/src/components/project/ProjectMappingContextLayer.vue b/src/components/project/ProjectMappingContextLayer.vue
index cb09bd62373a7268e8a66f438ea929beb85fc26f..f28852d0303e574ee6368e0fccffd55c56e26f7a 100644
--- a/src/components/project/ProjectMappingContextLayer.vue
+++ b/src/components/project/ProjectMappingContextLayer.vue
@@ -15,6 +15,7 @@
           :selected="selectedLayer.name"
           :selection.sync="selectedLayer"
           :search="true"
+          :placeholder="placeholder"
         />
         <!-- {{ form.layer.errors }} -->
       </div>
@@ -23,19 +24,29 @@
           class="field three wide {% if form.opacity.errors %} error{% endif %}"
         >
           <label for="opacity">Opacité</label>
-          <input type="number" :value="form.opacity" step="0.01" />
+          <input
+            type="number"
+            v-model.number="layerForm.opacity"
+            step="0.01"
+            @change="updateLayer"
+          />
           <!-- {{ form.opacity.errors }} -->
         </div>
         <div class="field three wide">
           <div class="ui checkbox">
-            <input type="checkbox" :checked="form.queryable" name="queryable" />
+            <input
+              type="checkbox"
+              :checked="layerForm.queryable"
+              name="queryable"
+              @change="updateLayer"
+            />
             <label for="queryable">Requêtable</label>
           </div>
           <!-- {{ form.queryable.errors }} -->
         </div>
       </div>
 
-      <div class="field">
+      <div @click="removeLayer" class="field">
         <div class="ui compact small icon floated button button-hover-red">
           <i class="ui grey trash alternate icon"></i>
           <span>Supprimer cette couche</span>
@@ -57,7 +68,7 @@ export default {
   },
   data() {
     return {
-      form: this.layer,
+      layerForm: null,
       selectedLayer: {
         name: null,
         value: null,
@@ -71,6 +82,42 @@ export default {
         return { name: el.service, value: el.title };
       });
     },
+
+    placeholder: function () {
+      return this.selectedLayer && this.selectedLayer.name
+        ? this.selectedLayer.name
+        : "Choisissez une couche";
+    },
+  },
+  watch: {
+    selectedLayer(newValue, oldValue) {
+      if (newValue !== oldValue) {
+        this.updateLayer()
+      }
+    },
+    layer(newValue, oldValue) {
+      console.log(newValue)
+      if (newValue !== oldValue) {
+        console.log(newValue)
+      }
+    }
+  },
+  methods: {
+    removeLayer() {
+      this.$emit("delete-layer");
+    },
+    updateLayer() {
+      this.$emit("update-layer", this.layerForm);
+    },
+  },
+  created() {
+    this.layerForm = {
+      opacity: "1.00",
+      order: 0,
+      queryable: false,
+      title: "Open street map",
+      ...this.layer, //* spread other values from props and overide previous ones if defined
+    };
   },
   mounted() {
     let selectedLayer = this.layers.find((el) => el.title === this.layer.title);
diff --git a/src/components/project/project_mapping_basemap.vue b/src/components/project/project_mapping_basemap.vue
index c2b291e55921bb6a688957abd248517d2b96156a..3d7e992bf09488411d06cbd213ca1b40862bd74b 100644
--- a/src/components/project/project_mapping_basemap.vue
+++ b/src/components/project/project_mapping_basemap.vue
@@ -7,6 +7,7 @@
         name="basemap-title"
         :value="basemapForm.title"
         required
+        @blur="$emit('update-basemap', basemapForm)"
       />
       <!-- {{ basemapForm.title.errors }} -->
     </div>
@@ -15,12 +16,17 @@
       <div class="ui segments layers-container">
         <ProjectMappingContextLayer
           v-for="layer in basemapForm.layers"
-          :key="layer.dataKey"
+          :key="'layer-' + layer.dataKey"
           :layer="layer"
+          v-on:update-layer="updateLayer"
+          v-on:delete-layer="removeLayer(layer.dataKey)"
         />
       </div>
       <div class="ui buttons">
-        <a class="ui compact small icon left floated button green">
+        <a
+          @click="addLayer"
+          class="ui compact small icon left floated button green"
+        >
           <i class="ui plus icon"></i>
           <span>Ajouter une couche</span>
         </a>
@@ -58,11 +64,9 @@ export default {
   },
   data() {
     return {
+      dataKey: 0,
       basemapForm: {
-        //dataKey: null,
-        //title: "",
-        //layers: [],
-        //id: null,
+        layers: [],
       },
     };
   },
@@ -70,21 +74,43 @@ export default {
     deleteBasemap() {
       this.$store.commit("map/DELETE_BASEMAP", this.basemapForm.dataKey);
     },
-  },
-  computed: {
-  /*   basemapForm: function () {
-      return this.basemap.map((el) => {
-        this.dataKey += 1;
-        return { dataKey: this.dataKey, ...el };
+    mapLayersDataKey() {
+      if (this.basemapForm) {
+        if (!this.basemapForm.layers) this.basemapForm["layers"] = [];
+        this.basemapForm.layers = this.basemapForm.layers.map((el) => {
+          this.dataKey += 1;
+          return { dataKey: this.dataKey, ...el };
+        });
+      }
+    },
+    addLayer() {
+      console.log("addLayer");
+      this.dataKey += 1;
+      this.basemapForm.layers.push({
+        dataKey: this.dataKey,
+        opacity: "1.00",
+        order: 0,
+        queryable: false,
+        title: "Open street map",
       });
-    }, */
+    },
+    removeLayer(dataKey) {
+      this.basemapForm.layers = this.basemapForm.layers.filter(
+        (layer) => layer.dataKey !== dataKey
+      );
+    },
+    updateLayer(payload) {
+      const index = this.basemapForm.layers.findIndex(
+        (el) => el.dataKey === payload.dataKey
+      );
+      console.log("updateLayer", index);
+      this.basemapForm.layers[index] = payload;
+      this.$emit("update-basemap", this.basemapForm); //* update store
+    },
   },
   mounted() {
-    this.basemapForm = this.basemap
-    /* for (const el in this.basemap) {
-      // * find basemap and fill form values
-      this.basemapForm[el] = this.basemap[el];
-    } */
+    this.basemapForm = this.basemap;
+    this.mapLayersDataKey();
   },
 };
 </script>
diff --git a/src/store/modules/map.js b/src/store/modules/map.js
index 480008f915b42c51802443e5d4e0f042cce808d0..d46ee2383dff855c7a4c4e1945aa1f4780ff0919 100644
--- a/src/store/modules/map.js
+++ b/src/store/modules/map.js
@@ -40,18 +40,21 @@ const map = {
   },
   mutations: {
     CREATE_BASEMAP(state, dataKey) {
-      state.basemaps = [...state.basemaps, {dataKey}]
+      state.basemaps = [...state.basemaps, { dataKey }]
     },
     DELETE_BASEMAP(state, dataKey) {
       state.basemaps = state.basemaps.filter(el => el.dataKey !== dataKey)
+    },
+    UPDATE_BASEMAPS(state, basemaps) {
+      state.basemaps = basemaps;
     }
   },
 
   actions: {
     INITIATE_MAP({ state, rootGetters }) {
       const project = rootGetters.project
-      var mapDefaultViewCenter = [37.7749, -122.4194]; // defaultMapView.center;
-      var mapDefaultViewZoom = 13; // defaultMapView.zoom;
+      let mapDefaultViewCenter = [37.7749, -122.4194]; // defaultMapView.center;
+      let mapDefaultViewZoom = 13; // defaultMapView.zoom;
       mapUtil.createMap({
         mapDefaultViewCenter,
         mapDefaultViewZoom,
@@ -70,8 +73,8 @@ const map = {
           JSON.parse(localStorage.getItem("geocontrib-map-options")) || {};
         const basemapIndex =
           mapOptions &&
-          mapOptions[project] &&
-          mapOptions[project]["current-basemap-index"]
+            mapOptions[project] &&
+            mapOptions[project]["current-basemap-index"]
             ? mapOptions[project]["current-basemap-index"]
             : 0;
         layersToLoad = state.baseMaps[basemapIndex].layers;
@@ -85,18 +88,23 @@ const map = {
         layersToLoad.reverse();
       }
       mapUtil.addLayers(layersToLoad, state.serviceMap, state.optionsMap);
- 
+
       // Remove multiple interactions with the map
       mapUtil.getMap().dragging.disable();
       mapUtil.getMap().doubleClickZoom.disable();
       mapUtil.getMap().scrollWheelZoom.disable();
- 
+
       // Add the features
       const featureGroup = mapUtil.addFeatures(state.features);
       if (featureGroup && featureGroup.getLayers().length > 0) {
         mapUtil.getMap().fitBounds(featureGroup.getBounds());
       }
 
+    },
+    SAVE_BASEMAPS({ state }) {
+      const data = JSON.stringify(state.basemaps);
+      console.log("SAVE_BASEMAPS", data);
+      // todo : call axios POST
     }
   }
 }
diff --git a/src/views/feature_type/Feature_type_edit.vue b/src/views/feature_type/Feature_type_edit.vue
index dc25dbda9cb958a4eb69aa3e1d537a25515b67df..c722b3986471e2e2b2ca81060d92f3b421d0237c 100644
--- a/src/views/feature_type/Feature_type_edit.vue
+++ b/src/views/feature_type/Feature_type_edit.vue
@@ -299,7 +299,7 @@ export default {
           .slice(0, -3)
           .replace(",", "")} )`;
       }
-      this.updateStore(); // * initialize form in store in case this.form wasn't modified
+      this.updateStore(); // * initialize form in store in case this.form would not be modified
     }
   },
   /* checkform() {
diff --git a/src/views/project/Project_mapping.vue b/src/views/project/Project_mapping.vue
index 7f1a0a1325da9c46dfb063634cf9284af1230593..7661ec2cdab7026db1e31fbb888427278627fcef 100644
--- a/src/views/project/Project_mapping.vue
+++ b/src/views/project/Project_mapping.vue
@@ -26,10 +26,15 @@
           v-for="basemap in basemapForms"
           :key="basemap.dataKey"
           :basemap="basemap"
+          v-on:update-basemap="updateBasemap2store"
         />
       </div>
 
-      <button type="submit" class="ui teal icon floated button">
+      <button
+        @click="saveChanges"
+        type="button"
+        class="ui teal icon floated button"
+      >
         <i class="white save icon"></i> Enregistrer les changements
       </button>
     </form>
@@ -66,6 +71,17 @@ export default {
       this.$store.commit("map/CREATE_BASEMAP", this.dataKey);
       this.dataKey += 1;
     },
+    updateBasemap2store(payload) {
+      const index = this.basemapForms.findIndex(
+        (el) => el.dataKey === payload.dataKey
+      );
+      console.log("updateBasemap2store", index);
+      this.basemapForms[index] = payload;
+      this.$store.commit("map/UPDATE_BASEMAPS", this.basemapForms);
+    },
+    saveChanges() {
+      this.$store.dispatch("map/SAVE_BASEMAPS");
+    },
   },
 };
 </script>
\ No newline at end of file