var quest = document.getElementById('quest'); //получение доступа к полю с вопросом
var answer = document.getElementById('answer'); //получение доступа к полю с ответом
var fname = ''; //ссылка на файл с результатами
var aver = ''; //ссылка на файл со средним числом
function makeTitle(title) { //вывести название теста
    quest.innerHTML = title;
}
function fileName(name, average) {
    fname = name;
    aver = average;
}
function makeKeyboard(kb = []) { //создание массива клавиатуры
    keyboard = kb;
}
function noConsole() {
    console = false;
}
function needRegister() {
    reg = true;
}

var questNum = 0; //номер вопроса
var questions = []; //вопросы
var answers = []; //вырианты ответа (radio) или текст сразу (input)
var types = []; //типы
var riAn = []; //правильиные ответы
var ass = []; //неправильные ответы
var make = 0; //кол-во вопросов (исп. при создании)
var uRRight = 0; //кол-во правильных ответов
var uRFalse = []; //номера вопросов, где ответ неверный
var iFalse = 0; //кол-во неверных ответов
var keyboard = []; //клавиши клавиатуры

var varQues = []; //для сортировки
var varAns = []; //для сортировки
var varTypes = []; //для сортировки
var varRiAn = []; //для сортировки
var len; //для сортировки
var lenOfLen = []; //для сортировки
var startText = document.getElementById('answer').innerHTML; //текст вначале
var console = true; //выводить правильные ответы в консоль или нет
var reg = false; //учитывать ли регистр

function makeQuest(questionS, answerS, typeS, riAN) { //создать вопрос вначале
    if (typeS == 'radios') {
        riAN = answerS[riAN] //правильный ответ текстом из массива вариантов
        answerS = answerS.sort(() => Math.random() - 0.5); //перемешать варианты у radio
    } else if (typeS == 'checkbox') {
        let len = riAN.length; //кол-во правильных ответов
        let rights = []; //правильные ответы
        rights = riAN; //перенести правильные ответы из riAN в rights
        riAN = []; //очистить riAN
        for (let i = 0; i < len; i++) {
            riAN[riAN.length] = answerS[rights[i]]; //правильные ответы текстом из массива вариантов
        }
        answerS = answerS.sort(() => Math.random() - 0.5); //перемешать варианты
    }
    questions[make] = questionS; //в общий массив (если дальше сортировки не будет, будут использоваться так, как сейчас)
    answers[make] = answerS; //в общий массив (если дальше сортировки не будет, будут использоваться так, как сейчас)
    types[make] = typeS; //в общий массив (если дальше сортировки не будет, будут использоваться так, как сейчас)
    riAn[make] = riAN; //в общий массив (если дальше сортировки не будет, будут использоваться так, как сейчас)
    varQues[make] = questionS; //для след. сортировки
    varAns[make] = answerS; //для след. сортировки
    varTypes[make] = typeS; //для след. сортировки
    varRiAn[make] = riAN; //для след. сортировки
    make++; // +1 вопрос
}
function sort() {
    len = questions.length; //кол-во вопросов - длина
    lenOfLen = []; //от 1 до N вопросов по порядку
    for (let i = 0; i < len; i++) { //заполнение массива
        lenOfLen[i] = i;
    }
    lenOfLen.sort(() => Math.random() - 0.5); //перемешка массива

    for (let i = 0; i < lenOfLen.length; i++) { //новый порядок
        questions[i] = varQues[lenOfLen[i]];
        answers[i] = varAns[lenOfLen[i]];
        types[i] = varTypes[lenOfLen[i]];
        riAn[i] = varRiAn[lenOfLen[i]];
    }
}

function next() { //след. вопрос (нужно, чтобы проверять, что ответ дан)
    if (questNum > 0) { //если это не первый вопрос
        if (types[questNum - 1] == 'radios') {
            let rad = document.getElementsByName('radio');
            for (let i = 0; i < rad.length; i++) {
                if (rad[i].checked) { //если хоть что-то нажато
                    nextQuest();
                }
            }
        } else if (types[questNum - 1] == 'input') {
            let val = document.getElementById('input').value;
            if (val.toLowerCase() != answers[questNum - 1].toLowerCase()) { //если хоть что-то введено
                nextQuest();
            }
        } else if (types[questNum - 1] == 'checkbox') {
            let check = document.getElementsByName('checkbox');
            for (let i = 0; i < check.length; i++) {
                if (check[i].checked) { //если хоть что-то выбрано
                    nextQuest();
                    break;
                }
            }
        } else {
            nextQuest();
        }

    } else {
        nextQuest();
    }
}
function nextQuest() { //след. вопрос (вывод нового вопроса)
    checkAnswer(); //проверка ответа на правильность
    if (questNum < questions.length) {
        quest.innerHTML = questions[questNum] + '   (' + (questNum + 1) + '/' + questions.length + ')'; //вывод вопроса (вопрос + степень прохождения теста)
    } else if (questNum == questions.length) { //если вопросов больше нет
        result(); //вывод результатов
    }
    if (types[questNum] == 'radios') { //проверка типов, чтобы понять, что и как выводить
        radios(answers[questNum]);
    } else if (types[questNum] == 'input') {
        input(answers[questNum]);
    } else if (types[questNum] == 'checkbox') {
        checkbox(answers[questNum]);
    }
    questNum++; //след. вопрос
}

function result() {
    let vAr = uRFalse; //перенос неверных ответов в другую переменную
    uRFalse = '<table border="2"><tr><th>ВОПРОС</th><th>ВАРИАНТ</th><th>ОТВЕТ</th></tr>'; //замена переменной неверных ответов на таблицу
    for (let i = 0; i < vAr.length; i++) { //проход по невернум ответам
        if (types[vAr[i]] == 'input') {
            uRFalse += '<tr><td>' + questions[vAr[i]] + '</td><td>' + ass[i] + '</td><td>' + riAn[vAr[i]] + '</td></tr>';
        } else if (types[vAr[i]] == 'radios') {
            uRFalse += '<tr><td>' + questions[vAr[i]] + '</td><td>' + ass[i] + '</td><td>' + riAn[vAr[i]] + '</td></tr>';
        } else if (types[vAr[i]] == 'checkbox') {
            uRFalse += '<tr><td>' + questions[vAr[i]] + '</td><td>' + ass[i] + '</td><td>' + riAn[vAr[i]] + '</td></tr>';
        }
    }
    uRFalse += '</table>';
    quest.innerHTML = 'Вы набрали ' + uRRight + ' баллов из ' + answers.length + '(' + Math.floor(uRRight / (answers.length / 100)) + '%).'; //результат в поле вопроса
    answer.innerHTML = 'Ошибки в: <br>' + uRFalse; //вывод ошибок в поле ответа
    document.getElementById('next').innerHTML = 'Выбор теста'; //замена текста на кнопке
    document.getElementById('next').onclick = function () { //замена функции кнопики
        toStat(); //функция для перехода к файлу подсчета
    };
}

function radios(strokes) { //если нужно вывести radio
    answer.innerHTML = '';
    for (let i = 0; i < strokes.length; i++) {
        $('#answer').append('<p><label><input type="radio" class="radios" name="radio" id="' + i + '" value="' + strokes[i] + '">' + strokes[i] + '</label></p>');
    }
}
function input(value) { //если нужно вывести input
    answer.innerHTML = '';
    $('#answer').append('<p><input type="text" autofocus="true" autocomplete="off" id="input" value="' + value + '">' + '</p>');
    if (keyboard.length > 0) {  //если есть клавиатура
        let kb = "<table id='keyboardTable' border='1'><tr>"; //создание таблицы
        for (let i = 0; i < keyboard.length; i++) { //добавление ячеек с символами
            kb += `<td><button onclick="pasteTxt('${keyboard[i]}')">${keyboard[i]}</button></td>`;
        }
        kb += "</tr></table>";
        $('#answer').append(kb); //вставка таблицы
    }
}
function checkbox(strokes) { //если нужно вывести checkbox
    answer.innerHTML = '';
    for (let i = 0; i < strokes.length; i++) {
        $('#answer').append('<p><label><input type="checkbox" value="' + strokes[i] + '" id="' + i + '" class="checkbox" name="checkbox">' + strokes[i] + '</label></p>');
    }
}

function checkAnswer() { //функция проверки ответа на правильность
    if (questNum > 0) { //если это не первый вопрос
        if (types[questNum - 1] == 'radios') { //для radio
            let rad = document.getElementsByName('radio'); //выбор всех radio
            for (let i = 0; i < rad.length; i++) { //проверка каждого
                if (rad[i].checked) { //если нажат
                    if (rad[i].value == riAn[questNum - 1]) { //если нажат верный
                        uRRight++; // + к прав. ответам
                    } else { //иначе
                        ass[iFalse] = rad[i].value; //запись неверного варинта ответа
                        if (console) console.log(riAn[questNum - 1]); //вывод в консоль правильного ответа
                        uRFalse[iFalse] = questNum - 1; //запись номера вопроса
                        iFalse++; // + к неправильным ответам
                    }
                }
            }
        } else if (types[questNum - 1] == 'input') { //для input
            let val = document.getElementById('input').value;
            val = val.replace(/ +/g, ' ').trim(); //убирает лишние пробелы
            if (!reg) val = val.toLowerCase(); //если регистр не учитывается
            let rn = riAn[questNum - 1];
            if (!reg) rn.toLowerCase(); //если регистр не учитывается
            if (val == rn) { //если введено верно
                uRRight++; // + к правильным ответам
            } else { //иначе
                uRFalse[iFalse] = questNum - 1; //запись номера вопроса
                ass[iFalse] = val; //запись неверного ответа
                if (ass[iFalse] == undefined) { //если текста нет
                    ass[iFalse] = '';
                }
                if (console) console.log(riAn[questNum - 1]); //вывод в консоль правильного ответа
                iFalse++; //+ к неправильным ответам
            }
        } else if (types[questNum - 1] == 'checkbox') { //для checkbox (нет вывода в консоль)
            let check = document.getElementsByName('checkbox'); //выбор всех checkbox
            let rightAnswers = []; //массив с ответами
            for (let i = 0; i < check.length; i++) { //проход по всем checkbox
                if (check[i].checked) { //если нажато
                    for (let j = 0; j < riAn[questNum - 1].length; j++) { //проверка на правильность
                        if (check[i].value == riAn[questNum - 1][j]) { //если в массиве пр. ответов есть такое значение
                            rightAnswers[rightAnswers.length] = check[i].value; //записать
                        }
                    }
                }
            }
            riAn[questNum - 1].sort(); //одинаковое расположение элементов массивов
            rightAnswers.sort(); //одинаковое расположение элементов массивов
            if (JSON.stringify(riAn[questNum - 1]) == JSON.stringify(rightAnswers)) { //если массивы совпадают
                uRRight++; // + к правильным ответам
            } else { //иначе
                uRFalse[iFalse] = questNum - 1; //запись номера вопроса
                ass[iFalse] = rightAnswers; //запись неверного ответа
                if (ass[iFalse] == undefined) { //если текста нет
                    ass[iFalse] = '';
                }
                iFalse++; // + к неправильным ответам
            }
        }
    }
}

function pasteTxt(txt) { //вставка текста в input из доп. клавиатуры
    if (document.getElementById('input') != undefined) {
        document.getElementById('input').value += txt;
    }
}

function toStat() { //переход к файлу подсчета 
    let date = new Date(Date.now() + 2e3); //удалить cookies через 2 сек.
    date = date.toUTCString(); //в строку
    if (Math.floor(uRRight / (answers.length / 100)) == 99) { //если ошибок нет
        document.cookie = `result = 100;  expires=${date}; path=/`;
    } else { //если ошибки есть
        document.cookie = `result = ${Math.floor(uRRight / (answers.length / 100))}; expires=${date}; path=/`; //рассчитать результат
    }
    document.cookie = `table = ${uRFalse};  expires=${date}; path=/`; //cookie с таблицей
    document.cookie = `file = ${fname}; expires=${date}; path=/`; //cookie с ссылкой на файл рез-тов
    document.cookie = `average = ${aver}; expires=${date}; path=/`; //cookie с ссылкой на среднее значение
    document.location.href = '../статистика/statistics.php'; //переход к файлу
}

$('body').keydown(function (event) { //горячие клавиши
    switch (event.keyCode) {
        case 13: //enter
            if (document.getElementById('next').innerHTML == 'Выбор теста') {
                toStat();
            } else {
                next();
            }
            break;

        case 49: //для radio первый элемент
            if (document.getElementById('0') !== null)
                document.getElementById('0').checked = true
            break;

        case 50: //для radio второй элемент
            if (document.getElementById('1') !== null)
                document.getElementById('1').checked = true
            break;

        case 51: //для radio третий элемент
            if (document.getElementById('2') !== null)
                document.getElementById('2').checked = true
            break;
        case 52: //для radio четвертый элемент
            if (document.getElementById('3') !== null)
                document.getElementById('3').checked = true
            break;
        case 53: //для radio пятый элемент
            if (document.getElementById('4') !== null)
                document.getElementById('4').checked = true
            break;

        default:
            break;
    }
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.