Jump to content
Sign in to follow this  
Andrew Becker

Простая админ-панель для викторины - Часть 1

Recommended Posts

Итааак, сегодня мы будем писать админку. Это как на старом форуме, только с ООП и немного обновлённым кодом.

Инструменты:

1. Json-Server - можете найти самостоятельно на просторах гитхаба, или перейти по ссылке >> https://github.com/typicode/json-server <<

2. JS, SASS, HTML - с этим знакомы, наверное, все. Если не с js, так с остальными двумя - точно.

3. Не очень прямые руки (я являюсь переходной формой джуна в мидла, так что говнокод для меня - это плохо, но логично).

Требования:

  • Можно добавить от 2 до 10 ответов
  • Длина ответа должна быть от 1 до 30 символов
  • Длина вопроса - до 300 символов
  • Можно добавить только один вопрос

Что ж, приступим.

Html, тут всё довольно просто, объяснять ничего не буду:

<section class="quiz">
		<div class="section-header">
			<h2>Викторина - вопросы</h2>
		</div>
		<div class="questions"></div>
		<div class="add_question">
			<input type="text" name="question" id="question" placeholder="Введите вопрос (не больше одного)">
			<input type="button" id="add_question" value="Добавить вопрос">
		</div>
		<div class="add_answer">
			<input type="text" name="answer" id="answer" placeholder="Введите варианты ответов (от 2 до 10)">
			<input type="button" value="Добавить ответ" id="add_answer">
		</div>
		<div class="add_to-server">
			<input type="button" id="add_to-server" value="Отправить на сервер">
		</div>
		<div class="error">
			<p></p>
		</div>
	</section>
	<section class="tips">
		<div class="rightSidebar">
			<h4>Правила использования админ-панели викторины:</h4>
			<p>1. Обязательно должен быть один вопрос и минимум два ответа</p>
			<p>2. Первым нужно добавлять вопрос, дальше - ответы</p>
			<p>3. Правильные ответы нужно помечать символом * в конце, например: Лермонтов*</p>
			<input type="button" value="Скрыть" class="hideBtn">
		</div>
	</section>
	<script src="js/adminPanel.js"></script>
	<script src="js/script.js"></script>

Sass, тоже всё довольно просто, но я могу использовать не лучшие решения, а ещё код получился на 172 строки, так что я его сюда скидывать не буду, однако, если хотите увидеть - пишите в комментах, отредактирую статью.

Ииии, js, который я объясню более подробно:

1. Сначала надо инициилизировать все переменные в конструкторе, потом планирую сделать, чтобы параметров стало поменьше:

class AdminPanel {
	constructor (questions, question, answer, addQuestion, addAnswer, addToServer, error, address, MQL, MAL) {
		this.hideBtn = document.querySelector(".hideBtn");
		this.tips = document.querySelector(".tips");
		this.addQuestionBtn = addQuestion;
		this.addToServerBtn = addToServer;
		this.questionsAndAnswers = [];
		this.addAnswerBtn = addAnswer;
		this.questionsCounter = 0;
		this.questions = questions;
		this.question = question;
		this.address = address;
		this.answer = answer;
		this.error = error;
		this.MQL = MQL; //max question length
		this.MAL = MAL; //max answer length
	}

2. Далее, функция вывода вопросов на дисплей, при клике на кнопку "добавить", рядом с полем вопроса - в ней проверяется длина вопроса, пишутся его стили и выводится ошибка с сообщением, если что-то пошло не так:

addQuestion () {
		if (this.question.value.length <= MQL && this.question.value.length > 0) {
			let p = document.createElement("p");
			p.innerText = this.question.value;
			this.questions.appendChild(p);
			this.questionsAndAnswers.push(this.question.value);
			this.addQuestionBtn.disabled = true;
			this.questionsCounter++;
		} else {
			this.error.innerText = "Ошибка: неверная длина вопроса";
			this.error.style.display = "block";
			setTimeout(function () {
				error.style.display = "none";
			}, 700);
		}
		this.question.value = "";
	}

3. Теперь вывод ответов, добавляемых пользователем, проверка их длины, и добавление стилей, а если что-то опять пошло не так - сообщение с ошибкой:

addAnswer () {
		if (this.answer.value.length <= MAL && this.answer.value.length > 0 && this.questionsCounter > 0) {
			let p = document.createElement("p");
			p.classList.add("answer");
			p.innerText = this.answer.value;
			this.questions.appendChild(p);
			this.questionsAndAnswers.push(this.answer.value);
			if(this.questionsAndAnswers.length === 11) this.addAnswerBtn.disabled = true;
		} else if (this.questionsCounter === 0) {
			this.error.innerText = "Ошибка: сначала введите вопрос";
			this.error.style.display = "block";
			setTimeout(function () {
				error.style.display = "none";
			}, 700);
		} else {
			this.error.innerText = "Ошибка: неверная длина ответа";
			this.error.style.display = "block";
			setTimeout(function () {
				error.style.display = "none";
			}, 700);
		}
		this.answer.value = "";
	}

4. Ну и отправка данных на сервер, снова с выводом ошибки, если ответов будет меньше двух (если хотите узнать, почему так записано, то идите на сайт json-server'a, в документации всё подробно написано):

addToServer () {
		if (this.questionsAndAnswers.length > 2) {
			fetch(this.address + "/questions", {
				method: "POST",
				body: JSON.stringify({
					question: this.questionsAndAnswers.shift(),
					answers: this.questionsAndAnswers
				}),
				headers: {
					"Content-type": "application/json; charset=UTF-8"
				}
			})
				.then(function () {
					window.location.reload();
				})
				.catch(console.log);
		} else {
			this.error.innerText = "Ошибка: недостаточно ответов";
			this.error.style.display = "block";
			setTimeout(function () {
				error.style.display = "none";
			}, 700);
		}
	}

5. И метод, который вызывается при клике на кнопку "Закрыть" у подсказок, справа от админки:

hideTips () {
			this.tips.style.display = "none";
	} 

 

А теперь - главная часть, для которой и создавался данный класс:

1. Объявляем переменные, находим в разметке то, что будем использовать.

let	questions = document.querySelector(".questions"),
		addQuestion = document.getElementById("add_question"),
		addToServer = document.getElementById("add_to-server"),
		addAnswer = document.getElementById("add_answer"),
		question = document.getElementById("question"),
		answer = document.getElementById("answer"),
		error = document.querySelector(".error p"),
		address = "http://localhost:3000",
		questionsAndAnswers = [],
		MQL = 300, //max question length
		MAL = 30; //max answer length

2. Создаём экземпляр класса AdminPanel

const adminPanel = new AdminPanel(questions, question, answer, addQuestion, addAnswer, addToServer, error, address, MQL, MAL);

3. И прописываем то, что должно работать при клике на конкретные кнопки.

adminPanel.hideBtn.addEventListener("click", () => adminPanel.hideTips());
adminPanel.addQuestionBtn.addEventListener("click", () => adminPanel.addQuestion());
adminPanel.addAnswerBtn.addEventListener("click", () => adminPanel.addAnswer());
adminPanel.addToServerBtn.addEventListener("click", () => adminPanel.addToServer());

 

Вот такой результат у меня получился:

image.thumb.png.65bc55ef18ed0b15f66c19608f901028.png

 

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

Если есть предложения по улучшению качества кода/каких-то других решений для методов - пишите.

  • Like 1

Share this post


Link to post

Просто для визуала не хватает подсветки синтаксиса в кусках с кодом

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...