Skip to content

Instantly share code, notes, and snippets.

@Lord-Vadim
Last active July 25, 2022 16:14
Show Gist options
  • Select an option

  • Save Lord-Vadim/50d1172321b944793c6c9b00a9bf2a43 to your computer and use it in GitHub Desktop.

Select an option

Save Lord-Vadim/50d1172321b944793c6c9b00a9bf2a43 to your computer and use it in GitHub Desktop.
Интерактивная таблица

Интерактивная таблица

Задание:

  • Средствами Vue.js реализуйте простую накладную — таблицу, содержащую поля "Наименование", "Количество", "Цена". В футере таблицы должна быть строка "Итог".

Требования:

  • Добавление/редактирование позиций должно производиться без перезагрузки страницы и открытия дополнительных модальных окон.
  • Должна быть возможность удалять позиции по одной.
  • Любое изменение в таблице приводит к перерасчету итога.
  • Интерфейс должен отвечать требованиям usability.
  • Валидация и верификация полей НЕ требуется.
  • Сохранение состояния таблицы после перезагрузки страницы НЕ требуется.
  • В качестве языка разработки допускается использовать JavaScript или TypeScript.

Особое внимание стоит обратить на следующие моменты:

  • Код должен быть написан понятно и аккуратно, с соблюдением табуляции и прочих элементов написания, без лишних элементов и функций, не имеющих отношения к функционалу тестового задания, снабжен понятными комментариями.
  • Читабельность и наличие элементарной архитектуры.
  • Чистота и оформление кода не менее важный фактор. Код должен быть написан в едином стиле (желательно в рекомендуемом для конкретного языка). Также к чистоте относятся отсутствие копипаста и дублирования логики.

A Pen by Vadim Epifanov on CodePen.

License.

<!-- Подключаем Vue.js -->
<script src="https://unpkg.com/vue"></script>
<!-- DOM -->
<div id="lvTable">
<table>
<thead> <!-- Заголовок таблицы -->
<tr>
<th>№</th>
<th>Наименование</th>
<th>Количество</th>
<th class="th60">Цена</th>
<th class="th60">Сумма</th>
<th>Х</th>
</tr>
</thead>
<tbody> <!-- Заполнение таблицы -->
<tr v-for="(entry, index) in tbData"> <!-- Цикл по строкам -->
<td style="text-align:center"><b>{{index + 1}}</b></td> <!-- Номер строки -->
<td><input class="th180" :value="entry['name']" v-model="entry['name']" placeholder="Введите наименование" title="Введите наименование товара"></td> <!-- Наименование -->
<td><input class="th60" :value="entry['count']" v-model="entry['count']" type="number" min="0" max="999999" maxlength="6" title="Введите количество товара"></td> <!-- Количество -->
<td><input class="th60" :value="entry['price']" v-model="entry['price']" type="number" min="0" max="999999" maxlength="6" title="Введите цену товара"></td> <!-- Цена -->
<td><input class="th60 thAm" :value="entry['amount']" readonly title="Сумма за товар"></td> <!-- Сумма -->
<td><button class="b20" v-if="tbData.length > 1" v-on:click="fDeleteRow(index)" title="Удалить строку">-</button></td> <!-- Удалить строку (если строк больше одной) -->
</tr>
</tbody>
<tfoot> <!-- футер таблицы -->
<tr>
<td><button class="b20" v-on:click="fAddNewRow" title="Добавить строку в таблицу">+</button></td> <!-- Кнопка добавления стороки в таблицу -->
<td colspan="3" style="text-align:right"><b>ИТОГО:</b></td>
<td colspan="2"><b>{{fCalcPrice}}</b></td> <!-- Итоговая сумма -->
</tr>
</tfoot>
</table>
</div>
var lvTB = new Vue({
el: '#lvTable',
data: {
tbFullPrice: 0, // Итоговая сумма
tbData: [ // Массив строк
{ name: '', count: 1, price: 1, amount: 1 }
]
},
computed: { // Определяем вычисляемое свойство для автоматического пересчета сумм и итога
fCalcPrice: function () { // Расчёт сумм по строкам и общего итога
tbFullPrice = 0;
for (i = 0; i < this.tbData.length; ++i) { // Цикл по строкам таблицы
this.tbData[i].amount = this.tbData[i].count * this.tbData[i].price; // Расчёт суммы в строке
tbFullPrice = tbFullPrice + this.tbData[i].amount; // Расчёт итоговой суммы
}
return tbFullPrice; // Функция возвращает итоговую сумму
}
},
methods: {
fAddNewRow: function () { // Добавить новую строку в таблицу
this.tbData.push({ name: '', count: 1, price: 1, amount: 1 });
},
fDeleteRow: function (index) { // Удалить строку с номером index из таблицы
this.tbData.splice(index, 1);
}
}
});
body, input { /* Настройка шрифта */
font-family: Helvetica Neue, Arial, sans-serif;
font-size: 14px;
color: #106070;
}
table { /* Параметры таблицы */
width: 630px;
margin: auto;
border: 2px solid #308090;
border-radius: 3px;
background-color: #fff;
}
th, td { /* Общие параметры заголовка и строк */
min-width: 30px;
padding: 10px 10px;
}
th { /* Параметры заголовка */
background-color: #308090;
color: #ffffff;
cursor: default;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
td { /* Параметры строк */
background-color: #f3f8f9;
}
.b20 { /* Параметры кнопок */
cursor: pointer;
width: 30px;
margin: 0 calc(50% - 15px);
text-align: center;
}
.th60 { /* Параметры полей ввода */
width: 80px;
margin: 0 calc(50% - 40px);
}
.th180 { /* Параметры полей ввода */
width: 180px;
}
.thAm { /* Параметры поля "Сумма" */
font-weight: bold;
border: 1px solid #a9a9a9;
background-color: #f3f8f9;
}
/* Настройка цвета placeholder */
::-webkit-input-placeholder {color:#a9a9a9}
::-moz-placeholder {color:#a9a9a9}
:-moz-placeholder {color:#a9a9a9}
:-ms-input-placeholder {color:#a9a9a9}
/* Скрытие placeholder когда поле в фокусе */
:focus::-webkit-input-placeholder {color: transparent}
:focus::-moz-placeholder {color: transparent}
:focus:-moz-placeholder {color: transparent}
:focus:-ms-input-placeholder {color: transparent}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment