Skip to content

Commit

Permalink
New feature #7810 Implement max/min date for date question
Browse files Browse the repository at this point in the history
DEV: implemented min/max dates for datepicker in Date question
DEV: supported formats/dates:
DEV: - fixed dates in format YYYY-MM-DD (e.g. 2013-08-24)
DEV: - {qcode}: reference to another datefield
DEV: -      supported on same (dynamic, JS) and on previous pages (PHP)
DEV: -      honors survey date format and date formats in
DEV: -      advanced attributes of a date question (mixing date
DEV: -      formats in one survey should be no problem)
DEV: - {expressions}: only on following page
DEV: -      Things like date from previous answer+3 days as min
DEV: -      for another question is possible using eg.
DEV: -      {date("Y-m-d",strtotime(departure)+3*60*60*24)}
DEV: -      on a following page
DEV:
DEV: I recycled the dropdown_dates_year_min/max fields
DEV: to avoid cluttering up the user interface. The fields still
DEV: take fixed years in format YYYY for backward compatibility,
DEV: so old survey will work as they used to.
DEV:
DEV: This also fixes #7981 (bug in jquery UI) because we do not use
DEV: the yearrange function of the datepicker anymore,
DEV: which is affected by this bug.
DEV:
DEV: Tested in FF and Chrome
  • Loading branch information
mfaber authored and unknown committed Jul 22, 2013
1 parent c12f391 commit 28be180
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 22 deletions.
8 changes: 4 additions & 4 deletions application/helpers/common_helper.php
Expand Up @@ -3240,16 +3240,16 @@ function questionAttributes($returnByName=false)
'category'=>$clang->gT('Display'),
'sortorder'=>110,
'inputtype'=>'text',
"help"=>$clang->gT('Minimum year value in calendar'),
"caption"=>$clang->gT('Minimum year'));
"help"=>$clang->gT('Minimum date selectable in calendar (YYYY-MM-DD)'),
"caption"=>$clang->gT('Minimum date'));

$qattributes["dropdown_dates_year_max"]=array(
"types"=>"D",
'category'=>$clang->gT('Display'),
'sortorder'=>111,
'inputtype'=>'text',
"help"=>$clang->gT('Maximum year value for calendar'),
"caption"=>$clang->gT('Maximum year'));
"help"=>$clang->gT('Maximum date selectable in calendar (YYYY-MM-DD)'),
"caption"=>$clang->gT('Maximum date'));

$qattributes["dropdown_prepostfix"]=array(
"types"=>"1",
Expand Down
83 changes: 70 additions & 13 deletions application/helpers/qanda_helper.php
Expand Up @@ -1094,15 +1094,13 @@ function do_date($ia)
<option value="">'.$clang->gT('Year').'</option>';

/*
* New question attributes used only if question attribute
* "dropdown_dates" is used (see IF(...) above).
*
* yearmin = Minimum year value for dropdown list, if not set default is 1900
* yearmax = Maximum year value for dropdown list, if not set default is 2020
* yearmax = Maximum year value for dropdown list, if not set default is 2037
* if full dates (format: YYYY-MM-DD) are given, only the year is used
*/
if (trim($aQuestionAttributes['dropdown_dates_year_min'])!='')
{
$yearmin = (int)LimeExpressionManager::ProcessString($aQuestionAttributes['dropdown_dates_year_min']);
$yearmin = (int)substr(LimeExpressionManager::ProcessString($aQuestionAttributes['dropdown_dates_year_min']),0,4);
}
else
{
Expand All @@ -1111,17 +1109,17 @@ function do_date($ia)

if (trim($aQuestionAttributes['dropdown_dates_year_max'])!='')
{
$yearmax = (int)LimeExpressionManager::ProcessString($aQuestionAttributes['dropdown_dates_year_max']);
$yearmax = (int)substr(LimeExpressionManager::ProcessString($aQuestionAttributes['dropdown_dates_year_max']), 0, 4);
}
else
{
$yearmax = 2020;
$yearmax = 2037;
}

if ($yearmin > $yearmax)
{
$yearmin = 1900;
$yearmax = 2020;
$yearmax = 2037;
}

if ($aQuestionAttributes['reverse']==1)
Expand Down Expand Up @@ -1223,6 +1221,12 @@ function do_date($ia)
$answer .= '<input type="hidden" name="qattribute_answer[]" value="'.$ia[1].'" />
<input type="hidden" id="qattribute_answer'.$ia[1].'" name="qattribute_answer'.$ia[1].'" />
<input type="hidden" id="dateformat'.$ia[1].'" value="'.$dateformatdetails['jsdate'].'"/>';

// MayDo:
// add js code to
// - fill dropdown boxes according to min/max
// - if one datefield box is changed update all others
// - would need a LOT of JS
}
else
{
Expand All @@ -1241,35 +1245,88 @@ function do_date($ia)
{
$dateoutput='';
}

$dropdown_dates_year_min_dynvars=false;
$dropdown_dates_year_max_dynvars=false;

if (trim($aQuestionAttributes['dropdown_dates_year_min'])!='') {
$minyear=$aQuestionAttributes['dropdown_dates_year_min'];
$dropdown_dates_year_min=str_replace(array( '}', '{' ), '', $aQuestionAttributes['dropdown_dates_year_min']);
if ($minyear!=$dropdown_dates_year_min) $dropdown_dates_year_min_dynvars=true;
// backward compatibility: if only a year is given, add month and day
if ((strlen($minyear)==4) && ($minyear>=1900) && ($minyear<=2037)) {
$minyear.='-01-01';
}
}
else
{
$minyear='1900';
$minyear='1900-01-01';
}

if (trim($aQuestionAttributes['dropdown_dates_year_max'])!='') {
$maxyear=$aQuestionAttributes['dropdown_dates_year_max'];
$dropdown_dates_year_max=str_replace(array( '}', '{' ), '', $aQuestionAttributes['dropdown_dates_year_max']);
if ($maxyear!=$dropdown_dates_year_max) $dropdown_dates_year_max_dynvars=true;
// backward compatibility: if only a year is given, add month and day
if ((strlen($maxyear)==4) && ($maxyear>=1900) && ($maxyear<=2037)) {
$maxyear.='-12-31';
}
}
else
{
$maxyear='2020';
$maxyear='2037-12-31';
}

$goodchars = str_replace( array("m","d","y"), "", $dateformatdetails['jsdate']);
$goodchars = "0123456789".substr($goodchars,0,1);
$iLength=strlen($dateformatdetails['dateformat']);

// HTML for date question using datepicker
$answer ="<p class='question answer-item text-item date-item'><label for='answer{$ia[1]}' class='hide label'>{$clang->gT('Date picker')}</label>
<input class='popupdate' type=\"text\" size=\"{$iLength}\" name=\"{$ia[1]}\" title='".sprintf($clang->gT('Format: %s'),$dateformatdetails['dateformat'])."' id=\"answer{$ia[1]}\" value=\"$dateoutput\" maxlength=\"{$iLength}\" onkeypress=\"return goodchars(event,'".$goodchars."')\" onchange=\"$checkconditionFunction(this.value, this.name, this.type)\" />
<input type='hidden' name='dateformat{$ia[1]}' id='dateformat{$ia[1]}' value='{$dateformatdetails['jsdate']}' />
<input type='hidden' name='datelanguage{$ia[1]}' id='datelanguage{$ia[1]}' value='{$clang->langcode}' />
<input type='hidden' name='dateyearrange{$ia[1]}' id='dateyearrange{$ia[1]}' value='{$minyear}:{$maxyear}' />
<input type='hidden' name='datemin{$ia[1]}' id='datemin{$ia[1]}' value=\"{$minyear}\" />
<input type='hidden' name='datemax{$ia[1]}' id='datemax{$ia[1]}' value=\"{$maxyear}\" />
</p>";
if (trim($aQuestionAttributes['hide_tip'])==1) {

// following JS is for setting datepicker limits on-the-fly according to variables given in dropdown_date_year_min/max attributes
// works with full dates (format: YYYY-MM-DD, js not needed), only a year, for backward compatibility (YYYY, js not needed),
// or variable names which refer to another date question (in curly brackets)
// The term $.datepicker.formatDate('yy-mm-dd', $.datepicker.parseDate($((LEMalias2varName['$dropdown_dates_year_min']).replace(/java/g, '#dateformat')).attr('value')
// gets the date format from the source variable (in extended attributes min/max field) and converts the date to the yy-mm-dd format

// only write JS code if there are variables used.... everything else can be dealt with in PHP
if ($dropdown_dates_year_min_dynvars==true || $dropdown_dates_year_max_dynvars==true) {
$answer.="<script>
$(document).ready(function() {
$('.popupdate').change(function() {
if (typeof LEMalias2varName !== 'undefined') {
";

if ($dropdown_dates_year_min_dynvars==true) {
// if (step($dropdown_dates_year_min)==step(aktuell)) {
$answer.=" if ('$dropdown_dates_year_min' in LEMalias2varName) {
$('#datemin{$ia[1]}').attr('value', $.datepicker.formatDate('yy-mm-dd',
$.datepicker.parseDate($((LEMalias2varName['$dropdown_dates_year_min']).replace(/java/g, '#dateformat'))
.attr('value'), LEMval('$dropdown_dates_year_min'))));
}
";
}
if ($dropdown_dates_year_max_dynvars==true) {
$answer.=" if ('$dropdown_dates_year_max' in LEMalias2varName) {
$('#datemax{$ia[1]}').attr('value', $.datepicker.formatDate('yy-mm-dd',
$.datepicker.parseDate($((LEMalias2varName['$dropdown_dates_year_max']).replace(/java/g, '#dateformat'))
.attr('value'), LEMval('$dropdown_dates_year_max'))));
}
";
}
$answer.="}
});
});
</script>";
}
if (trim($aQuestionAttributes['hide_tip'])==1) {
$answer.="<p class=\"tip\">".sprintf($clang->gT('Format: %s'),$dateformatdetails['dateformat'])."</p>";
}
}
Expand Down
21 changes: 16 additions & 5 deletions scripts/date.js
Expand Up @@ -6,16 +6,14 @@ $(document).ready(function(){
format=format.replace(/H/gi,"0");
format=format.replace(/N/gi,"0");
language=$('#datelanguage'+basename).val();
yearrange=$('#dateyearrange'+basename).val();
range=yearrange.split(':');
datemin=$('#datemin'+basename).val();
datemax=$('#datemax'+basename).val();
$(e).datepicker({ dateFormat: format,
showOn: 'both',
changeYear: true,
changeMonth: true,
yearRange: yearrange,
defaultDate: +0,
minDate:new Date(range[0],0,1),
maxDate: new Date(range[1],11,31),
beforeShow: customRange,
duration: 'fast'
}, $.datepicker.regional[language]);
});
Expand All @@ -29,6 +27,19 @@ $(document).ready(function(){
$('.year').change();
});

function customRange(input)
{
var basename = input.id.substr(6);
datemin=$('#datemin'+basename).val();
datemax=$('#datemax'+basename).val();
//alert('date.js: '+datemin+' '+ datemax);
//FF is picky....have to remove the time with substr
return {
minDate: new Date(Date.parse(datemin.substr(0,10))),
maxDate: new Date(Date.parse(datemax.substr(0,10))),
};
}


function dateUpdater() {

Expand Down

0 comments on commit 28be180

Please sign in to comment.