override view, action and service implementation

parent bc182d79
......@@ -20,6 +20,7 @@ return [
'module/sch_sync/bootstrap.php',
'module/schools/bootstrap.php',
'module/application_form/bootstrap.php',
'module/tpe_survey/bootstrap.php',
],
'cache_config' => 'data/cache/config/settings.php',
];
......@@ -31,6 +31,7 @@ return [
['/school/software', ['school'], ['get', 'post', 'delete']],
['/application-form', ['school'], ['get', 'post'], 'GrEduLabs\ApplicationForm\Acl\Assertion\CanSubmit'],
['/application-form/submit-success', ['school'], ['get']],
['/tpe_survey', ['school'], ['get', 'post']],
],
],
],
......
......@@ -13,6 +13,7 @@ return [
'paths' => [
__DIR__ . '/../../module/schools/public',
__DIR__ . '/../../module/application_form/public',
__DIR__ . '/../../module/tpe_survey/public',
],
],
];
......@@ -6,7 +6,8 @@
StaffRow,
StaffView,
TeacherView,
teacherTemplate;
teacherTemplate,
staffModel;
Teacher = Backbone.Model.extend({ idAttribute: 'id' });
......@@ -63,7 +64,7 @@
},
editEmployee: function (evt) {
var teacherId;
if ($(evt.target).is('a')) return;
if (!$(evt.target).is('td')) return;
teacherId = $(evt.target).closest('tr').data('id');
this.teacherView.render(teacherId);
return this;
......@@ -176,6 +177,10 @@
});
}
});
new StaffView({ model: new Staff() });
staffModel = new Staff();
new StaffView({ model: staffModel });
window.EDULABS.models = window.EDULABS.models || {};
window.EDULABS.models.staff = staffModel;
}(window.EDULABS.utils));
<?php
use GrEduLabs\TpeSurvey\Action\SurveyForm;
use GrEduLabs\TpeSurvey\Middleware\SurveyFormDefaults;
use GrEduLabs\TpeSurvey\Service\SurveyService;
use GrEduLabs\TpeSurvey\Service\SurveyServiceInterface;
use Slim\App;
use Slim\Container;
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
return function (App $app) {
$container = $app->getContainer();
$events = $container->get('events');
$events('on', 'app.autoload', function ($autoloader) {
$autoloader->addPsr4('GrEduLabs\\TpeSurvey\\', __DIR__ . '/src/');
});
$events('on', 'app.services', function (Container $c) {
$c[SurveyServiceInterface::class] = function ($c) {
return new SurveyService();
};
$c[SurveyFormDefaults::class] = function ($c) {
return new SurveyFormDefaults($c->get('view'));
};
$c[SurveyForm::class] = function ($c) {
return new SurveyForm($c->get(SurveyServiceInterface::class));
};
});
$events('on', 'app.bootstrap', function (App $app, Container $c) {
$c->get('view')->getEnvironment()->getLoader()->prependPath(__DIR__ . '/templates');
$app->group('/tpe_survey', function () {
$this->map(['GET', 'POST'], '', SurveyForm::class)->setName('tpe_survey');
});
});
$events('on', 'app.bootstrap', function (App $app, Container $c) {
$c->get('router')->getNamedRoute('school.staff')->add(SurveyFormDefaults::class);
}, -10);
};
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
(function ($, _, utils) {
'use strict';
var ModalView;
ModalView = Backbone.View.extend({
el: '#tpe_survey-form-modal',
model: null,
template: null,
events: {
'submit': 'submitForm'
},
initialize: function () {
this.model = null,
this.template = _.template(this.$el.find('.modal-content script[type="text/template"]').html());
},
render: function () {
var that = this,
html,
url;
if (!this.model) return this;
html = this.template({teacher: this.model.toJSON()});
url = this.$el.find('form').attr('action');
this.$el.find('.modal-content').html(html);
$.ajax({
url: url,
type: 'get',
dataType: 'json',
data: {
teacher_id: that.model.get('id')
}
}).done(function (response) {
var elements = $(that.$el.find('form')[0].elements),
prop,
element;
for (prop in response) {
if (response.hasOwnProperty(prop)) {
elements.closest('[name^="' + prop + '"]').each(function (i, element){
element = $(element);
if ('text' === element.attr('type') && /^assets_in_use/.test(element.attr('name'))) {
element.val(response[prop][response[prop].length - 1]);
} else if ('checkbox' === element.attr('type')) {
element.prop('checked', -1 !== _.indexOf(response[prop], element.val()));
} else {
element.val(response[prop] || '');
}
});
}
}
}).always(function (response) {
that.show();
});
return this;
},
show: function () {
this.$el.modal('show');
return this;
},
hide: function () {
this.$el.modal('hide');
return this;
},
submitForm: function (evt) {
var that = this,
form = this.$el.find('form'),
url = form.attr('action'),
data = utils.serializeObject(form);
evt.preventDefault();
$.ajax({
url: url,
type: 'post',
dataType: 'json',
data: data,
}).done(function (response) {
that.hide();
}).fail(function (xhr, err) {
alert('Προέκυψε κάποιο σφάλμα');
});
return false;
}
});
var modal = new ModalView(),
staffModel = window.EDULABS.models.staff || {};
$('#school-staff table tbody').on('click', 'td.tpe_survey a', function (evt) {
var target = $(evt.target).closest('a'),
id = target.data('id'),
teacher = typeof staffModel.get === 'function' && staffModel.get(id);
evt.preventDefault();
if(!teacher) {
return;
}
modal.model = teacher;
modal.render();
});
}(jQuery, _, window.EDULABS.utils));
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\TpeSurvey\Action;
use GrEduLabs\TpeSurvey\Service\SurveyServiceInterface;
use Slim\Http\Request;
use Slim\Http\Response;
class SurveyForm
{
/**
*
* @var SurveyServiceInterface
*/
private $service;
public function __construct(SurveyServiceInterface $service)
{
$this->service = $service;
}
public function __invoke(Request $req, Response $res)
{
$teacherId = $req->getParam('teacher_id');
if ($req->isPost()) {
$this->service->saveAnswers($teacherId, $req->getParams());
}
$data = $this->service->getAnswers($teacherId);
$res = $res->withJson($data);
return $res;
}
}
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\TpeSurvey\Middleware;
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\Views\Twig;
class SurveyFormDefaults
{
private static $knowledgeLevels = ['ΜΕΤΡΙΑ', 'ΚΑΛΑ', 'ΠΟΛΥ ΚΑΛΑ', 'ΑΡΙΣΤΑ'];
private static $assetsInUse = ['Η/Υ', 'TABLET', 'ΔΣΔ (Διαδραστικό Σύστημα Διδασκαλίας)', 'ΒΙΝΤΕΟΠΡΟΒΟΛΕΑΣ', 'ΚΙΤ ΡΟΜΠΟΤΙΚΗΣ'];
private static $softwareInUse = [
'sw_web2' => [
'label' => 'WEB 2.0 ΕΡΓΑΛΕΙΑ',
'desc' => 'Περιγράψτε, πχ socrative, padlet, wiki κλπ',
],
'sw_packages' => [
'label' => 'ΕΚΠΑΙΔΕΥΤΙΚΑ ΠΑΚΕΤΑ ΛΟΓΙΣΜΙΚΟΥ',
'desc' => 'Περιγράψτε, πχ interactive physics, modelus, geogebra κλπ',
],
'sw_digitalschool' => [
'label' => 'ΦΩΤΟΔΕΝΤΡΟ/ΨΗΦΙΑΚΟ ΣΧΟΛΕΙΟ',
'desc' => 'Περιγράψτε, πχ εμπλουτισμένα βιβλία, εφαρμογές φωτόδενδρου (ποιές), υπηρεσίες (ποιές)',
],
'sw_other' => [
'label' => 'ΑΛΛΟ',
'desc' => 'Περιγράψτε',
],
];
private static $useCase = [
'uc_eduprograms' => [
'label' => 'ΣΥΜΜΕΤΟΧΗ ΣΕ ΠΡΟΓΡΑΜΜΑΤΑ',
'desc' => 'Περιγράψτε, πχ eTwinning, Scientix, Erasmus+, άλλο',
],
'uc_digitaldesign' => [
'label' => 'ΨΗΦΙΑΚΑ ΣΧΕΔΙΑ ΜΑΘΗΜΑΤΩΝ',
'desc' => 'Περιγράψτε',
],
'uc_asyncedu' => [
'label' => 'ΑΣΥΓΧΡΟΝΗ ΔΙΔΑΣΚΑΛΙΑ',
'desc' => 'Περιγράψτε, πχ moodle, η-τάξη, άλλο',
],
'uc_other' => [
'label' => 'ΑΛΛΟ',
'desc' => 'Περιγράψτε',
],
];
/**
*
* @var Twig
*/
private $view;
public function __construct(Twig $view)
{
$this->view = $view;
}
public function __invoke(Request $req, Response $res, callable $next)
{
$map = function ($value) {
return ['value' => $value, 'label' => $value];
};
if ($req->isGet()) {
$this->view['tpe_survey'] = [
'knowledge_levels' => array_map($map, self::$knowledgeLevels),
'assets_in_use' => array_map($map, self::$assetsInUse),
'software_in_use' => self::$softwareInUse,
'use_case' => self::$useCase,
];
}
return $next($req, $res);
}
}
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\TpeSurvey\Service;
use RedBeanPHP\R;
class SurveyService implements SurveyServiceInterface
{
public function getAnswers($teacherId)
{
$bean = R::findOne('tpesurvey', 'teacher_id = ?', [$teacherId]);
$data = $bean->export();
$data['assets_in_use'] = explode('|', $data['assets_in_use']);
return $data;
}
public function saveAnswers($teacherId, array $data)
{
if (isset($data['assets_in_use'])) {
$data['assets_in_use'] = implode('|', $data['assets_in_use']);
}
$bean = R::findOne('tpesurvey', 'teacher_id = ?', [$teacherId]);
if (null === $bean) {
$bean = R::dispense('tpesurvey');
}
$bean->teacher_id = (int) $teacherId;
$bean->import($data, [
'knowledge_level',
'assets_in_use',
'sw_web2',
'sw_packages',
'sw_digitalschool',
'sw_other',
'uc_eduprograms',
'uc_digitaldesign',
'uc_asyncedu',
'uc_other',
]);
R::store($bean);
}
}
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\TpeSurvey\Service;
interface SurveyServiceInterface
{
/**
*
* @param int $teacherId
* @return array
*/
public function getAnswers($teacherId);
/**
*
* @param int $teacherId
* @param array $data
*/
public function saveAnswers($teacherId, array $data);
}
{% extends "schools/index.twig" %}
{% import "schools/index.twig" as macros %}
{% block schoolTitle %}
{{ parent() }} <small>Εκπαιδευτικοί</small>
{% endblock %}
{% block navItems %}
<li role="presentation" class="pull-right">
<a href="#" class="btn btn-primary btn-add-teacher" title="Καταχώρηση εκπαιδευτικού">
<i class="visible-xs fa fa-plus"></i>
<span class="hidden-xs">Καταχώρηση εκπαιδευτικού</span>
</a>
</li>
{% endblock %}
{% block schoolContent %}
<div id="school-staff">
<p>
Σε αυτή τη καρτέλα καταχωρούνται ο Δ/ντης του σχολείου, οι Υπεύθυνοι
σχολικών εργαστηρίων, καθώς και εκείνοι οι εκπαιδευτικοί που χρησιμοποιούν
ή πρόκειται να χρησιμοποιήσουν ΤΠΕ στο σχολείο.
</p>
<div class="table-responsive">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>Όνομα</th>
<th>Επώνυμο</th>
<th>Τηλέφωνο</th>
<th>Email</th>
<th>Ειδικότητα</th>
<th>Θέση</th>
<th>Χρήση ΤΠΕ</th>
</tr>
</thead>
<tbody>
{% for teacher in staff %}
<tr data-teacher="{{ teacher|json_encode }}" data-id="{{ teacher.id }}">
<td class="name">{{ teacher.name }}</td>
<td class="surname">{{ teacher.surname }}</td>
<td class="telephone">{{ teacher.telephone }}</td>
<td class="email">
<a href="mailto:{{ teacher.email }}">{{ teacher.email }}</a>
</td>
<td class="branch">{{ teacher.branch }}</td>
<td class="position">{{ teacher.position }}</td>
<td class="tpe_survey">
<a href="#tpe_survey" class="btn btn-primary btn-xs" type="button" data-id="{{ teacher.id }}">
<i class="fa fa-file-text-o"></i>
&nbsp;Ερωτηματολόγιο
</a>
</td>
</tr>
{% else %}
<tr class="no-records">
<td colspan="7" class="text-center text-muted">
Δεν έχουν καταχωρηθεί εκπαιδευτικοί.
</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<th colspan="7"></th>
</tr>
</tfoot>
</table>
</div>
<div class="modal fade" id="teacher-form-modal" tabindex="-1" role="dialog" aria-labelledby="teacher-from">
<form class="form-horizontal" data-url="{{ path_for('school.staff') }}">
<div class="modal-dialog" role="form">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">Στοιχεία εκπαιδευτικού</h4>
</div>
<div class="modal-body">
{{ macros.input('name', 'Όνομα', '', 'text', {'required': ''}) }}
{{ macros.input('surname', 'Επώνυμο', '', 'text', {'required': ''}) }}
{{ macros.input('telephone', 'Τηλέφωνο','', 'tel', {'required': ''}) }}
{{ macros.input('email', 'Email','', 'email', {'required': ''}) }}
{{ macros.select('branch_id', 'Ειδικότητα', branches, '', {'required': ''}) }}
{{ macros.checkbox('is_principle', 'Διευθυντής') }}
{{ macros.checkbox('is_responsible', 'Υπεύθυνος εργαστηρίου') }}
<input type="hidden" name="id" value="">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger pull-left remove">Διαγραφή</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Κλείσιμο</button>
<button type="submit" class="btn btn-primary">Αποθήκευση</button>
</div>
</div>
</div>
</form>
</div>
{% include "tpe_survey/form.twig" %}
<script type="text/template" id="teacher-row">
<td class="name"><%= teacher.name %></td>
<td class="surname"><%= teacher.surname %></td>
<td class="telephone"><%= teacher.telephone %></td>
<td class="email">
<a href="mailto:<%= teacher.email %>"><%= teacher.email %></a>
</td>
<td class="branch"><%= teacher.branch %></td>
<td class="positionLabel"><%= teacher.position %></td>
<td class="tpe_survey">
<a href="#tpe_survey" class="btn btn-primary btn-xs" type="button" data-id="<%= teacher.id %>">
<i class="fa fa-file-text-o"></i>
&nbsp;Ερωτηματολόγιο
</a>
</td>
</script>
</div>
{% endblock %}
{% block inlinejs %}
{{ parent() }}
<script src="{{ base_url }}/js/schools/staff.js"></script>
<script src="{{ base_url }}/js/schools/tpe_survey.js"></script>
{% endblock %}
\ No newline at end of file
{% import "tpe_survey/macros/form.twig" as form %}
<div class="modal fade" id="tpe_survey-form-modal" tabindex="-1" role="dialog" aria-labelledby="tpe_survey-from">
<form class="form-horizontal" action="{{ path_for('tpe_survey') }}" method="post">
<div class="modal-dialog modal-lg" role="form">
<div class="modal-content">
<script type="text/template">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title"><%= teacher.fullname %>: Χρήση ΤΠΕ </h4>
</div>
<div class="modal-body">
{{ macros.select('knowledge_level', 'Γνώση ΤΠΕ', tpe_survey.knowledge_levels, '', {'required': ''}) }}
{{ form.multicheckbox('assets_in_use', 'Υλικό που χρησιμοποιεί', tpe_survey.assets_in_use, '', {freeText: true, required: ''}) }}
<div class="form-group">
<label class="control-label hidden-xs hidden-sm col-md-3">Λογισμικό που χρησιμοποιεί</label>
<div class="col-xs-12 col-sm-12 col-md-9 text-left">
{% for swKey, sw in tpe_survey.software_in_use %}
<label class="control-label"> {{ sw.label }}</label>
<input class="form-control" type="text" name="{{ swKey }}" placeholder="{{ sw.desc }}">
{% endfor %}
</div>
</div>
<div class="form-group">
<label class="control-label hidden-xs hidden-sm col-md-3">Τρόπος χρήσης</label>
<div class="col-xs-12 col-sm-12 col-md-9 text-left">
{% for ucKey, uc in tpe_survey.use_case %}
<label class="control-label"> {{ uc.label }}</label>
<input class="form-control" type="text" name="{{ ucKey }}" placeholder="{{ uc.desc }}">
{% endfor %}
</div>
</div>
<input type="hidden" name="teacher_id" value="<%= teacher.id %>">
<input type="hidden" name="id" value="">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Κλείσιμο</button>
<button type="submit" class="btn btn-primary">Αποθήκευση</button>
</div>
</script>
</div>
</div>
</form>
</div>
\ No newline at end of file
{% macro multicheckbox(name, label, options, checked, attributes={freeText: false}) %}
<div class="form-group">
<label class="control-label hidden-xs hidden-sm col-md-3">{{ label|raw }}</label>
<div class="col-xs-12 col-sm-12 col-md-9">
{% for checkbox in options %}
<div class="checkbox">
<label>
<input type="checkbox" value="{{ checkbox.value }}" name="{{ name }}">
{{ checkbox.label }}
</label>
</div>
{% endfor %}
{% if attributes.freeText %}
<div class="checkbox">
<input type="text" value="" name="{{ name }}" class="form-control" placeholder="Άλλο">
</div>
{% endif %}
</div>
</div>
{% endmacro %}
......@@ -11,7 +11,11 @@
window.EDULABS.utils.serializeObject = function (form) {
return _.reduce(form.serializeArray(), function (hash, pair) {
if (!!hash[pair.name]) {
hash[pair.name] = [hash[pair.name], pair.value];
if (typeof hash[pair.name].push === 'function') {
hash[pair.name].push(pair.value);
} else {
hash[pair.name] = [hash[pair.name], pair.value];
}
} else {
hash[pair.name] = pair.value;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment