Практикум №6 (продолжение)

Описание задания вы всегда можете посмотреть под спойлером.


Задание 5



В данной задаче нам необходимо реализовать следующий функционал нашей программы: при вводе пользователем данных(через запятую) в блоке статей возможного дохода (в левой части программы), они должны одновременно выводиться в правой части программы в графе "Дополнительный доход".

При вводе данных в поле инпута возникает непосредственно событие input, когда мы выходим из инпута и кликаем за его пределами, возникает уже событие change.

Найдём наш инпут, в который пользователь будет вводить статьи возможного дохода:

Код

  <div class="choose-income-label">Введите статьи возможного дохода через запятую</div>
  <input class="choose-income" type="text" id="income">


как видим, он имеет класс choose-income, и этот инпут мы сохраняли с вами ранее в переменной incomeItem

Код

incomeItem = document.querySelector('.choose-income')


Будем работать с этой переменной. Добавляем ей обработчик события, при этом событие мы будем использовать, в отличие от предыдущих вариантов, не click, а input:

Код

incomeItem.addEventListener('input', function() {

});


в объекте appData в chooseIncome мы уже написали ранее готовый код функции, теперь нам лишь остаётся просто взять его оттуда и вставить в коллбэк-функцию нашего обработчика.
Итак, берём код из объекта appData:

Код

  chooseIncome: function () {
  let items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  while (typeof (items) != 'string' || typeof (items) == null || items == '') {
  items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  }
  appData.income = items.split(', ');
  appData.income.push(prompt('Может быть что-то еще?', ''));
  appData.income.sort();

  appData.income.forEach(function (itemmassive, i) {
  alert('Способы дополнительного заработка: ' + (i + 1) + ' - ' + itemmassive);
  });
  }


мы возьмём только часть кода, вот эту (остальное можно просто удалить):

Код

  let items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  appData.income = items.split(', ');


и вставим в функцию нашего обработчика:

Код

incomeItem.addEventListener('input', function() {
  let items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  appData.income = items.split(', ');
});


ну и, конечно, здесь необходима небольшая доработка кода: для начала из переменной items мы удалим prompt(), поскольку данные от пользователя мы уже будем получать не через всплывающие окна, а через непосредственно интерфейс программы (а именно, через инпут).
Поэтому вместо prompt() мы пропишем incomeItem.value

Код

incomeItem.addEventListener('input', function() {
  let items = incomeItem.value;
  appData.income = items.split(', ');
});


ну и осталось добавить строку кода, которая будет выводить данные в графу "Дополнительный доход" в правой части программы.
У этого блока div(а данные будут выводиться именно в блоке div) есть класс income-value:

Код

  <div class="income">Дополнительный доход: </div>
  <div class="income-value"></div>


блок с этим классом у нас сохранён в переменной incomeValue:

Код

incomeValue = document.getElementsByClassName('income-value')[0]


с помощью уже знакомой вам команды textContent реализуем нашу задачу:

Код

incomeItem.addEventListener('input', function() {
  let items = incomeItem.value;
  appData.income = items.split(', ');
  incomeValue.textContent = appData.income;
});




Задание 6



Так как по условию задания расчёт должен быть возможен только при активном чекбоксе, то и начнём мы с него.

Данный чекбокс(а точнее это инпут, имеющий type="checkbox") имеет идентификатор savings

Код

  <div class="checksavings">Есть ли накопления:  
  <input id="savings" type="checkbox" />
  </div>


и сохранён у нас ранее в переменной checkSavings

Код

checkSavings = document.querySelector('#savings')


берём эту переменную и добавляем к ней обработчик события click:

Код

checkSavings.addEventListener('click', function() {

});


внутри функции мы прописываем управляющую инструкцию:

Код

checkSavings.addEventListener('click', function() {
  if(appData.savings == true) {
  appData.savings = false;
  } else {
  appData.savings = true;
  }
});


смысл её состоит в том, что когда мы кликаем на чекбоксе, тем самым выделяя его, наш savings в объекте appData становится true, при повторном клике(выделение снимается) savings становится опять false.
Изначально, в объекте appData, для savings, как вы помните, установлено значение false.

Код

let appData = {
  expenses: {},
  optionalExpenses: {},
  income: [],
  savings: false


следующее, что нам необходимо реализовать в этом задании, это расчёт накоплений пользователя за месяц и за год, при условии, что он ввёл соответствующие данные в поля: "Сумма" и "Процент"
Найдём их в коде страницы:

Код

  <label for="sum">Сумма</label>
  <input class="choose-sum" id="sum" type="text">
  <label for="percent">Процент</label>
  <input class="choose-percent" id="percent" type="text">


эти два инпута у нас сохранены в переменных sumValue и percentValue

Код

  sumValue = document.querySelector('.choose-sum'),
  percentValue = document.querySelector('.choose-percent')


берём переменную sumValue и к ней цепляем обработчик события input:

Код

sumValue.addEventListener('input', function() {

});


а далее мы пропишем код внутри нашей каллбэк-функции:

Код

sumValue.addEventListener('input', function() {
  if(appData.savings == true) {
  let sum = +sumValue.value,
  percent = +percentValue.value;

  appData.monthIncome = sum/100/12*percent;
  appData.yearIncome = sum/100*percent;

  monthSavingsValue.textContent = appData.monthIncome.toFixed(1);
  yearSavingsValue.textContent = appData.yearIncome.toFixed(1);

  }
});


давайте разбираться, что это за код тут понаписан.
Сначала идёт условие, в котором говорится, что если наш чекбокс активен(то есть в нём стоит галочка), соответственно в объекте appData у savings стоит значение true, то запускается следующий механизм: создаются две новые переменные sum и percent, в которые сохраняются те значения, что вводит пользователь в поля инпутов "Сумма" и "Процент".

Унарные плюсы при этом переводят строковые значения, возвращаемые value, обратно в числовые. Далее, в наш объект appData записываются две новые пары "ключ: значение", в которых содержатся значения рассчитанных сумм накоплений за день и за год.

Последние две строки в этом блоке кода выводят значения рассчитанных сумм накоплений за месяц и за год в правую часть программы в графы "Накопления за 1 месяц" и "Накопления за 1 год" соответственно.

Тоже самое мы можем прописать и для percentValue:

Код

percentValue.addEventListener('input', function() {
  if(appData.savings == true) {
  let sum = +sumValue.value,
  percent = +percentValue.value;

  appData.monthIncome = sum/100/12*percent;
  appData.yearIncome = sum/100*percent;

  monthSavingsValue.textContent = appData.monthIncome.toFixed(1);
  yearSavingsValue.textContent = appData.yearIncome.toFixed(1);

  }
});


глобальный же объект appData, после того, как из него мы удалили весь лишний код, будет выглядеть так:

Код

let appData = {
  expenses: {},
  optionalExpenses: {},
  income: [],
  savings: false
};


Полный код нашего скрипта (нашей программы):

Код

let startBtn = document.getElementById('start'),
  budgetValue = document.getElementsByClassName('budget-value')[0],
  dayBudgetValue = document.getElementsByClassName('daybudget-value')[0],
  levelValue = document.getElementsByClassName('level-value')[0],
  expensesValue = document.getElementsByClassName('expenses-value')[0],
  optionalExpensesValue = document.getElementsByClassName('optionalexpenses-value')[0],
  incomeValue = document.getElementsByClassName('income-value')[0],
  monthSavingsValue = document.getElementsByClassName('monthsavings-value')[0],
  yearSavingsValue = document.getElementsByClassName('yearsavings-value')[0],

  expensesItem = document.getElementsByClassName('expenses-item'),
  expensesBtn = document.getElementsByTagName('button')[0],
  optionalExpensesBtn = document.getElementsByTagName('button')[1],
  countBtn = document.getElementsByTagName('button')[2],
  optionalExpensesItem = document.querySelectorAll('.optionalexpenses-item');

incomeItem = document.querySelector('.choose-income'),
  checkSavings = document.querySelector('#savings'),
  sumValue = document.querySelector('.choose-sum'),
  percentValue = document.querySelector('.choose-percent'),
  yearValue = document.querySelector('.year-value'),
  monthValue = document.querySelector('.month-value'),
  dayValue = document.querySelector('.day-value');

let money, time;

expensesBtn.disabled = true;
optionalExpensesBtn.disabled = true;
countBtn.disabled = true;

startBtn.addEventListener('click', function () {
  time = prompt('Введите дату в формате YYYY-MM-DD', '');
  money = +prompt('Ваш бюджет на месяц?', '');

  while (isNaN(money) || money == null || money == '') {
  money = +prompt('Введите ваш бюджет на месяц', '');
  }

  appData.budget = money;
  appData.timeData = time;
  budgetValue.textContent = money.toFixed();
  yearValue.value = new Date(Date.parse(time)).getFullYear();
  monthValue.value = new Date(Date.parse(time)).getMonth() + 1;
  dayValue.value = new Date(Date.parse(time)).getDate();

  expensesBtn.disabled = false;
  optionalExpensesBtn.disabled = false;
  countBtn.disabled = false;
});

expensesBtn.addEventListener('click', function () {
  let sum = 0;
  for (let i = 0; i < expensesItem.length; i++) {
  let a = expensesItem[i].value,
  b = expensesItem[++i].value;

  if (typeof (a) != null && typeof (b) != null && a != '' && b != '' && a.length < 50) {

  appData.expenses[a] = b;
  sum += +b;
  } else {
  i--;
  }

  }
  expensesValue.textContent = sum;
});

optionalExpensesBtn.addEventListener('click', function() {
  for (let i = 0; i < optionalExpensesItem.length; i++) {
  let questionOptExpenses = optionalExpensesItem[i].value;

  appData.optionalExpenses[i] = questionOptExpenses;
  optionalExpensesValue.textContent += appData.optionalExpenses[i] + ' ';
  }
});

countBtn.addEventListener('click', function() {
  appData.moneyPerDay = ( (appData.budget - +expensesValue.textContent) / 30).toFixed(2);
  dayBudgetValue.textContent = appData.moneyPerDay;

  if (appData.moneyPerDay < 500) {
  levelValue.textContent = 'Низкий уровень дохода';
  } else if (appData.moneyPerDay > 500 && appData.moneyPerDay < 1000) {
  levelValue.textContent = 'Средний уровень дохода';
  } else if (appData.moneyPerDay > 1000) {
  levelValue.textContent = 'Высокий уровень дохода';
  } else {
  levelValue.textContent = 'Что-то пошло не так';
  }
});

incomeItem.addEventListener('input', function() {
  let items = incomeItem.value;
  appData.income = items.split(', ');
  incomeValue.textContent = appData.income;
});

checkSavings.addEventListener('click', function() {
  if(appData.savings == true) {
  appData.savings = false;
  } else {
  appData.savings = true;
  }
});

sumValue.addEventListener('input', function() {
  if(appData.savings == true) {
  let sum = +sumValue.value,
  percent = +percentValue.value;

  appData.monthIncome = sum/100/12*percent;
  appData.yearIncome = sum/100*percent;

  monthSavingsValue.textContent = appData.monthIncome.toFixed(1);
  yearSavingsValue.textContent = appData.yearIncome.toFixed(1);

  }
});

percentValue.addEventListener('input', function() {
  if(appData.savings == true) {
  let sum = +sumValue.value,
  percent = +percentValue.value;

  appData.monthIncome = sum/100/12*percent;
  appData.yearIncome = sum/100*percent;

  monthSavingsValue.textContent = appData.monthIncome.toFixed(1);
  yearSavingsValue.textContent = appData.yearIncome.toFixed(1);

  }
});

let appData = {
  expenses: {},
  optionalExpenses: {},
  income: [],
  savings: false
};


Протестировать работу программы можно на этой странице.

Ссылка на GitHub

Комментарии к материалу: