Skip to content

Commit

Permalink
Merge pull request #7 from yura2015/master
Browse files Browse the repository at this point in the history
8 module
  • Loading branch information
dosandk authored Jun 9, 2021
2 parents ef2e207 + 905bc8a commit 42af13f
Show file tree
Hide file tree
Showing 16 changed files with 2,290 additions and 615 deletions.
1 change: 0 additions & 1 deletion 05-dom-document-loading/1-notification/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,5 @@ export default class NotificationMessage {
this.element = null;
NotificationMessage.activeNotification = null;
}

}

335 changes: 148 additions & 187 deletions 06-events-practice/1-sortable-table-v2/index.js
Original file line number Diff line number Diff line change
@@ -1,215 +1,176 @@
export default class SortableTable {

element = null;
//класс пропорти ( стрелочные функции как обработчики событий) располагать над конструктором
handler = (event) => {

let field = event.target.parentElement.dataset.id;
if(event.target.parentElement.dataset.sortable === 'false') { return; }
if(event.target.parentElement.dataset.order === '')
event.target.parentElement.dataset.order = 'asc'
else if (event.target.parentElement.dataset.order === 'asc') {
event.target.parentElement.dataset.order = 'desc'
} else if (event.target.parentElement.dataset.order === 'desc') {
event.target.parentElement.dataset.order = 'asc';
}
let order = event.target.parentElement.dataset.order;
this.sort(field, order);
}
export default class SortableTable {
element;
subElements = {};

onSortClick = event => {
const column = event.target.closest('[data-sortable="true"]');

const toggleOrder = order => {
const orders = {
asc: 'desc',
desc: 'asc'
};

return orders[order];
};

if (column) {
const { id, order } = column.dataset;
const sortedData = this.sortData(id, toggleOrder(order));
const arrow = column.querySelector('.sortable-table__sort-arrow');

column.dataset.order = toggleOrder(order);

constructor(headersConfig, {
data = [], sorted = {}
} = {}) {
if (!arrow) {
column.append(this.subElements.arrow);
}

this.data = data;
this.headersConfig = Array.from(headersConfig);
this.sorted = sorted;
this.isSortLocally = true;
this.render();
this.subElements.body.innerHTML = this.getTableRows(sortedData);
}
};

constructor(headersConfig = [], {
data = [],
sorted = {
id: headersConfig.find(item => item.sortable).id, // title
order: 'asc'
}
} = {}) {
this.headersConfig = headersConfig;
this.data = data;
this.sorted = sorted;

//this.handler = this.handler.bind(this);
this.addEventListeners();

this.render();
this.initEventListeners();
}

addEventListeners() {
this.element.addEventListener('click', this.handler);
// this.element.removeEventListener('click', this.handler);
getTableHeader() {
return `<div data-element="header" class="sortable-table__header sortable-table__row">
${this.headersConfig.map(item => this.getHeaderRow(item)).join('')}
</div>`;
}

getTabHeader() {
return ` <div data-element="header" class="sortable-table__header sortable-table__row">
${this.headersConfig.map(item => this.getHeaderRow(item.id, item.title, item.sortable)).join('') }
</div>`;
getHeaderRow ({id, title, sortable}) {
const order = this.sorted.id === id ? this.sorted.order : 'asc';

return `
<div class="sortable-table__cell" data-id="${id}" data-sortable="${sortable}" data-order="${order}">
<span>${title}</span>
${this.getHeaderSortingArrow(id)}
</div>
`;
}

getHeaderRow(id, title, sortable) {
return `
<div class="sortable-table__cell" data-id="${id}" data-sortable="${sortable}">
<span>${title}</span>
<span data-element="arrow" class="sortable-table__sort-arrow">
<span class="sort-arrow"></span>
</span>
</div>
`;
getHeaderSortingArrow (id) {
const isOrderExist = this.sorted.id === id ? this.sorted.order : '';

return isOrderExist
? `<span data-element="arrow" class="sortable-table__sort-arrow">
<span class="sort-arrow"></span>
</span>`
: '';
}

getTableBody () {
return `
<div data-element="body" class="sortable-table__body">
${this.getTableRows(this.data)}
</div>
`;
getTableBody(data) {
return `
<div data-element="body" class="sortable-table__body">
${this.getTableRows(data)}
</div>`;
}

getTableRows(data) {
return data.map(item => {
return `
<a href="/products/${item.id}" class="sortable-table__row">
${this.getTableRow(item)}
</a> `;
}).join('');
getTableRows (data) {
return data.map(item => `
<div class="sortable-table__row">
${this.getTableRow(item, data)}
</div>`
).join('');
}

getTableRow(item) {
const cells = this.headersConfig.map(({id, template} ) => {
return {
id,
template
};
});
return cells.map( ( { id, template}) => {
return template
? template (item[id])
: ` <div class="sortable-table__cell">${item[id]}</div> `;
} ).join('');
getTableRow (item) {
const cells = this.headersConfig.map(({id, template}) => {
return {
id,
template
};
});

return cells.map(({id, template}) => {
return template
? template(item[id])
: `<div class="sortable-table__cell">${item[id]}</div>`;
}).join('');
}

getTable() {
return `
<div class="sortable-table">
${this.getTabHeader()}
${this.getTableBody()}
</div>
`;
getTable(data) {
return `
<div class="sortable-table">
${this.getTableHeader()}
${this.getTableBody(data)}
</div>`;
}

render() {
const wrapper = document.createElement('div'); // (*)
wrapper.innerHTML = this.getTable();
const {id, order} = this.sorted;
const wrapper = document.createElement('div');

const sortedData = this.sortData(id, order);

const element = wrapper.firstElementChild;
this.element = element;

this.subElements = this.getSubElements(element);
wrapper.innerHTML = this.getTable(sortedData);

this.sort(this.sorted.id, this.sorted.order);
const element = wrapper.firstElementChild;

this.element = element;
this.subElements = this.getSubElements(element);
}

initEventListeners() {
this.subElements.header.addEventListener('pointerdown', this.onSortClick);
}

sort(field, order) {

if (this.isSortLocally) {
this.sortOnClient(field, order);
} else {
this.sortOnServer(field, order);
}
}

sortOnClient(field, order) {
const sortedData = this.sortData(field, order);
const allColumns = this.element.querySelectorAll(`.sortable-table__cell[data-id]`);
const currentColumn = this.element.querySelector(`.sortable-table__cell[data-id="${field}"]`)

allColumns.forEach(column => {
column.dataset.order = '';
});

currentColumn.dataset.order = order;
this.subElements.body.innerHTML = this.getTableRows(sortedData);
}
sortData(field, order) {
const arr = [...this.data];
const column = this.headersConfig.find(item => item.id === field);
const { sortType } = column;
const directions = {
asc: 1,
desc: -1
};
const direction = directions[order];
return arr.sort( (a,b) => {
switch(sortType) {
case 'namber':
return direction * (a[field] - b[field]);
case 'string':
return direction * (a[field].localeCompare(b[field], ['ru', 'en'], {caseFirst:'upper'}) );
default:
return direction * (a[field] - b[field]);
}
});
}

// getSubElements(element) {
// const elements = element.querySelectorAll('[data-element]');
// return [...elements].reduce((accum,subElement) => {
// accum[subElement.dataset.element] = subElement;
// return accum;
// }, {});
// }

getSubElements(element) {
const result = {};
const elements = element.querySelectorAll('[data-element]');

for(const subElement of elements) {
const name = subElement.dataset.element;
result[name] = subElement;
}
return result;
sortData(id, order) {
const arr = [...this.data];
const column = this.headersConfig.find(item => item.id === id);
const {sortType, customSorting} = column;
const directions = {
asc: 1,
desc: - 1
};
const direction = directions[order];

return arr.sort((a, b) => {
switch (sortType) {
case 'number':
return direction * (a[id] - b[id]);
case 'string':
return direction * a[id].localeCompare(b[id], ['ru', 'en']);
case 'custom':
return direction * customSorting(a, b);
default:
return direction * (a[id] - b[id]);
}
});
}

getSubElements(element) {
const result = {};
const elements = element.querySelectorAll('[data-element]');

for (const subElement of elements) {
const name = subElement.dataset.element;

result[name] = subElement;
}

return result;
}

// getListeners(element) {
// const elements = element.querySelectorAll('[data-id]');
// for(const subElement of elements) {
// const name = subElement.dataset.id; //item.sortable //data-sortable
// subElement.addEventListener('click', this.sort(name, this.sorted.order));
//// if(subElement.dataset.sortable === 'true') { subElement.addEventListener('click', this.sort(name, this.sorted.order));
//// subElement.addEventListener('click', //this.sort(name, this.sorted.order));
//// function(event) { // (1)
//// this.sort(name, this.sorted.order);
//// })
//// }
// }
// }


// elem.dispatchEvent(new CustomEvent("hello", {
// detail: { name: "Вася" }


// onClick(event) {
// let field = event.target.dataset.id;
// // if(!field.)
// field = event.target.closest('div'); //('div');
// if (!field) return;
// field = event.target.dataset.id;
// sort(field, 'asc');

//
// };

remove () {
if(this.element) {
this.element.remove();
}
}

// NOTE: удаляем обработчики событий, если они есть
destroy() {
this.remove();
this.element.removeEventListener('click', this.handler);
this.element = null;
this.subElements = {};
}
}
remove() {
this.element.remove();
}

destroy() {
this.remove();
this.subElements = {};
}

}
Loading

0 comments on commit 42af13f

Please sign in to comment.