1/** 2 * Catalog list actions 3 */ 4AimeosCatalogLists = { 5 6 /** 7 * Shows the basket after submitting the form 8 * 9 * @param DomNode form Form DOM element 10 */ 11 async showBasket(form) { 12 13 await fetch(form.getAttribute("action"), { 14 body: new FormData(form), 15 method: 'POST' 16 }).then(response => { 17 return response.text(); 18 }).then(data => { 19 Aimeos.createContainer(AimeosBasket.updateBasket(data)); 20 }); 21 }, 22 23 24 /** 25 * Marks products as pinned 26 */ 27 setPinned() { 28 29 $('.catalog-list-items').each((idx, el) => { 30 $('.product .btn-pin', el).removeClass('active'); 31 32 for(id in $(el).data('pinned')) { 33 $('.product[data-prodid="' + id + '"] .btn-pin', el).addClass('active'); 34 } 35 }); 36 }, 37 38 39 /** 40 * Add to basket 41 */ 42 onAddBasket() { 43 44 $(document).on("click", ".catalog-list-items .product .btn-action", ev => { 45 const target = $(ev.currentTarget).closest(".product"); 46 ev.preventDefault(); 47 48 Aimeos.createOverlay(); 49 50 if($(".catalog-list-items:not(.list) .basket .items-selection .selection li, .catalog-list-items:not(.list) .basket .items-attribute .selection li", target).length) { 51 const node = target.clone(); 52 53 $("[id]", node).each((idx, el) => { 54 el.setAttribute("id", el.getAttribute("id") + '-2'); 55 }); 56 57 $("[for]", node).each((idx, el) => { 58 el.setAttribute("for", el.getAttribute("for") + '-2'); 59 }); 60 61 node.on("click", ".btn-action", (ev) => { 62 if(AimeosCatalog.checkVariants(ev.currentTarget)) { 63 this.showBasket($(ev.currentTarget).closest("form.basket")[0]); 64 } 65 ev.stopPropagation(); 66 ev.preventDefault(); 67 }); 68 69 Aimeos.createContainer($('<div class="catalog-list catalog-list-items list">').append(node)); 70 return; 71 } 72 73 this.showBasket($("form.basket", target)[0]); 74 }); 75 }, 76 77 78 /** 79 * Enables infinite scroll if available 80 */ 81 async onScroll() { 82 83 if($('.catalog-list-items').data('infiniteurl')) { 84 const scroll = async function() { 85 86 const list = $('.catalog-list-items'); 87 const infiniteUrl = list.data('infiniteurl'); 88 89 if(infiniteUrl && list.length && list[0].getBoundingClientRect().bottom < window.innerHeight * 3) { 90 list.data('infiniteurl', ''); 91 92 await fetch(infiniteUrl).then(response => { 93 return response.text(); 94 }).then(data => { 95 const nonce = $('script.items-stock', document)?.attr('nonce'); 96 const nextPage = $('<html/>').html(data); 97 const newList = $('.catalog-list-items', nextPage); 98 const ids = newList.data('pinned') || {}; 99 100 $('.product', newList).each((idx, node) => { 101 ids[node.dataset.prodid] ? $('.btn-pin', node).addClass('active') : null; 102 list.append(node); 103 }); 104 105 $('script.items-stock', nextPage).each((idx, node) => { 106 node.setAttribute('nonce', nonce); 107 $(document.head).append(node); 108 }); 109 110 list.data('infiniteurl', newList.data('infiniteurl')); 111 $(window).trigger('scroll'); 112 Aimeos.loadImages(); 113 }); 114 } 115 }; 116 117 $(window).on('scroll', scroll); 118 scroll(); 119 } 120 }, 121 122 123 /** 124 * Add products to pinned list 125 */ 126 onPin() { 127 128 $("body").on("click", ".catalog-list-items .product .btn-pin", async ev => { 129 130 const el = $(ev.currentTarget); 131 const url = el.hasClass('active') ? el.data('rmurl') : el.attr('href'); 132 133 if(url) { 134 const form = new FormData(); 135 const csrf = el.closest('form').find('.csrf-token'); 136 137 form.append(csrf.attr('name'), csrf.attr('value')); 138 el.toggleClass('active'); 139 140 await fetch(url, { 141 method: 'POST', 142 body: form 143 }).then(response => { 144 return response.text(); 145 }).then(data => { 146 const doc = $('<html/>').html(data); 147 const pinned = $(".catalog-session-pinned", doc); 148 149 if(pinned.length) { 150 $('.catalog-session-pinned').replaceWith(pinned); 151 } 152 }); 153 154 return false; 155 } 156 }); 157 }, 158 159 160 /** 161 * Initializes the catalog list actions 162 */ 163 init() { 164 if(this.once) return; 165 this.once = true; 166 167 this.setPinned(); 168 this.onAddBasket(); 169 this.onScroll(); 170 this.onPin(); 171 } 172}; 173 174 175$(function() { 176 AimeosCatalogLists.init(); 177});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.