Merge branch 'feature/create_interval_date' into 'develop'

Définition des dates par interval

Voilou, voilou

See merge request !106
This commit is contained in:
Antonin 2016-04-26 23:44:33 +02:00
commit 64454f0f79
14 changed files with 264 additions and 40 deletions

View File

@ -133,7 +133,7 @@
## Changelog du 21 juin 2011 (pyg@framasoft.net)
- très nombreuses modifications CSS
- modification adminstuds.php : ajout de classes aux formulaires et ajout de stripslashes à l'affichage (TODO: à généraliser)
- modification adminstuds.php : ajout de classes aux formulaires et ajout de stripslashes à l'affichage
- modification infos_sondages.php : simplification du tableau de choix, ajouts de CSS, ajouts de labels pour faciliter la selection
## Changelog version 0.6.7 (mai 2011)

View File

@ -74,6 +74,9 @@ const LOG_FILE = 'admin/stdout.log';
// Days (after expiration date) before purge a poll
const PURGE_DELAY = 60;
// Max slots per poll
const MAX_SLOTS_PER_POLL = 366;
// Config
$config = [
/* general config */

View File

@ -179,7 +179,7 @@ if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (
}
$summary .= '</ol>';
$end_date_str = utf8_encode(strftime('%d/%m/%Y', $max_expiry_time)); //textual date
$end_date_str = utf8_encode(strftime($date_format['txt_date'], $max_expiry_time)); //textual date
echo '
<form name="formulaire" action="' . Utils::get_server_name() . 'create_classic_poll.php" method="POST" class="form-horizontal" role="form">

View File

@ -124,6 +124,19 @@ if (!isset($_SESSION['form']->title) || !isset($_SESSION['form']->admin_name) ||
} else {
if (!empty($_POST['days'])) {
// Remove empty dates
$_POST['days'] = array_filter($_POST['days'], function($d) {return !empty($d);});
// Check if there are at most MAX_SLOTS_PER_POLL slots
if (count($_POST['days']) > MAX_SLOTS_PER_POLL) {
// Display step 2
$smarty->assign('title', __('Step 2 date', 'Poll dates (2 on 3)'));
$smarty->assign('choices', $_SESSION['form']->getChoices());
$smarty->assign('error', __f('Error', 'You can\'t select more than %d dates', MAX_SLOTS_PER_POLL));
$smarty->display('create_date_poll_step_2.tpl');
exit;
}
// Clear previous choices
$_SESSION['form']->clearChoices();
@ -133,7 +146,8 @@ if (!isset($_SESSION['form']->title) || !isset($_SESSION['form']->admin_name) ||
if (!empty($day)) {
// Add choice to Form data
$time = mktime(0, 0, 0, substr($_POST["days"][$i],3,2),substr($_POST["days"][$i],0,2),substr($_POST["days"][$i],6,4));
$date = DateTime::createFromFormat(__('Date', 'datetime_parseformat'), $_POST['days'][$i])->setTime(0, 0, 0);
$time = $date->getTimestamp();
$choice = new Choice($time);
$_SESSION['form']->addChoice($choice);
@ -154,7 +168,7 @@ if (!isset($_SESSION['form']->title) || !isset($_SESSION['form']->admin_name) ||
Utils::print_header ( __('Step 3', 'Removal date and confirmation (3 on 3)') );
bandeau_titre(__('Step 3', 'Removal date and confirmation (3 on 3)'));
$end_date_str = utf8_encode(strftime('%d/%m/%Y', $max_expiry_time)); // textual date
$end_date_str = utf8_encode(strftime($date_format['txt_date'], $max_expiry_time)); // textual date
// Summary
$summary = '<ul>';
@ -235,6 +249,7 @@ if (!isset($_SESSION['form']->title) || !isset($_SESSION['form']->admin_name) ||
// Display step 2
$smarty->assign('title', __('Step 2 date', 'Poll dates (2 on 3)'));
$smarty->assign('choices', $_SESSION['form']->getChoices());
$smarty->assign('error', null);
$smarty->display('create_date_poll_step_2.tpl');

View File

@ -43,6 +43,73 @@ $(document).ready(function () {
}
};
/**
* Parse a string date
* @param dateStr The string date
* @param format The format PHP style (allowed: %Y, %m and %d)
*/
var parseDate = function (dateStr, format) {
var dtsplit = dateStr.split(/[\/ .:-]/);
var dfsplit = format.split(/[\/ .:-]/);
if (dfsplit.length != dtsplit.length) {
return null;
}
// creates assoc array for date
var df = [];
for (var dc = 0; dc < dtsplit.length; dc++) {
df[dfsplit[dc]] = dtsplit[dc];
}
// Build date
return new Date(parseInt(df['%Y']), parseInt(df['%m']) - 1, parseInt(df['%d']), 0, 0, 0, 0);
};
var formatDate = function (date, format) {
return format
.replace('%d', ("00" +date.getDate()).slice(-2))
.replace('%m', ("00" + (date.getMonth() + 1)).slice(-2))
.replace('%Y', ("0000" + date.getFullYear()).slice(-4));
};
function newDateFields(dateStr) {
var nb_days = $selected_days.find('fieldset').length;
var last_day = $selected_days.find('fieldset:last');
var last_day_title = last_day.find('legend input').attr('title');
var re_id_hours = new RegExp('"d' + (nb_days - 1) + '-h', 'g');
var re_name_hours = new RegExp('name="horaires' + (nb_days - 1), 'g');
var new_day_html = last_day.html().replace(re_id_hours, '"d' + nb_days + '-h')
.replace('id="day' + (nb_days - 1) + '"', 'id="day' + nb_days + '"')
.replace('for="day' + (nb_days - 1) + '"', 'for="day' + nb_days + '"')
.replace(re_name_hours, 'name="horaires' + nb_days)
.replace(/value="(.*?)"/g, 'value=""')
.replace(/hours" title="(.*?)"/g, 'hours" title="" p')
.replace('title="' + last_day_title + '"', 'title="' + last_day_title.substring(0, last_day_title.indexOf(' ')) + ' ' + (nb_days + 1) + '"');
last_day
.after('<fieldset>' + new_day_html + '</fieldset>')
.next().find('legend input').val(dateStr);
$('#day' + (nb_days)).focus();
$removeaday_and_copyhours.removeClass('disabled');
}
var useFirstEmptyDateField = function (dateStr) {
var used = false;
$selected_days.find('fieldset legend input').each(function () {
if (!used) {
if ($(this).val() == '') {
$(this).val(dateStr);
used = true;
}
}
});
return used;
};
// Handle form submission
$(document.formulaire).on('submit', function (e) {
if (!submitDaysAvalaible()) {
@ -144,24 +211,7 @@ $(document).ready(function () {
// Button "Add a day"
$('#add-a-day').on('click', function () {
var nb_days = $selected_days.find('fieldset').length;
var last_day = $selected_days.find('fieldset:last');
var last_day_title = last_day.find('legend input').attr('title');
var re_id_hours = new RegExp('"d' + (nb_days - 1) + '-h', 'g');
var re_name_hours = new RegExp('name="horaires' + (nb_days - 1), 'g');
var new_day_html = last_day.html().replace(re_id_hours, '"d' + nb_days + '-h')
.replace('id="day' + (nb_days - 1) + '"', 'id="day' + nb_days + '"')
.replace('for="day' + (nb_days - 1) + '"', 'for="day' + nb_days + '"')
.replace(re_name_hours, 'name="horaires' + nb_days)
.replace(/value="(.*?)"/g, 'value=""')
.replace(/hours" title="(.*?)"/g, 'hours" title="" p')
.replace('title="' + last_day_title + '"', 'title="' + last_day_title.substring(0, last_day_title.indexOf(' ')) + ' ' + (nb_days + 1) + '"');
last_day.after('<fieldset>' + new_day_html + '</fieldset>');
$('#day' + (nb_days)).focus();
$removeaday_and_copyhours.removeClass('disabled');
newDateFields();
});
// Button "Remove a day"
@ -176,6 +226,58 @@ $(document).ready(function () {
submitDaysAvalaible();
});
// Add an range of dates
$('#interval_add').on('click', function (ev) {
var startDateField = $('#range_start');
var endDateField = $('#range_end');
var startDate = parseDate(startDateField.val(), window.date_formats.DATE);
var endDate = parseDate(endDateField.val(), window.date_formats.DATE);
// Clear error classes
startDateField.parent().removeClass('has-error');
endDateField.parent().removeClass('has-error');
var maxDates = 123; // 123 = 4 months
var tooMuchDates = endDate - startDate > maxDates * 86400 * 1000;
if (startDate != null && endDate != null && !tooMuchDates) {
if (startDate <= endDate) {
while (startDate <= endDate) {
var dateStr = formatDate(startDate, window.date_formats.DATE);
if (!useFirstEmptyDateField(dateStr)) {
newDateFields(dateStr);
}
startDate.setDate(startDate.getDate() + 1);
}
// Hide modal
startDateField.val('');
endDateField.val('');
$('#add_days').modal('hide');
submitDaysAvalaible();
} else {
setTimeout(function () {
startDateField.parent().addClass('has-error');
endDateField.parent().addClass('has-error');
}, 200);
}
} else {
setTimeout(function () {
if (startDate == null || tooMuchDates) {
startDateField.parent().addClass('has-error');
}
if (endDate == null || tooMuchDates) {
endDateField.parent().addClass('has-error');
}
}, 200);
}
});
// Title update on hours and buttons -/+ hours
$(document).on('change', '.input-group.date input', function () {

View File

@ -18,7 +18,7 @@
$(document).ready(function () {
var init_datepicker = function () {
$('.input-group.date').datepicker({
format: "dd/mm/yyyy",
format: window.date_formats.DATEPICKER || "dd/mm/yyyy",
todayBtn: "linked",
orientation: "top left",
autoclose: true,

View File

@ -41,14 +41,20 @@
"ASTERISK": "*"
},
"Date": {
"dd/mm/yyyy": "jj/mm/aaaa",
"dd/mm/yyyy": "dd/mm/yyyy",
"datepicker": "yyyy-mm-dd",
"datetime_parseformat": "Y-m-d",
"%A, den %e. %B %Y": "%A %e %B %Y",
"FULL": "%A, den %e. %B %Y",
"SHORT": "%A %e %B %Y",
"DAY": "%a %e",
"DATE": "%Y-%m-%d",
"MONTH_YEAR": "%B %Y",
"DATETIME": "%Y-%m-%d %H:%M"
"DATETIME": "%Y-%m-%d %H:%M",
"Add range dates": "DE_Ajout d'un intervalle de dates",
"Max dates count": "DE_Vous pouvez sélectionner au maximum 4 mois",
"Start date": "DE_Date de début",
"End date": "DE_Date de fin"
},
"Language selector": {
"Select the language": "Sprache wählen",
@ -362,6 +368,7 @@
"CANT_CONNECT_TO_DATABASE": "Kann nicht mit der Datenbank verbinden",
"Password is empty": "DE_Le mot de passe est vide.",
"Passwords do not match": "DE_Les mot de passes ne correspondent pas.",
"Poll id already used": "DE_L'identifiant est déjà utilisé"
"Poll id already used": "DE_L'identifiant est déjà utilisé",
"You can't select more than %d dates": "DE_Vous ne pouvez pas choisir plus de %d dates"
}
}

View File

@ -41,14 +41,20 @@
"ASTERISK": "*"
},
"Date" : {
"dd/mm/yyyy": "jj/mm/aaaa",
"dd/mm/yyyy": "yyyy-mm-dd",
"datepicker": "yyyy-mm-dd",
"datetime_parseformat": "Y-m-d",
"%A, den %e. %B %Y": "%A %e %B %Y",
"FULL": "%A, %B %e, %Y",
"SHORT": "%A %e %B %Y",
"DAY": "%a %e",
"DATE": "%Y-%m-%d",
"MONTH_YEAR": "%B %Y",
"DATETIME": "%m/%d/%Y %H:%M"
"DATETIME": "%m/%d/%Y %H:%M",
"Add range dates": "Add range dates",
"Max dates count": "You can select at most 4 months",
"Start date": "Start date",
"End date": "End date"
},
"Language selector": {
"Select the language": "Select language",
@ -362,6 +368,7 @@
"CANT_CONNECT_TO_DATABASE": "Unable to connect to database",
"Password is empty": "Password is empty.",
"Passwords do not match": "Passwords do not match.",
"Poll id already used": "Identifier is already used"
"Poll id already used": "Identifier is already used",
"You can't select more than %d dates": "You can't select more than %d dates"
}
}

View File

@ -42,13 +42,19 @@
},
"Date": {
"dd/mm/yyyy": "dd/mm/aaaa",
"datepicker": "yyyy-mm-dd",
"datetime_parseformat": "Y-m-d",
"%A, den %e. %B %Y": "%A %e de %B de %Y",
"FULL": "%A, %e de %B de %Y",
"SHORT": "%A %e %B %Y",
"DAY": "%a %e",
"DATE": "%d-%m-%Y",
"MONTH_YEAR": "%B de %Y",
"DATETIME": "%d/%m/%Y %H:%M"
"DATETIME": "%d/%m/%Y %H:%M",
"Add range dates": "ES_Ajout d'un intervalle de dates",
"Max dates count": "ES_Vous pouvez sélectionner au maximum 4 mois",
"Start date": "ES_Date de début",
"End date": "ES_Date de fin"
},
"Language selector": {
"Select the language": "Elegir el idioma",
@ -119,6 +125,9 @@
"Poll rules": "Permisos de la encuesta",
"Edit the poll rules": "Modificar los permisos de la encuesta",
"Votes and comments are locked": "Los votos y comentarios están bloqueados",
"Votes and comments are open": "ES_Les votes et commentaires sont ouverts",
"Votes are editable": "ES_Les votes sont modifiables",
"Votes are editable solely by their owner.": "ES_Les votes sont modifiables uniquement par leur créateur",
"Save the new rules": "ES_Enregistrer les nouvelles permissions",
"Cancel the rules edit": "ES_Annuler le changement de permissions",
"Results are hidden": "Los resutaldos no son visibles",
@ -359,6 +368,7 @@
"CANT_CONNECT_TO_DATABASE": "No se puede conectar a la base de datos",
"Password is empty": "ES_Le mot de passe est vide.",
"Passwords do not match": "ES_Les mot de passes ne correspondent pas.",
"Poll id already used": "ES_L'identifiant est déjà utilisé"
"Poll id already used": "ES_L'identifiant est déjà utilisé",
"You can't select more than %d dates": "ES_Vous ne pouvez pas choisir plus de %d dates"
}
}

View File

@ -42,13 +42,19 @@
},
"Date": {
"dd/mm/yyyy": "jj/mm/aaaa",
"datepicker": "dd/mm/yyyy",
"datetime_parseformat": "d/m/Y",
"%A, den %e. %B %Y": "%A %e %B %Y",
"FULL": "%A %e %B %Y",
"SHORT": "%A %e %B %Y",
"DAY": "%a %e",
"DATE": "%Y-%m-%d",
"DATE": "%d/%m/%Y",
"MONTH_YEAR": "%B %Y",
"DATETIME": "%d-%m-%Y %H:%M"
"DATETIME": "%d-%m-%Y %H:%M",
"Add range dates": "Ajout d'un intervalle de dates",
"Max dates count": "Vous pouvez sélectionner au maximum 4 mois",
"Start date": "Date de début",
"End date": "Date de fin"
},
"Language selector": {
"Select the language": "Choisir la langue",
@ -376,6 +382,7 @@
"CANT_CONNECT_TO_DATABASE": "Impossible de se connecter à la base de données",
"Password is empty": "Le mot de passe est vide.",
"Passwords do not match": "Les mots de passe ne correspondent pas.",
"Poll id already used": "L'identifiant est déjà utilisé"
"Poll id already used": "L'identifiant est déjà utilisé",
"You can't select more than %d dates": "Vous ne pouvez pas choisir plus de %d dates"
}
}

View File

@ -42,13 +42,19 @@
},
"Date": {
"dd/mm/yyyy": "gg/mm/aaaa",
"datepicker": "gg/mm/yyyy",
"datetime_parseformat": "g/m/Y",
"%A, den %e. %B %Y": "%A %e %B %Y",
"FULL": "%A %e %B %Y",
"SHORT": "%A %e %B %Y",
"DAY": "%a %e",
"DATE": "%Y-%m-%d",
"MONTH_YEAR": "%B %Y",
"DATETIME": "%d/%m/%Y %H:%M"
"DATETIME": "%d/%m/%Y %H:%M",
"Add range dates": "IT_Ajout d'un intervalle de dates",
"Max dates count": "IT_Vous pouvez sélectionner au maximum 4 mois",
"Start date": "IT_Date de début",
"End date": "IT_Date de fin"
},
"Language selector": {
"Select the language": "Scegliere la lingua",
@ -360,6 +366,7 @@
"The column already exists": "IT_La colonne existe déjà",
"MISSING_VALUES": "Valori mancanti",
"CANT_CONNECT_TO_DATABASE": "Impossibile connettersi al database",
"Poll id already used": "IT_L'identifiant est déjà utilisé"
"Poll id already used": "IT_L'identifiant est déjà utilisé",
"You can't select more than %d dates": "IT_Vous ne pouvez pas choisir plus de %d dates"
}
}

View File

@ -42,11 +42,17 @@
"Date": {
"dd/mm/yyyy": "jj/mm/aaaa",
"%A, den %e. %B %Y": "%A %e %B %Y",
"datepicker": "dd/mm/yyyy",
"datetime_parseformat": "d/m/Y",
"FULL": "%A %e %B %Y",
"SHORT": "%A %e %B %Y",
"DAY": "%a %e",
"DATE": "%Y-%m-%d",
"MONTH_YEAR": "%B %Y"
"MONTH_YEAR": "%B %Y",
"Add range dates": "OC_Ajout d'un intervalle de dates",
"Max dates count": "OC_Vous pouvez sélectionner au maximum 4 mois",
"Start date": "OC_Date de début",
"End date": "OC_Date de fin"
},
"Language selector": {
"Select the language": "Seleccionar la lenga",
@ -358,6 +364,7 @@
"Failed to delete column": "Fracàs de la supression de colomna",
"The column already exists": "La colomna existís ja",
"MISSING_VALUES": "Mancan de valors",
"CANT_CONNECT_TO_DATABASE": "Impossible de se connectar a la banca de donadas"
"CANT_CONNECT_TO_DATABASE": "Impossible de se connectar a la banca de donadas",
"You can't select more than %d dates": "OC_Vous ne pouvez pas choisir plus de %d dates"
}
}

View File

@ -1,6 +1,12 @@
{extends file='page.tpl'}
{block name="header"}
<script type="text/javascript">
window.date_formats = {
DATE: '{__('Date', 'DATE')}',
DATEPICKER: '{__('Date', 'datepicker')}'
};
</script>
<script type="text/javascript" src="{'js/app/framadatepicker.js'|resource}"></script>
<script type="text/javascript" src="{'js/app/date_poll.js'|resource}"></script>
{/block}
@ -11,6 +17,12 @@
<div class="col-md-10 col-md-offset-1">
<h3>{__('Step 2 date', 'Choose the dates of your poll')}</h3>
{if $error != null}
<div class="alert alert-danger">
<p>{$error}</p>
</div>
{/if}
<div class="alert alert-info">
<p>{__('Step 2 date', 'To schedule an event you need to propose at least two choices (two hours for one day or two days).')}</p>
@ -26,7 +38,7 @@
{foreach $choices as $i=>$choice}
{if $choice->getName()}
{$day_value = strftime('%d/%m/%Y', $choice->getName())}
{$day_value = $choice->getName()|date_format:$date_format['txt_date']}
{else}
{$day_value = ''}
{/if}
@ -79,6 +91,11 @@
<button type="button" id="add-a-day" class="btn btn-default" title="{__('Step 2 date', 'Add a day')}"><span
class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">{__('Step 2 date', 'Add a day')}</span></button>
</div>
<a href="" data-toggle="modal" data-target="#add_days" class="btn btn-default" title="{__('Date', 'Add range dates')}">
<span class="glyphicon glyphicon-plus text-success"></span>
<span class="glyphicon glyphicon-plus text-success"></span>
<span class="sr-only">{__('Step 2 date', 'Add days')}</span>
</a>
</div>
<div class="col-md-8 text-right">
<div class="btn-group">
@ -99,4 +116,46 @@
</div>
</div>
</form>
<div id="add_days" class="modal fade">
<div class="modal-dialog modal-md">
<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">{__('Date', 'Add range dates')}</h4>
</div>
<div class="modal-body row">
<div class="col-xs-12">
<div class="alert alert-info">
{__('Date', 'Max dates count')}
</div>
</div>
<div class="col-xs-12">
<label for="range_start">{__('Date', 'Start date')}</label>
<div class="input-group date">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span>
<input type="text" class="form-control" id="range_start"
data-date-format="{__('Date', 'dd/mm/yyyy')}" size="10" maxlength="10"
placeholder="{__('Date', 'dd/mm/yyyy')}"/>
</div>
</div>
<div class="col-xs-12">
<label for="range_end">{__('Date', 'End date')}</label>
<div class="input-group date">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span>
<input type="text" class="form-control" id="range_end"
data-date-format="{__('Date', 'dd/mm/yyyy')}" size="10" maxlength="10"
placeholder="{__('Date', 'dd/mm/yyyy')}"/>
</div>
</div>
</div>
<div class="modal-footer">
<button data-dismiss="modal" class="btn btn-default">{__('Generic', 'Cancel')}</button>
<button id="interval_add" class="btn btn-success">{__('Generic', 'Add')}</button>
</div>
</div>
</div>
</div>
{/block}

View File

@ -5,7 +5,7 @@
<h3>
{__('Poll results', 'Votes of the poll')} {if $hidden}<i>({__('PollInfo', 'Results are hidden.')})</i>{/if}
{if $accessGranted}
<a href="" data-toggle="modal" data-target="#hint_modal"><i class="glyphicon glyphicon-info-sign"></i></a>
<a href="" data-toggle="modal" data-target="#hint_modal"><i class="glyphicon glyphicon-info-sign"></i></a><!-- TODO Add accessibility -->
{/if}
</h3>