[WIP] Move date picker step to VueJS

- Get rid of timepicker and use native date picker (the downside is that
we can't see which days are already taken)
- Save days and times inside localStorage instead of session

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2018-10-09 11:48:11 +02:00
parent d29b703e0e
commit d5c52cd60d
7 changed files with 444 additions and 217 deletions

View file

@ -79,22 +79,21 @@ switch ($step) {
// Step 2/4 : Select dates of the poll
// Prefill form->choices
foreach ($form->getChoices() as $c) {
/** @var Choice $c */
$count = 3 - count($c->getSlots());
for ($i = 0; $i < $count; $i++) {
$c->addSlot('');
}
}
// foreach ($form->getChoices() as $c) {
// /** @var Choice $c */
// $count = 2 - count($c->getSlots());
// for ($i = 0; $i < $count; $i++) {
// $c->addSlot('');
// }
// }
$count = 3 - count($form->getChoices());
for ($i = 0; $i < $count; $i++) {
$c = new Choice('');
$c->addSlot('');
$c->addSlot('');
$c->addSlot('');
$form->addChoice($c);
}
// $count = 2 - count($form->getChoices());
// for ($i = 0; $i < $count; $i++) {
// $c = new Choice('');
// $c->addSlot('');
// $c->addSlot('');
// $form->addChoice($c);
// }
$_SESSION['form'] = serialize($form);
@ -145,7 +144,7 @@ switch ($step) {
if (!empty($day)) {
// Add choice to Form data
$date = DateTime::createFromFormat(__('Date', 'Y-m-d'), $_POST['days'][$i])->setTime(0, 0, 0);
$date = DateTime::createFromFormat('Y-m-d', $_POST['days'][$i])->setTime(0, 0, 0);
$time = (string) $date->getTimestamp();
$choice = new Choice($time);
$form->addChoice($choice);
@ -177,7 +176,7 @@ switch ($step) {
}
$summary .= '</ul>';
$end_date_str = utf8_encode(strftime($date_format['txt_date'], $max_expiry_time)); // textual date
$end_date_str = utf8_encode(strftime('%Y-%m-%d', $max_expiry_time)); // textual date
$_SESSION['form'] = serialize($form);

View file

@ -12,6 +12,7 @@ $(document).ready(function() {
* @param adminPolls
*/
function setAdminPolls(adminPolls) {
localStorage.removeItem('current_poll');
localStorage.setItem('admin_polls', JSON.stringify(adminPolls));
}

View file

@ -60,28 +60,28 @@ $(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(/[\/ .:-]/);
// /**
// * 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;
}
// 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];
}
// // 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);
};
// // 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
@ -97,7 +97,7 @@ $(document).ready(function () {
return parseInt(/^d([0-9]+)-h[0-9]+$/.exec($(last_day).find('.hours').filter(':first').attr('id'))[1])
}
function newDateFields(dateStr) {
function newDateFields(date) {
var last_day = $selected_days.find('fieldset').filter(':last');
var last_day_title = last_day.find('legend input').attr('title');
var new_day_number = getLastDayNumber(last_day) + 1;
@ -115,7 +115,7 @@ $(document).ready(function () {
last_day
.after('<fieldset>' + new_day_html + '</fieldset>')
.next().find('legend input').val(dateStr);
.next().find('legend input').val(date.toISOString());
$('#day' + (new_day_number)).focus();
updateButtonState();
}
@ -128,12 +128,12 @@ $(document).ready(function () {
}
}
var useFirstEmptyDateField = function (dateStr) {
var useFirstEmptyDateField = function (date) {
var used = false;
$selected_days.find('fieldset legend input').each(function () {
if (!used) {
if ($(this).val() == '') {
$(this).val(dateStr);
$(this).val(date.toISOString());
used = true;
}
}
@ -280,24 +280,25 @@ $(document).ready(function () {
$('#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);
var startDate = dateFns.parse(startDateField.val());
var endDate = dateFns.parse(endDateField.val());
// 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;
var maxDate = dateFns.addMonths(startDate, 4);
var tooMuchDates = dateFns.isAfter(endDate, maxDate);
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);
if (dateFns.isBefore(startDate, endDate)) {
console.log('ready for while', dateFns.isBefore(startDate, endDate));
while (dateFns.isBefore(startDate, endDate)) {
// var dateStr = formatDate(startDate, window.date_formats.DATE);
if (!useFirstEmptyDateField(startDate)) {
newDateFields(startDate);
}
startDate.setDate(startDate.getDate() + 1);
startDate = dateFns.addDays(startDate, 1);
}
// Hide modal

View file

@ -16,36 +16,36 @@
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
*/
$(document).ready(function () {
var init_datepicker = function () {
$('.input-group.date').datepicker({
format: window.date_formats.DATEPICKER || "dd/mm/yyyy",
todayBtn: "linked",
orientation: "top left",
autoclose: true,
language: lang,
todayHighlight: true,
beforeShowDay: function (date) {
// Retrieve selected dates from text fields
var selected_days = [];
$('#selected-days').find('input[id^="day"]').each(function () {
if ($(this).val() != '') {
selected_days.push($(this).val());
}
});
// var init_datepicker = function () {
// $('.input-group.date').datepicker({
// format: 'Y-m-d',
// todayBtn: "linked",
// orientation: "top left",
// autoclose: true,
// language: lang,
// todayHighlight: true,
// beforeShowDay: function (date) {
// // Retrieve selected dates from text fields
// var selected_days = [];
// $('#selected-days').find('input[id^="day"]').each(function () {
// if ($(this).val() != '') {
// selected_days.push($(this).val());
// }
// });
// Disable selected dates in DatePicker
for (var i = 0; i < selected_days.length; i++) {
var selected_date = selected_days[i].split('/');
// // Disable selected dates in DatePicker
// for (var i = 0; i < selected_days.length; i++) {
// var selected_date = selected_days[i].split('/');
if (date.getFullYear() == selected_date[2] && (date.getMonth() + 1) == selected_date[1] && date.getDate() == selected_date[0]) {
return {
classes: 'disabled selected'
};
}
}
}
});
};
// if (date.getFullYear() == selected_date[2] && (date.getMonth() + 1) == selected_date[1] && date.getDate() == selected_date[0]) {
// return {
// classes: 'disabled selected'
// };
// }
// }
// }
// });
// };
$(document).on('click', '.input-group.date .input-group-addon, .input-group.date input', function () {
// Re-init datepicker config before displaying
@ -95,4 +95,4 @@ $(document).ready(function () {
}
});
});
});

175
js/app/new_date_poll.js Normal file
View file

@ -0,0 +1,175 @@
class Slot {
constructor(text) {
this.text = text || '';
}
}
class Choice {
constructor(day, slots) {
this.day = day || '';
this.slots = slots || [new Slot(), new Slot()];
}
}
$(document).ready(function () {
var app = new Vue({
delimiters: ['%%', '%%'],
el: '#date-poll',
template: '#date-poll-component',
data() {
return {
choices: JSON.parse(localStorage.getItem('current_poll')) || [new Choice(), new Choice()],
interval: {
start: null,
end: null,
},
modal_open: false,
};
},
created() {
console.log('created choices', this.choices);
},
mounted() {
console.log('mounted', this.choices);
},
computed: {
twoDate: function() {
return this.choices.filter(choice => !this.isChoiceCompletelyEmpty(choice)).length <= 2;
},
noSlots: function() {
console.log(this.choiceSlotsEmpty(this.choices[0]));
return this.choiceSlotsEmpty(this.choices[0]);
}
},
watch: {
choices: {
handler(newList, oldList) {
console.log('choices changed');
let j = 0;
// while (j < this.choices.length) {
// if (this.choices.length > 2) {
// if (this.choices[j].day === '' && this.choices.length > (j + 1) && this.choices[j+1].day !== '') {
// this.choices.splice(j, 1);
// console.log('removing empty choice before value', this.choices);
// break;
// }
// if (this.choices[j].day === '' && this.choices.length > (j + 1) && this.choices[j+1].day === '') {
// this.choices.splice(j + 1, 1);
// console.log('removing empty choice before another empty choice', this.choices);
// break;
// }
// }
// if (this.choices[j].text !== '' && this.choices.length === (j + 1)) {
// console.log('adding extra empty choice');
// this.choices.push(new Choice());
// break;
// }
// j = j+1;
// }
if (this.choices.length >= 2 && this.choices[this.choices.length - 1].day !== '') {
const filteredList = this.choices.filter(choice => !this.isChoiceCompletelyEmpty(choice));
console.log('filtered list', filteredList);
if (filteredList.length >= 2) {
this.choices = filteredList;
this.choices.push(new Choice());
console.log('adding extra empty choice');
}
}
this.choices.forEach((choice) => {
let i = 0;
while (i < choice.slots.length) {
console.log('processing slot ', i);
if (choice.slots.length > 2) {
if (choice.slots[i].text === '' && choice.slots.length > (i + 1) && choice.slots[i+1].text !== '') {
choice.slots.splice(i, 1);
console.log('removing empty slot before value', choice.slots);
break;
}
if (choice.slots[i].text === '' && choice.slots.length > (i + 1) && choice.slots[i+1].text === '') {
choice.slots.splice(i + 1, 1);
console.log('removing empty slot before another empty slot', choice.slots);
break;
}
}
if (choice.slots[i].text !== '' && choice.slots.length === (i + 1)) {
console.log('adding extra empty slot');
choice.slots.push(new Slot());
break;
}
i = i+1;
}
// if (choice.slots.length >= 2 && choice.slots[choice.slots.length - 1].text !== '') {
// console.log('choice slots before', choice.slots);
// choice.slots = choice.slots.filter(slot => slot.text !== '');
// console.log('choice slots after', choice.slots);
// choice.slots.push(new Slot());
// }
console.log('slots nb', choice.slots.length);
});
},
deep: true,
},
},
methods: {
addChoice() {
this.choices.push(new Choice());
},
removeChoice(index) {
this.choices.splice(index, 1);
if (this.choices.length < 2) {
this.choices.push(new Choice());
}
},
removeLastChoice() {
this.removeChoice(-1);
},
addSlot(choice) {
choice.slots = [...choice.slots, ''];
},
removeLastSlot(choice) {
choice.slots = choice.slots.slice(0, -1);
},
removeAllDays() {
this.choices = [new Choice(), new Choice()];
},
removeAllSlots() {
this.choices.forEach((choice) => {
choice.slots = ['', '', ''];
});
},
addInterval(res) {
if (res !== 'ok') {
return;
}
this.choices = this.choices.filter(choice => !this.isChoiceCompletelyEmpty(choice));
while (dayjs(this.interval.start).isBefore(this.interval.end) || dayjs(this.interval.start).isSame(this.interval.end)) {
this.choices.push(new Choice(this.interval.start));
this.interval.start = dayjs(this.interval.start).add(1, 'day').format('YYYY-MM-DD');
}
this.choices.push(new Choice());
},
onSubmit(e) {
localStorage.setItem('current_poll', JSON.stringify(this.choices));
},
copyTimesFromFirstDay() {
i = 1;
slots = this.choices[0].slots;
while (i < this.choices.length) {
let newChoice = new Choice(this.choices[i].day, slots.slice());
this.choices.splice(i, 1, newChoice);
i = i+1;
}
},
isChoiceCompletelyEmpty(choice) {
return this.choiceDayEmpty(choice) && this.choiceSlotsEmpty(choice);
},
choiceDayEmpty(choice) {
return choice.day === '';
},
choiceSlotsEmpty(choice) {
return choice.slots.every((slot) => slot.text === '');
}
},
});
});

View file

@ -7,166 +7,218 @@
DATEPICKER: '{__('Date', 'yyyy-mm-dd')}'
};
</script>
<script type="text/javascript" src="{'js/app/framadatepicker.js'|resource}"></script>
<script type="text/javascript" src="{'js/app/date_poll.js'|resource}"></script>
<script src="https://vuejs.org/js/vue.js"></script>
{* <script src="http://cdn.date-fns.org/v1.9.0/date_fns.min.js"></script> *}
<script src="https://unpkg.com/dayjs"></script>
<script type="text/javascript" src="//unpkg.com/uiv/dist/uiv.min.js"></script>
{* <script type="text/javascript" src="{'js/app/framadatepicker.js'|resource}"></script> *}
<script type="text/javascript" src="{'js/app/new_date_poll.js'|resource}"></script>
{/block}
{block name=main}
<form name="formulaire" action="" method="POST" class="form-horizontal" role="form">
<div class="row" id="selected-days">
<div class="col-md-10 col-md-offset-1">
<h3>{__('Step 2 date', 'Choose dates for your poll')}</h3>
<script type="text/x-template" id="date-poll-component">
<div>
<form name="formulaire" action="" method="POST" class="form-horizontal" role="form" @submit="onSubmit">
<div class="row" id="selected-days">
<div class="col-md-10 col-md-offset-1">
<h3>{__('Step 2 date', 'Choose dates for your poll')}</h3>
{if $error != null}
<div class="alert alert-danger">
<p>{$error}</p>
</div>
{/if}
{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 provide at least two choices (e.g., two time slots on one day or two days).')}</p>
<div class="alert alert-info">
<p>{__('Step 2 date', 'To schedule an event you need to provide at least two choices (e.g., two time slots on one day or two days).')}</p>
<p>{__('Step 2 date', 'You can add or remove additional days and times with the buttons')}
<span class="glyphicon glyphicon-minus text-info"></span>
<span class="sr-only">{__('Generic', 'Remove')}</span>
<span class="glyphicon glyphicon-plus text-success"></span>
<span class="sr-only">{__('Generic', 'Add')}</span>
</p>
<p>{__('Step 2 date', 'You can add or remove additional days and times with the buttons')}
<span class="glyphicon glyphicon-minus text-info"></span>
<span class="sr-only">{__('Generic', 'Remove')}</span>
<span class="glyphicon glyphicon-plus text-success"></span>
<span class="sr-only">{__('Generic', 'Add')}</span>
</p>
<p>{__('Step 2 date', 'For each selected day, you are free to suggest meeting times (e.g., \"8h\", \"8:30\", \"8h-10h\", \"evening\", etc.)')}</p>
</div>
<p>{__('Step 2 date', 'For each selected day, you are free to suggest meeting times (e.g., \"8h\", \"8:30\", \"8h-10h\", \"evening\", etc.)')}</p>
</div>
<div id="days_container">
{foreach $choices as $i=>$choice}
{if $choice->getName()}
{$day_value = $choice->getName()|date_format:$date_format['txt_date']}
{else}
{$day_value = ''}
{/if}
<fieldset>
<div class="form-group">
<legend>
<label class="sr-only" for="day{$i}">{__('Generic', 'Day')} {$i+1}</label>
<div id="days_container">
<fieldset v-for="(choice, i) in choices">
<div class="form-group">
<legend>
<label class="sr-only" for="day{$i}">{__('Generic', 'Day')} {$i+1}</label>
<div class="col-xs-10 col-sm-11">
<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="day{$i}" title="{__('Generic', 'Day')} {$i+1}"
data-date-format="{__('Date', 'yyyy-mm-dd')}" aria-describedby="dateformat{$i}" name="days[]" value="{$day_value}"
size="10" maxlength="10" placeholder="{__('Date', 'yyyy-mm-dd')}" autocomplete="off"/>
<div class="col-xs-10 col-sm-11">
<div class="input-group date">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span>
<input type="date" class="form-control" id="day{$i}" title="{__('Generic', 'Day')} {$i+1}"
data-date-format="{__('Date', 'yyyy-mm-dd')}" aria-describedby="dateformat{$i}" name="days[]" v-model="choice.day"
size="10" maxlength="10" placeholder="{__('Date', 'yyyy-mm-dd')}" autocomplete="off"/>
</div>
</div>
<div class="col-xs-2 col-sm-1">
<button
type="button"
title="{__('Step 2 date', 'Remove this day')}"
class="remove-day btn btn-sm btn-link"
@click="removeChoice(i)"
>
<span class="glyphicon glyphicon-remove text-danger"></span>
<span class="sr-only">{__('Step 2 date', 'Remove this day')}</span>
</button>
</div>
</div>
<div class="col-xs-2 col-sm-1">
<button type="button" title="{__('Step 2 date', 'Remove this day')}" class="remove-day btn btn-sm btn-link">
<span class="glyphicon glyphicon-remove text-danger"></span>
<span class="sr-only">{__('Step 2 date', 'Remove this day')}</span>
</button>
</div>
<span id="dateformat{$i}" class="sr-only">({__('Date', 'yyyy-mm-dd')})</span>
</legend>
<span id="dateformat{$i}" class="sr-only">({__('Date', 'yyyy-mm-dd')})</span>
</legend>
{foreach $choice->getSlots() as $j=>$slot}
<div class="col-sm-2">
<div class="col-sm-2" v-for="(slot, j) in choice.slots">
<label for="d{$i}-h{$j}" class="sr-only control-label">{__('Generic', 'Time')} {$j+1}</label>
<input type="text" class="form-control hours" title="{$day_value} - {__('Generic', 'Time')} {$j+1}"
placeholder="{__('Generic', 'Time')} {$j+1}" id="d{$i}-h{$j}" name="horaires{$i}[]" value="{$slot|html_special_chars}"/>
:placeholder="'{__('Generic', 'Time')} ' + (j + 1)" id="d{$i}-h{$j}" :name="'horaires' + i + '[]'" v-model="slot.text" />
</div>
{/foreach}
<div class="col-sm-2">
<div class="btn-group btn-group-xs" style="margin-top: 5px;">
<button type="button" title="{__('Step 2 date', 'Remove a time slot')}" class="remove-an-hour btn btn-default">
<span class="glyphicon glyphicon-minus text-info"></span>
<span class="sr-only">{__('Step 2 date', 'Remove a time slot')}</span>
</button>
<button type="button" title="{__('Step 2 date', 'Add a time slot')}" class="add-an-hour btn btn-default">
<span class="glyphicon glyphicon-plus text-success"></span>
<span class="sr-only">{__('Step 2 date', 'Add a time slot')}</span>
</button>
</div>
{* <div class="col-sm-2">
<div class="btn-group btn-group-xs" style="margin-top: 5px;">
<button
type="button"
title="{__('Step 2 date', 'Remove a time slot')}"
class="remove-an-hour btn btn-default"
@click="removeLastSlot(choice)"
>
<span class="glyphicon glyphicon-minus text-info"></span>
<span class="sr-only">{__('Step 2 date', 'Remove a time slot')}</span>
</button>
<button
type="button"
title="{__('Step 2 date', 'Add a time slot')}"
class="add-an-hour btn btn-default"
@click="addSlot(choice)"
>
<span class="glyphicon glyphicon-plus text-success"></span>
<span class="sr-only">{__('Step 2 date', 'Add a time slot')}</span>
</button>
</div>
</div> *}
</div>
</div>
</fieldset>
{/foreach}
</div>
</fieldset>
</div>
<div class="col-md-4">
<button type="button" id="copyhours" class="btn btn-default disabled" title="{__('Step 2 date', 'Copy times from the first day')}"><span
class="glyphicon glyphicon-sort-by-attributes-alt text-info"></span><span
class="sr-only">{__('Step 2 date', 'Copy times from the first day')}</span></button>
<div class="btn-group btn-group">
<button type="button" id="remove-a-day" class="btn btn-default disabled" title="{__('Step 2 date', 'Remove a day')}"><span
class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">{__('Step 2 date', 'Remove a day')}</span></button>
<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 class="col-md-4">
<button
type="button"
id="copyhours"
class="btn btn-default"
title="{__('Step 2 date', 'Copy times from the first day')}"
:class="{ disabled: noSlots }"
@click="copyTimesFromFirstDay"
><span
class="glyphicon glyphicon-sort-by-attributes-alt text-info"></span><span
class="sr-only">{__('Step 2 date', 'Copy times from the first day')}</span></button>
{* <div class="btn-group btn-group">
<button
type="button"
id="remove-a-day"
class="btn btn-default"
:class="{ disabled: twoDate }"
title="{__('Step 2 date', 'Remove a day')}"
@click="removeLastChoice"
>
<span
class="glyphicon glyphicon-minus text-info">
</span>
<span
class="sr-only">
{__('Step 2 date', 'Remove a day')}
</span>
</button>
<button
type="button"
id="add-a-day"
class="btn btn-default"
title="{__('Step 2 date', 'Add a day')}"
@click="addChoice"
>
<span
class="glyphicon glyphicon-plus text-success">
</span>
<span class="sr-only">{__('Step 2 date', 'Add a day')}</span>
</button>
</div> *}
<btn
class="btn btn-default"
title="{__('Date', 'Add range dates')}"
@click="modal_open = true"
>
<span class="glyphicon glyphicon-plus text-success"></span>
<span class="glyphicon glyphicon-plus text-success"></span>
<span class="sr-only">{__('Date', 'Add range dates')}</span>
</btn>
</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">{__('Date', 'Add range dates')}</span>
</a>
</div>
<div class="col-md-8 text-right">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-remove text-danger"></span>
{__('Generic', 'Remove')} <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a id="resetdays" href="javascript:void(0)">{__('Step 2 date', 'Remove all days')}</a></li>
<li><a id="resethours" href="javascript:void(0)">{__('Step 2 date', 'Remove all times')}</a></li>
</ul>
<div class="col-md-8 text-right">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-remove text-danger"></span>
{__('Generic', 'Remove')} <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a id="resetdays" href="javascript:void(0)" @click="removeAllDays">{__('Step 2 date', 'Remove all days')}</a></li>
<li><a id="resethours" href="javascript:void(0)" @click="removeAllSlots">{__('Step 2 date', 'Remove all times')}</a></li>
</ul>
</div>
<a class="btn btn-default" href="{$SERVER_URL}create_poll.php?type=date"
title="{__('Step 2', 'Return to step 1')}">{__('Generic', 'Back')}</a>
<button
name="choixheures"
value="{__('Generic', 'Next')}"
type="submit"
class="btn btn-success"
title="{__('Step 2', 'Go to step 3')}"
>{__('Generic', 'Next')}</button>
</div>
<a class="btn btn-default" href="{$SERVER_URL}create_poll.php?type=date"
title="{__('Step 2', 'Return to step 1')}">{__('Generic', 'Back')}</a>
<button name="choixheures" value="{__('Generic', 'Next')}" type="submit" class="btn btn-success disabled"
title="{__('Step 2', 'Go to step 3')}">{__('Generic', 'Next')}</button>
</div>
</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', 'You can select at most 4 months')}
</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', 'yyyy-mm-dd')}" size="10" maxlength="10"
placeholder="{__('Date', 'yyyy-mm-dd')}"/>
</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', 'yyyy-mm-dd')}" size="10" maxlength="10"
placeholder="{__('Date', 'yyyy-mm-dd')}"/>
</div>
</form>
<modal
v-model="modal_open"
ref="modal"
title="{__('Date', 'Add range dates')}"
ok-text="{__('Generic', 'Add')}"
ok-type="success"
cancel-text="{__('Generic', 'Cancel')}"
cancel-type="default"
@hide="addInterval"
>
<div class="modal-body row">
<div class="col-xs-12">
<div class="alert alert-info">
{__('Date', 'You can select at most 4 months')}
</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 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="date" class="form-control" id="range_start"
data-date-format="{__('Date', 'yyyy-mm-dd')}" size="10" maxlength="10"
placeholder="{__('Date', 'yyyy-mm-dd')}"
v-model="interval.start"
/>
</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="date" class="form-control" id="range_end"
data-date-format="{__('Date', 'yyyy-mm-dd')}" size="10" maxlength="10"
placeholder="{__('Date', 'yyyy-mm-dd')}"
v-model="interval.end"
/>
</div>
</div>
</div>
</modal>
</div>
</div>
</script>
<div id="date-poll"></div>
{/block}

View file

@ -7,11 +7,10 @@
DATEPICKER: '{__('Date', 'yyyy-mm-dd')}'
};
</script>
<script type="text/javascript" src="{'js/app/framadatepicker.js'|resource}"></script>
{/block}
{block name="main"}
<form name="formulaire" method="POST" class="form-horizontal" role="form">
<form name="formulaire" method="POST" class="form-horizontal" role="form" onsubmit="return onSubmit();">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="well summary">
@ -26,7 +25,7 @@
<div class="col-sm-6">
<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="enddate" data-date-format="{__('Date', 'yyyy-mm-dd')}" aria-describedby="dateformat" name="enddate" value="{$end_date_str}" size="10" maxlength="10" placeholder="{__('Date', 'yyyy-mm-dd')}" />
<input type="date" class="form-control" id="enddate" data-date-format="{__('Date', 'yyyy-mm-dd')}" aria-describedby="dateformat" name="enddate" value="{$end_date_str}" size="10" maxlength="10" placeholder="{__('Date', 'yyyy-mm-dd')}" />
</div>
</div>
<span id="dateformat" class="sr-only">{__('Date', 'yyyy-mm-dd')}</span>