brotherton-erpnext/erpnext/www/all-products/index.js
Faris Ansari 5f8b358fd4
Website: Product Configurator and Bootstrap 4 (#15965)
- Refactored Homepage with customisable Hero Section
- New Homepage Section to add content on Homepage as cards or using Custom HTML
- Products page at "/all-products" with customisable filters
- Item Configure dialog to find an Item Variant filtered by attribute values
- Contact Us dialog on Item page
- Customisable Item page content using the Website Content field
2019-03-19 11:48:32 +05:30

162 lines
4.5 KiB
JavaScript

$(() => {
class ProductListing {
constructor() {
this.bind_filters();
this.bind_search();
this.restore_filters_state();
}
bind_filters() {
this.field_filters = {};
this.attribute_filters = {};
$('.product-filter').on('change', frappe.utils.debounce((e) => {
const $checkbox = $(e.target);
const is_checked = $checkbox.is(':checked');
if ($checkbox.is('.attribute-filter')) {
const {
attributeName: attribute_name,
attributeValue: attribute_value
} = $checkbox.data();
if (is_checked) {
this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name] || [];
this.attribute_filters[attribute_name].push(attribute_value);
} else {
this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name] || [];
this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name].filter(v => v !== attribute_value);
}
if (this.attribute_filters[attribute_name].length === 0) {
delete this.attribute_filters[attribute_name];
}
} else if ($checkbox.is('.field-filter')) {
const {
filterName: filter_name,
filterValue: filter_value
} = $checkbox.data();
if (is_checked) {
this.field_filters[filter_name] = this.field_filters[filter_name] || [];
this.field_filters[filter_name].push(filter_value);
} else {
this.field_filters[filter_name] = this.field_filters[filter_name] || [];
this.field_filters[filter_name] = this.field_filters[filter_name].filter(v => v !== filter_value);
}
if (this.field_filters[filter_name].length === 0) {
delete this.field_filters[filter_name];
}
}
const query_string = get_query_string({
field_filters: JSON.stringify(if_key_exists(this.field_filters)),
attribute_filters: JSON.stringify(if_key_exists(this.attribute_filters)),
});
window.history.pushState('filters', '', '/all-products?' + query_string);
$('.page_content input').prop('disabled', true);
this.get_items_with_filters()
.then(html => {
$('.products-list').html(html);
})
.then(data => {
$('.page_content input').prop('disabled', false);
return data;
})
.catch(() => {
$('.page_content input').prop('disabled', false);
});
}, 1000));
}
make_filters() {
}
bind_search() {
$('input[type=search]').on('keydown', (e) => {
if (e.keyCode === 13) {
// Enter
const value = e.target.value;
if (value) {
window.location.search = 'search=' + e.target.value;
} else {
window.location.search = '';
}
}
});
}
restore_filters_state() {
const filters = frappe.utils.get_query_params();
let {field_filters, attribute_filters} = filters;
if (field_filters) {
field_filters = JSON.parse(field_filters);
for (let fieldname in field_filters) {
const values = field_filters[fieldname];
const selector = values.map(value => {
return `input[data-filter-name="${fieldname}"][data-filter-value="${value}"]`;
}).join(',');
$(selector).prop('checked', true);
}
this.field_filters = field_filters;
}
if (attribute_filters) {
attribute_filters = JSON.parse(attribute_filters);
for (let attribute in attribute_filters) {
const values = attribute_filters[attribute];
const selector = values.map(value => {
return `input[data-attribute-name="${attribute}"][data-attribute-value="${value}"]`;
}).join(',');
$(selector).prop('checked', true);
}
this.attribute_filters = attribute_filters;
}
}
get_items_with_filters() {
const { attribute_filters, field_filters } = this;
const args = {
field_filters: if_key_exists(field_filters),
attribute_filters: if_key_exists(attribute_filters)
};
return new Promise((resolve, reject) => {
frappe.call('erpnext.portal.product_configurator.utils.get_products_html_for_website', args)
.then(r => {
if (r.exc) reject(r.exc);
else resolve(r.message);
})
.fail(reject);
});
}
}
new ProductListing();
function get_query_string(object) {
const url = new URLSearchParams();
for (let key in object) {
const value = object[key];
if (value) {
url.append(key, value);
}
}
return url.toString();
}
function if_key_exists(obj) {
let exists = false;
for (let key in obj) {
if (obj.hasOwnProperty(key) && obj[key]) {
exists = true;
break;
}
}
return exists ? obj : undefined;
}
});