Содержание:

  • Введение
  • Почему именно SurveyJS?
  • Создание опроса
  • Настройка проекта Angular
  • Установка и настройка SurveyJS
  • Создание опроса удовлетворенности сотрудников
  • Настройка базы данных MongoDB
  • Сохранение результатов в коллекции MongoDB

Введение

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

В первом случае они показывают, что начальство принимает во внимание интересы подопечных и ценит их. Таким образом, повышается моральный дух и растет удовлетворенность работой.

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

Удовлетворенные сотрудники отличаются высокой продуктивностью. Они по-настоящему вовлечены в работу, что приводит к повышению создаваемой коммерческой ценности. И наоборот, если в организации есть неудовлетворенные сотрудники, прибыльность бизнеса будет падать. Так что полезно всегда быть в курсе, и в этом помогут внутренние опросы работников.

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

  • Angular: фреймворк для проектирования приложений и платформа для создания одностраничных приложений.
  • SurveyJS: бесплатный конструктор форм на JavaScript с открытым исходным кодом (ссылка на Github), который упрощает создание форм на собственном сервере.
  • MongoDB: документная база данных. Классифицируется как база данных типа NoSQL. MongoDB использует JSON-подобные документы с опциональными схемами.

Кто-то может возразить: хоть Angular и является предпочтительным корпоративным фреймворком, с его помощью разработчику не так-то легко создавать анкеты, которые хорошо масштабируются при наличии в них множества вопросов. Но в этой статье мы покажем элегантный способ разработки корпоративного опроса с помощью Angular, в котором не нужно использовать пары ngIf и ng-template для каждого вопроса, а также лишние привязки.

На помощь нам придет SurveyJS. С помощью этой библиотеки с открытым исходным кодом можно упростить создание форм и работу с ними в динамическом режиме. Рассмотрим это более подробно ниже, а пока разберемся, какие вопросы мы поместим в анкету.

Они подробно указаны в таблице ниже:

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

В следующем разделе мы рассмотрим, почему используем SurveyJS в качестве инструмента для создания опроса.

Почему именно SurveyJS?

Следующие доводы красноречиво показывают, почему стоит использовать SurveyJS в сочетании с Angular для решения этой задачи, вместо того чтобы разрабатывать формы/опросы вручную с помощью примитивов Angular.

  • Создание опросов на собственном сервере. Мы можем защитить данные и хранить их в выбранной базе данных, а не использовать сторонние онлайн-сервисы, как, например, Google Формы, которые хранят результаты в файлах Google Таблиц.
  • Возможность легко создавать сложные опросы, включающие условную логику и ветвление. Мы также можем делать формы более развернутыми и адаптированными ко многим случаям использования без необходимости встраивать дополнительный JavaScript.
  • Создание динамических форм, которые легко обновлять. Формы SurveyJS основаны на принципе data-first, поэтому нужно просто обновить модель JSON-формы.
  • Включение различных компонентов ввода с валидацией, таких как многострочные вводы, чекбоксы, выпадающие окна, матричные анкеты, загрузка файлов и многое другое, что дает большую гибкость при разработке форм и опросов.
  • Создание многоязычных опросов. Мы можем просто создать один общий опрос вместо множества анкет для каждого отдельного языка.

И это еще не все преимущества. SurveyJS дает возможность либо использовать имеющиеся компоненты форм, либо настроить все с помощью CSS, чтобы эти компоненты были более индивидуальными и отвечали корпоративным интересам.

Теперь приступим к самому процессу.

Создание опроса

Шаг 1. Настройка проекта Angular

Сначала необходимо убедиться в том, что у нас установлена последняя версия Angular CLI.

npm install -g @angular/cli

Узнать больше об Angular CLI и найти подробную информацию об установке можно здесь.

После установки Angular CLI создаем приложение Angular с помощью команды ng, как показано ниже:

ng new employee-satisfaction-survey-app

Эта команда создаст приложение со следующей структурой:

Структура приложения

Шаг 2. Установка и настройка SurveyJS

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

npm install survey-angular-ui — save

После установки SurveyJS приступаем к настройке.

Шаг 2.1. Ссылка на таблицы стилей пользовательского интерфейса SurveyJS в файле angular.json

SurveyJS поставляется с 2 таблицами стилей: Modern и DefaultV2 (см. на рисунке ниже).

Темы пользовательского интерфейса SurveyJS
{
“$schema”: “./node_modules/@angular/cli/lib/config/schema.json”,
“version”: 1,
“newProjectRoot”: “projects”,
“projects”: {
“employee-satisfaction-survey-app”: {
“projectType”: “application”,
“schematics”: {},
“root”: “”,
“sourceRoot”: “src”,
“prefix”: “app”,
“architect”: {
“build”: {
“builder”: “@angular-devkit/build-angular:browser”,
“options”: {

“styles”: [
“src/styles.css”,
“node_modules/survey-core/defaultV2.min.css”,
// Modern theme
“node_modules/survey-core/modern.min.css”
],
“scripts”: []
},
“configurations”: {

},
“defaultConfiguration”: “production”
},
“serve”: {

},
“extract-i18n”: {

},
“test”: {

}
}
}
}
}

Шаг 2.2. Применение в компоненте приложения темы, на которую дана ссылка

Для этого воспользуемся методом StyleManager.applyTheme(theme-name); и передадим название темы в качестве параметра (“modern” или “defaultV2”).

import { StylesManager } from “survey-core”;

StylesManager.applyTheme("modern");

Шаг 2.3. Создание модели опроса

Вот что говорится в документации SurveyJS:

Модель описывает макет и содержимое опроса. Простейшая модель опроса содержит один или несколько вопросов без модификации макета.

Модель состоит из объекта JSON, в котором объявлены вопросы и их типы. Этот объект JSON называется схемой.

Например, эта простая схема содержит один вопрос, объявленный в массиве элементов:

const surveyJson = {
elements: [ // каждый элемент содержит вопрос
{
name: ‘Name’,// имя поля
title: ‘Enter your full name:’,// название поля
type: ‘text’,// тип поля
},
],
};

Затем создадим модель, передав схему в конструктор Model, как показано в приведенном ниже коде:

import { Component, OnInit } from ‘@angular/core’;
import { Model, StylesManager } from “survey-core”;

StylesManager.applyTheme('modern');

const surveyJson = {
elements: [
{
name: 'Name',
title: 'Enter your full name:',
type: 'text',
},
],
};

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
title = 'employee-satisfaction-survey-app';
surveyModel: Model | undefined;

ngOnInit() {
const survey = new Model(surveyJson);
this.surveyModel = survey;
}
}

Шаг 2.4. Добавление модуля SurveyJS в app.module.ts 

Чтобы отрендерить опрос, нужно импортировать модуль библиотеки форм SurveyJS в app.module.ts.

import { NgModule } from ‘@angular/core’;
import { BrowserModule } from ‘@angular/platform-browser’;
import { AppRoutingModule } from ‘./app-routing.module’;
import { AppComponent } from ‘./app.component’;
import { SurveyModule } from ‘survey-angular-ui’;

@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, SurveyModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}

Потом просто добавим элемент <survey> в шаблон компонента и передадим экземпляр модели, который создали выше, в качестве атрибута model:

<survey [model]=”surveyModel”></survey>

Шаг 2.5. Запуск приложения

Наконец, запустим приложение:

npm run start

Если вы правильно следовали вышеуказанным шагам, на выходе у вас получится следующее:

Шаг 3. Создание опроса удовлетворенности сотрудников

Теперь сосредоточимся на схеме опроса и посмотрим, как можно использовать различные типы компонентов в соответствии с каждым вопросом, содержащимся в нем.

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

  • Простое текстовое поле: text.
  • Простое поле текстовой области: comment.
  • Поле компонента RadioGroup: radiogroup.
  • Матрица компонентов RadioGroup: matrix.

Если хотите получить более подробную информацию о различных компонентах, предоставляемых SurveyJS, ознакомьтесь с API библиотеки форм.

Итак, мы знаем, какие компоненты нам нужны. Обновим схему JSON:

const surveyJson = {
title: ‘Your opinion counts!’,
description: ‘Please express what you think about your job?’,
pages: [
{
elements: [
{
name: ‘Name’,
title: ‘Enter your full name:’,
type: ‘text’,
},
{
name: ‘OverallSatisfaction’,
title:
‘How would you describe your overall level of job satisfaction?’,
type: ‘radiogroup’,
isRequired: true,
choices: [
‘Very satisfied’,
‘Satisfied’,
‘Neutral’,
‘Dissatisfied’,
‘Very dissatisfied’,
],
},
{
name: ‘Quality’,
title: ‘How would you rate the following?’,
type: ‘matrix’,
isRequired: true,
columns: [
{
value: 1,
text: ‘Very poor’,
},
{
value: 2,
text: ‘Poor’,
},
{
value: 3,
text: ‘Average’,
},
{
value: 4,
text: ‘Good’,
},
{
value: 5,
text: ‘Excellent’,
},
],
rows: [
{
value: ‘Salary’,
text: ‘Salary’,
},
{
value: ‘OverallBenefits’,
text: ‘Overall benefits’,
},
{
value: ‘HealthBenefits’,
text: ‘Health benefits’,
},
{
value: ‘PhysicalWorkEnvironment’,
text: ‘Physical work environment’,
},
{
value: ‘TrainingOpportunities’,
text: ‘Training opportunities’,
},
{
value: ‘WorkingTimeFlexibility’,
text: ‘Working time flexibility’,
},
],
},
{
name: ‘ValuedAtWork’,
title: ‘Do you feel valued at work?’,
type: ‘radiogroup’,
isRequired: true,
choices: [‘Yes’, ‘No’],
},
{
name: ‘Explanation’,
title: ‘If no please explain’,

visibleIf: “{ValuedAtWork}=’No’”,
type: ‘comment’,
},
{
name: ‘Feedback’,
title: ‘Please Provide Any Additional Feedback’,
type: ‘comment’,
},
],
},
],
};

Примечание:

  • Чтобы пометить вопрос как обязательный, добавьте свойство isRequired.
  • Чтобы задать тип вопроса, используйте свойство type.
  • Чтобы показать поля при выполнении условия, применяйте свойство visibleIf.

Затем сохраните и обновите приложение, чтобы увидеть изменения в браузере:

Опрос удовлетворенности сотрудников

Чтобы обработать опрос после того, как пользователь его заполнит, нужно использовать обработчик событий onComplete. В качестве примера запишем (выведем) результаты в консоль браузера.

Добавьте следующий код в app.component.ts:

import { Component, OnInit } from ‘@angular/core’;
import { Model, StylesManager } from ‘survey-core’;

// const SURVEY_ID = 1;

StylesManager.applyTheme('modern');

const surveyJson = {

};

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
title = 'My First Survey';
surveyModel: Model;
logSurveyResults(sender) {
console.log(sender.data);
}
ngOnInit() {
const survey = new Model(surveyJson);
survey.onComplete.add(this.logSurveyResults);
this.surveyModel = survey;
}
}

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

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

Шаг 4. Настройка базы данных MongoDB

При работе с реальными приложениями результаты в консоль не выводятся, но мы будем использовать эти результаты в других веб-сервисах. Фактически, нам нужно отправить результаты на сервер, где они будут храниться в базе данных и обрабатываться системой.

Для полноты картины создадим простой API с помощью Express и MongoDB. Этот API будет получать результаты опроса и хранить их в базе данных.

Сначала установим node, npm и MongoDB (можете скачать их отсюда).

$ node -v
$ npm -v
$ mongo -v

Затем создадим приложение Node.js и установим необходимые пакеты. Вот что мы будем использовать.

  • Express: минималистичный фреймворк для веб-приложений Node.js, предоставляющий набор функций для веб- и мобильных приложений.
  • Nodemon: инструмент, помогающий разрабатывать приложения на базе Node.js, автоматически перезапуская приложение node при обнаружении изменений файлов в каталоге.
  • Mongoose: инструмент моделирования объектов MongoDB для Node.js.
$ mkdir employee-satisfaction-survey-api
$ cd employee-satisfaction-survey-api
$ npm init
$ npm install express nodemon mongoose — save

Затем создадим следующую структуру приложения:

Структура API-проекта
  • package.json:
{
“name”: “employee-satisfaction-survey-api”,
“version”: “1.0.0”,
“description”: “Employee satisfaction survey api”,
“main”: “index.js”,
“scripts”: {
“start”: “nodemon index.js”
},
“author”: “Sihem BOUHENNICHE”,
“license”: “ISC”,
“dependencies”: {
“express”: “⁴.18.2”,
“mongoose”: “⁶.7.4”,
“nodemon”: “².0.20”
}
}
  • index.js  —  точка входа API, содержащая приложение Express и объявление маршрутов:
// Импорт зависимостей
const express = require(“express”);
const database = require(“./initdb.utils”);

// Создание экземпляра приложения
const app = express();

// Определение JSON в качестве типа возвращаемого значения
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Настройка заголовков
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
res.setHeader("Access-Control-Allow-Credentials", true);
next();
});

// Определение маршрутов
app.use("/hello", (req, res) => {
res.status(200).json({ message: "Hello world !" });
});
app.use("/surveys", require("./survey.routes"));

// Этот маршрут будет обрабатывать все запросы, которые
// не обрабатываются никаким другим обработчиком маршрутов. С
// помощью этого обработчика мы перенаправяем пользователя на
// страницу ошибки с сообщением NOT FOUND и кодом
// состояния 404 (код состояния HTTP для NOT found).
app.all("*", (req, res) => {
res.status(404).json({ error: "End point not found" });
});

// Обработка ошибок базы данных
database.on("error", (error) => {
console.log("Connection error: - - - - - - - - - - - - - ");
console.log(error);
console.log(" - - - - - - - - - - - - - - - - - - - - - - ");
});

// Запуск приложения после подключения к базе данных
database.once("connected", () => {
console.log("Database Connected");

const PORT = 3001;
app.listen(PORT, () => console.log("Server ready at 3001"));
});
  • initdb.js содержит конфигурацию соединения с базой данных:
const mongoose = require(“mongoose”);

const MONGO_HOST = "localhost";
const MONGO_PORT = 27017;
const MONGO_DB_NAME = "surveydb";
const MONGO_URL = `mongodb://${MONGO_HOST}:${MONGO_PORT}/${MONGO_DB_NAME}`;
const connectOptions = {
useNewUrlParser: true,
};

mongoose.connect(MONGO_URL, connectOptions);
const database = mongoose.connection;

module.exports = database;
  • survey.model.js содержит схему модели опроса:
const mongoose = require(“mongoose”);

const SurveySchema = mongoose.Schema(
{
Name: String,
OverallSatisfaction: String,
Quality: Array,
ValuedAtWork: String,
Explanation: String,
Feedback: String,
},
{
timestamps: true,
strict: false,
}
);

module.exports = mongoose.model("Survey", SurveySchema);
  • survey.controller.js содержит веб-сервисы. В этом примере мы создадим только 2 сервиса  —  для сохранения и получения результатов.
const Survey = require(“./survey.model”);

// Создание и сохранение нового опроса
exports.create = (req, res) => {
const surveyData = req.body;

// Создание запроса POST
const survey = new Survey(surveyData);

// Сохранение запроса POST в базе данных
survey
.save()
.then((data) => {
res.send(data);
})
.catch((err) => {
res.status(500).send({
message:
err.message || "Some error occurred while creating the survey.",
});
});
};

// Находим все опросы
exports.findAll = (req, res) => {
Survey.find({})
.then((data) => {
res.send(data);
})
.catch((err) => {
res.status(500).send({
message: err.message || "Some error occurred while retrieving data.",
});
});
};
  • survey.routes.js содержит маршруты API:
const surveyController = require(“./survey.controller”);
const router = require(“express”).Router();

//CRUD
router
.post("/", surveyController.create)
.get("/", surveyController.findAll);

module.exports = router;

Теперь запустим API, выполнив следующую команду:

npm run start

Если вы перейдете по адресу http://localhost:3001/hello, то увидите сообщение “hello world!”.

Если попробуете перейти по адресу http://localhost:3001/surveys, то получите пустой ответ, поскольку опрос еще не сохранен.

В следующем разделе посмотрим, как сохранить результаты с помощью API.

Шаг 5. Сохранение результатов в коллекции MongoDB

Итак, мы располагаем API. Обновим app.component.ts и, вместо того чтобы просто записать результаты опроса, отправим их с помощью HTTP-запроса в API.

import { Component, OnInit } from ‘@angular/core’;
import { Model, StylesManager } from ‘survey-core’;

// const SURVEY_ID = 1;

StylesManager.applyTheme('modern');

const surveyJson = {

};

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
title = 'My First Survey';
surveyModel: Model;
logSurveyResults(sender) {
console.log(sender.data);
}
saveSurveyResults(sender) {
const request = new XMLHttpRequest();
const url = '<http://localhost:3001/surveys>';
request.open('POST', url);
request.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
request.send(JSON.stringify(sender.data));
}
ngOnInit() {
const survey = new Model(surveyJson);
survey.onComplete.add(this.saveSurveyResults);
this.surveyModel = survey;
}
}

Если мы нажмем на кнопку завершения опроса, то после заполнения всех полей данные будут отправлены в API:

И если вы сейчас попробуете зайти на http://localhost:3001/surveys, то увидите результаты:

Полный код этого проекта можно найти по следующим ссылкам.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Sohom Das: Create Employee Satisfaction Survey Using Angular + MongoDB

Предыдущая статьяДиспетчеризация методов в Swift
Следующая статьяОбзор функциональностей CSS, которые появились в 2022 году