]> _ Git - fluidbook-html5.git/commitdiff
wip #7957 @0.25
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Mon, 26 Jan 2026 14:02:03 +0000 (15:02 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Mon, 26 Jan 2026 14:02:07 +0000 (15:02 +0100)
js/libs/fluidbook/cart/fluidbook.cart.newheidi.js [new file with mode: 0644]
style/cart/newheidi.less [new file with mode: 0644]

diff --git a/js/libs/fluidbook/cart/fluidbook.cart.newheidi.js b/js/libs/fluidbook/cart/fluidbook.cart.newheidi.js
new file mode 100644 (file)
index 0000000..d0aad3c
--- /dev/null
@@ -0,0 +1,342 @@
+function FluidbookCartNewHeidi(cart) {
+    this.cart = cart;
+    this.fluidbook = this.cart.fluidbook;
+    this.data = this.fluidbook.settings.basketReferences;
+    this.showAddToCartTooltips = false;
+    this.items = {};
+    this.init();
+}
+
+FluidbookCartNewHeidi.prototype = {
+    init: function () {
+        var $this = this;
+        this.items = this.fluidbook.cache.get('cart', {});
+
+        $(document).on(this.fluidbook.input.changeEvent, '#kimplaycart input[name=qty]', function() {
+            let ref = $(this).data('ref')
+            $this.items['' + ref]['quantity'] = $(this).val();
+            $this.save();
+        })
+
+        $(document).on(this.fluidbook.input.clickEvent, '#open-request', function () {
+            $this.fluidbook.menu.quickCloseView();
+            $this.getContactForm();
+            return false;
+        });
+
+        $(document).on(this.fluidbook.input.clickEvent, '#send-request', function() {
+            $this.sendRequest();
+        })
+
+        $(document).on(this.fluidbook.input.clickEvent, '#kimplay-additem button', function () {
+            let form = $(this).closest('#kimplay-additem');
+            $this.items[''+$(this).data('ref')] = {
+                name: $(form).find('h3').text(),
+                quantity: $(form).find('[name=qty]').val(),
+                comment: $(form).find('[name=comment]').val()
+            };
+
+            $this.fluidbook.tooltip.displayTooltipDuring($this.fluidbook.l10n.__("the item has been added to your cart"), 2500);
+            $this.fluidbook.menu.closeView();
+            $this.save();
+        });
+    },
+
+    emptyCart: function () {
+        this.items = {};
+        this.updateCart();
+        this.save();
+        resize();
+    },
+
+    addToCart: function (ref) {
+        let quantity, comment;
+
+        if (this.items[ref] === undefined) {
+            quantity = 1;
+            comment = '';
+        } else {
+            quantity = this.items[ref].quantity;
+            comment = this.items[ref].comment;
+        }
+
+        let view = `<div id="kimplay-additem">
+        ${this.fluidbook.menu.getCaption("", 'small')}
+            <div class="content">
+                <div class="image"><img src="${this.data[ref].image}" /></div>
+                    <div class="form">
+                        <h3>${this.data[ref].name}</h3>
+                        <div>(réf. ${ref})</div>
+                        <br>
+                        <label>Quantité souhaitée :</label>
+                        <input type="text" name="qty" value="${quantity}"><br><br><br>
+                        <label>Commentaire (facultatif)</label>
+                        <textarea name="comment">${comment}</textarea><br><br><br>
+                        <button data-ref="${ref}">Ajouter à ma sélection</button>
+                    </div>
+                </div>
+            </div>`;
+        this.fluidbook.menu.openCustomView(view, 'cart-kimplay-qty');
+    },
+
+    removeFromCart: function (key) {
+        if(typeof this.items === "object") {
+            delete this.items[key]
+        }else {
+            this.items.splice(key, 1);
+        }
+        this.save();
+    },
+
+    save: function () {
+        this.fluidbook.cache.set('cart', this.getItems());
+        this.updateIcon();
+        this.fluidbook.cart.updateLinks();
+    },
+
+    getItems: function () {
+        return this.items;
+    },
+
+    hasItem: function (ref) {
+        return this.items[ref] !== undefined;
+    },
+
+    getItemsReferences: function () {
+        let res = [];
+        $.each(this.getItems(), function (i, item) {
+            res.push(i);
+        });
+        return res;
+    },
+
+    getItemsNumbers: function () {
+        let res = 0;
+        $.each(this.getItems(), function (i, item) {
+            res++;
+        });
+        return res;
+    },
+
+    getAllQuantities: function () {
+        let res = 0;
+        $.each(this.getItems(), function (i, item) {
+            res += parseInt(item.quantity);
+        });
+        return res;
+    },
+
+    updateCart: function () {
+        if ($('#kimplaycart').length > 0) {
+            $('#kimplaycart .content').html(this.getCartContent());
+        }
+    },
+
+    updateIcon: function () {
+        console.log(this.getItemsNumbers());
+        $(this.fluidbook).trigger('fluidbook.cart.updateIcon', {number: this.getItemsNumbers()});
+    },
+
+    openMenu: function (p1, p2, callback) {
+        this.fluidbook.menu.quickCloseView();
+        return this.openCart(p2, callback);
+    },
+
+    openCart: function (p2, callback) {
+        this._endMenu(this.fluidbook.l10n.__('my selection'), this.getCartContent(), function () {
+            callback();
+        });
+    },
+
+    getCartContent: function () {
+        if (this.getItemsNumbers() == 0) {
+            return '<div class="cart-empty">' + this.fluidbook.l10n.__('your selection is empty') + '</div>';
+        }
+
+        var $this = this;
+        var content = '<table id="kimplaycarttable" class="cart-items" cellpadding="0" cellspacing="0">';
+        content += '<thead>';
+        content += '<tr>';
+        content += '<th></th>';
+        content += '<th class="col-ref">' + this.fluidbook.l10n.__('réf') + '</th>';
+        content += '<th class="col-designation">' + this.fluidbook.l10n.__('désignation') + '</th>';
+        content += '<th class="col-quantite">' + this.fluidbook.l10n.__('quantité') + '</th>';
+        content += '<th class="col-comment">' + this.fluidbook.l10n.__('commentaire') + '</th>';
+        content += '<th class="col-suppr"></th>';
+        content += '</tr></thead>';
+        content += '<tbody>';
+        $.each(this.getItems(), function (i) {
+            var item = $this.items[i];
+            if (item === undefined || item === null) {
+                return;
+            }
+
+            var dataByRef = $this.data[i]
+
+            content += '<tr>';
+
+            if (dataByRef.image) {
+                content += '<td class="image"><img src="' + dataByRef.image + '"/></td>';
+            }
+            else {
+                content += '<td></td>';
+            }
+
+            content += '<td class="reference">' + i + '</td>';
+            content += '<td class="designation"><span>' + item.name + '</span></td>';
+            content += '<td class="quantite"><input type="text" name="qty" value="' + item.quantity + '" data-ref="' + i + '"></td>';
+            content += '<td class="commentaire"><span>' + item.comment + '</span></td>';
+            content += '<td class="delete"><a href="#" data-cart-delete="' + i + '">' + getSpriteIcon('interface-close') + '</a></td>';
+            content += '</tr>';
+        });
+        content += '</tbody>';
+        content += '</table>';
+        content += '<div class="cart-footer">';
+        content += '<div class="fonctions">';
+        content += '<a href="#/closeview" class="completeSelection" role="button" aria-label="' + this.fluidbook.l10n.__('close') + '">' + this.fluidbook.l10n.__('compléter ma sélection') + '</a>';
+        content += '<button class="sendRequest" id="open-request">' + this.fluidbook.l10n.__('envoyer ma demande') + '</button>';
+        content += '</div>';
+        content += '</div>';
+
+        return content;
+    },
+
+
+    _endMenu: function (title, content, callback) {
+        var view = '<div id="kimplaycart">';
+        view += this.fluidbook.menu.getCaption(title, 'small');
+        view += '<div class="content">';
+        view += "" + content;
+        view += '</div>';
+        view += '</div>';
+        this.fluidbook.menu.viewWrap(view, 'cart');
+        callback();
+    },
+
+    getMenuWidth: function () {
+        return 900;
+    },
+
+    parseFloat: function (s) {
+        if (typeof s === 'number') {
+            return s;
+        }
+        if (s === undefined || s === null || s === '') {
+            return 0;
+        }
+        s = s.replace(/\s/g, '');
+        return parseFloat(s);
+    },
+
+    parseInt: function (s) {
+        if (typeof s === 'number') {
+            return Math.round(s);
+        }
+        if (s === undefined || s === null || s === '') {
+            return 0;
+        }
+        s = s.replace(/\s/g, '');
+        return parseInt(s);
+    },
+
+    getContactForm: function() {
+        let view = `<div id="kimplay-sendcart">
+        ${this.fluidbook.menu.getCaption("Mes coordonnées", 'small')}
+            <div class="content">
+                <form id="kimplay-sendcart-form">
+                    <div class="form-group">
+                        <label for="company">Nom de l'entreprise*</label>
+                        <input type="text" id="company" name="company">
+                    </div>
+                    <br>
+                    <div class="form-group">
+                        <label for="name">Nom*</label>
+                        <input type="text" name="name">
+                    </div><br>
+                    <div class="form-group">
+                        <label for="firstname">Prénom</label>
+                        <input type="text" name="firstname">
+                    </div>
+                    <br>
+                    <div class="form-group">
+                        <label for="mail">Email*</label>
+                        <input type="email" name="mail">
+                    </div><br>
+                    <div class="form-group">
+                        <label for="phone">Téléphone*</label>
+                        <input type="text" name="phone">
+                    </div><br>
+                    <div class="form-group">
+                        <label for="address">Adresse</label>
+                        <input type="text" name="address">
+                    </div><br>
+                    <div class="form-group textarea">
+                        <label for="message">Message</label>
+                        <textarea name="message"></textarea>
+                    </div><br>
+                    <span>*Champs obligatoires</span>
+                </form>
+                <div class="cart-footer">
+                    <div class="fonctions">
+                      <a href="#/closeview" class="completeSelection" role="button" aria-label="${this.fluidbook.l10n.__('close')}">${this.fluidbook.l10n.__('compléter ma sélection')}</a>
+                      <button class="sendRequest" id="send-request">${this.fluidbook.l10n.__('envoyer ma demande')}</button>
+                    </div>
+                </div>
+            </div>
+        </div>`;
+        this.fluidbook.menu.openCustomView(view, 'cart-kimplay-sendcart');
+    },
+
+    getConfirm: function () {
+        return `<p class="confirm-content">Votre demande a bien été transmise.
+            Une copie de votre sélection va vous être adressée par email par l'équipe commerciale.
+            <br><br>
+            D’ici là nous restons joignables pour toute
+            question à l’adresse : <a href="mailto:info@cofalu.com">info@cofalu.com</a>
+        </p>`
+    },
+
+    updateCartContent: function (html) {
+       $(".mview .content").html(html)
+    },
+
+    updateTitle: function (title = "Connexion") {
+        $("#mview-dialog-title").text(title)
+    },
+
+    sendRequest: function() {
+        const $this = this;
+        const form = document.getElementById("kimplay-sendcart-form");
+        const formData = new FormData(form);
+        formData.append('cart_items', JSON.stringify($this.getItems()))
+        $.ajax({
+            url: $this.fluidbook.service.getBaseURL(true) + 'kimplay',
+            cache: false,
+            data: formData,
+            processData: false,
+            contentType: false,
+            method: 'post',
+            xhrFields: {withCredentials: true},
+            success: function () {
+                $this.emptyCart();
+                $this.updateTitle('Merci !')
+                $this.updateCartContent($this.getConfirm())
+                $this.fluidbook.resize.resize();
+                $("[data-menu=kimplay-sendcart], #kimplay-sendcart").addClass("confirm")
+            },
+            error: function (xhr, status, error) {
+                let errorsMessage = JSON.parse(xhr.responseText);
+                $this.displayErrors(errorsMessage)
+            },
+        });
+    },
+
+    displayErrors: function (errors) {
+        $(".error").removeClass("error")
+        for (let k in errors['errors']) {
+            $("#kimplay-sendcart input[name=" + k + "]").val("")
+            $("#kimplay-sendcart label[for=" + k + "]").addClass('error')
+            $("#kimplay-sendcart input[name=" + k + "]")[0].placeholder = `${errors['errors'][k][0]}`
+        }
+    },
+};
\ No newline at end of file
diff --git a/style/cart/newheidi.less b/style/cart/newheidi.less
new file mode 100644 (file)
index 0000000..ab56342
--- /dev/null
@@ -0,0 +1,356 @@
+.link a.active[data-cart-ref] {
+  background-color: rgba(0, 255, 0, 0.5);
+}
+
+.mview {
+  font-size: 14px;
+  background: #fff;
+  color: #000;
+  text-transform: uppercase;
+  padding: 0 30px;
+  font-family: 'Metropolis', 'Open-Sans', sans-serif;
+  width: 100% !important;
+
+  &[data-menu=cart-kimplay-qty] {
+    max-width: 614px !important;
+  }
+
+  &[data-menu=cart] {
+    max-width: 1064px !important;
+  }
+
+  &[data-menu=cart-kimplay-sendcart] {
+    max-width: 680px !important;
+    &.confirm {
+      max-width: max-content !important;
+      padding: 41px 50px;
+    }
+  }
+
+  * {
+    letter-spacing: 1px;
+  }
+
+  .caption {
+    height: auto;
+    padding: 30px 0;
+    position: relative;
+
+    h2 {
+      text-transform: uppercase;
+      font-size: 16px;
+      font-weight: bold;
+    }
+
+    a.back.small {
+      background-color: #fff;
+      width: 32px;
+      height: 32px;
+      top: 50%;
+      transform: translateY(-50%);
+      right: 0;
+    }
+  }
+
+  table {
+    font-size: 14px;
+  }
+
+  .fonctions {
+    padding-top: 30px;
+    padding-right: 0;
+    font-size: 14px;
+    font-weight: bold;
+    display: flex;
+    justify-content: flex-end;
+  }
+
+  input, textarea {
+    border: 2px solid #000;
+    padding: 2px;
+    font-size: 16px;
+    font-family: @font;
+  }
+
+  input {
+    width: 70px;
+    text-align: center;
+    background-color: #fff !important;
+  }
+
+  button {
+    border: 0;
+    background-color: #ad1057;
+    color: #fff;
+    text-transform: uppercase;
+    text-align: center;
+    padding: 14px 0;
+    display: block;
+    width: 100%;
+    font-weight: bold;
+    cursor: pointer;
+    font-family: 'Metropolis', 'Open-Sans', sans-serif;
+  }
+
+  .fonctions a.completeSelection {
+    border: 2px solid #ad1057;
+    background-color: #fff;
+    color: #ad1057;
+  }
+
+  .sendRequest {
+    display: inline-block;
+    width: auto;
+    padding: 16px 25px;
+    height: 45px;
+    margin-left: 10px;
+    vertical-align: top;
+  }
+
+  .confirm-content {
+    padding-bottom: 30px;
+    text-align: left;
+    text-transform: initial;
+    line-height: 20px;
+    max-width: 367px;
+  }
+}
+
+.mview[data-menu="cart-kimplay-qty"] {
+  width: 605px;
+  height: 364px;
+
+  .caption {
+    height: 50px;
+    padding: 0;
+    position: initial;
+
+    a.back {
+      top: 18px;
+      right: 4px;
+    }
+  }
+
+  .content {
+    display: flex;
+  }
+
+  .image {
+    display: inline-block;
+    vertical-align: middle;
+    width: 245px;
+
+    img {
+      max-width: 250px;
+      max-height: 300px;
+    }
+  }
+
+  .form {
+    width: 350px;
+    display: inline-block;
+    vertical-align: middle;
+    text-align: left;
+    text-transform: uppercase;
+    padding: 0 0 0 50px;
+
+    h3 {
+      font-size: 16px;
+    }
+
+    textarea {
+      min-width: 100%;
+      width: 100%;
+      max-width: 100%;
+      height: 58px;
+      max-height: 58px;
+      min-height: 58px;
+      padding: 5px;
+    }
+
+    label {
+      margin-bottom: 5px;
+      display: block;
+    }
+  }
+}
+
+#kimplaycart {
+
+  .caption a.back.small {
+    right: -10px;
+  }
+
+  &table {
+    margin-left: 0;
+  }
+
+  table {
+    table-layout: fixed;
+
+    th {
+      text-transform: uppercase;
+      padding: 20px 0;
+      background-color: #ad1057;
+      color: #fff;
+      text-align: left;
+      font-weight: 600;
+      height: 60px;
+
+      &.col-quantite {
+        text-align: center;
+        width: 21%;
+      }
+
+      &.col-suppr {
+        width: 3%;
+      }
+
+      &.col-designation {
+        width: 20%;
+      }
+
+      &.col-comment {
+        width: 32%;
+      }
+    }
+
+    td {
+      padding-left: 0;
+      padding-right: 0;
+      height: 80px;
+      text-transform: initial;
+
+      &.image {
+        width: 130px;
+      }
+
+      &.reference,
+      &.designation,
+      &.commentaire {
+        white-space: normal;
+        word-break: break-word;
+      }
+
+      &.quantite {
+        text-align: center;
+      }
+
+      &.commentaire,&.reference {
+        padding-right: 20px;
+      }
+
+      &.delete {
+        width: 20px;
+
+        a {
+          width: 20px;
+          background: #e30613;
+          text-align: center;
+          height: 20px;
+          color: white;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+        }
+
+        svg {
+          width: 8px;
+        }
+      }
+    }
+  }
+
+  input {
+    margin-bottom: 0;
+  }
+
+  img {
+    height: 75px;
+    width: 100%;
+    object-fit: contain;
+  }
+}
+
+#kimplay-sendcart {
+  width: 100%;
+  max-width: 680px;
+
+  .caption a.back {
+    right: -10px;
+  }
+
+  form {
+    text-align: right;
+    padding: 30px 0 0;
+
+    label {
+
+      &.error {
+        color: #e30613;
+        & + input::placeholder {
+          color: #e30613;
+        }
+      }
+    }
+
+    .form-group {
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      gap: 10px;
+
+      &.textarea {
+        align-items: flex-start;
+
+        label {
+          position: relative;
+          top: 6px;
+        }
+      }
+    }
+
+    input, textarea {
+      width: 320px;
+      text-align: left;
+      padding: 5px 10px;
+      font-size: 14px;
+    }
+
+    textarea {
+      height: 80px;
+      resize: none;
+    }
+  }
+
+  &.confirm {
+
+    .caption {
+      position: initial;
+
+      a.back {
+        right: 16px;
+        top: 30px;
+      }
+    }
+  }
+}
+
+div.link[data-action="basket"] {
+  position: relative;
+
+  span.number {
+    position: absolute;
+    background-color: #e30613;
+    color: #fff;
+    text-align: center;
+    right: -10px;
+    bottom: -10px;
+    width: 20px;
+    height: 20px;
+    border-radius: 50%;
+    font-weight: bold;
+    font-size: 12px;
+    line-height: 20px;
+  }
+}
\ No newline at end of file