Make a Lasting Impression

Join the Mailing List

Who's Online

22 user(s) are online (12 user(s) are browsing Support Forums)

Members: 0
Guests: 22

more...
ImpressCMS proudly uses SourceForge
ImpressCMS on Ohloh.net





Allowing a non-date default value for date boxes in forms
Just can't stay away
Joined:
2007/12/28 22:23
From Toronto, Canada
Posts: 79
Hello,

This is an old issue that I first wrote about seven years ago(!): http://sourceforge.net/tracker/index. ... roup_id=41586&atid=430842

The bottom line is, date boxes right now are always initialized with a date. If no date is given when the box is created, then it defaults to today's date. This is a big problem because when you are parsing what the user submits in a form, you have no way of knowing if the user really picked today's date, or whether they just left the date box alone.

To solve this problem, you need to provide a non-date, non-blank default value, so you can then test for that value when you are processing the user's submission. Then you can know for sure if the user left the box alone, or if they intentionally blanked the date, or intentionally chose today's date (or any other date).

I have made some changes to four files in Impress 1.3 to allow for this. I think the changes are minimally invasive. They do not interfere with existing functionality, they just change the way the boxes are rendered, so that if you initialize the box with no date, ie: "", then a non-date default value is used, instead of the current date. When the user clicks on the calendar, it still defaults to the current date.

The four changes are:

1. class/xoopsform/formtextdateselect.php

It looks like there's a bug in this file actually. Rather than just passing everything that it gets up to the new icms class, it is altering the date value, even though the icms class will do exactly the same thing. So I suggest commenting/removing one line:


//$value = !is_numeric($value) ? time() : (int) ($value);
parent::__construct($caption$name$size$value);


2. language/english/global.php

There's two new constants that I suggest adding to this configuration file, where other locale-specific values are kept:


define
("_DATE_DEFAULT""YYYY-mm-dd");
define("_CAL_MONDAYFIRST""false");


The first is the value that is shown to users in a date box that is initialized with no date. The second is a flag that tells the calendar whether to start weeks on Monday or not (I couldn't find any configuration option in the gui or code to control this elsewhere).

3. libraries/icms/form/elements/Date.php

This is where the bulk of the changes go, but as I said, they don't hinder any existing functionality:


public function __construct($caption$name$size 15$value0) {
    if(
$value === "") {
        
$value _DATE_DEFAULT;
    } elseif(!
is_numeric($value)) {
        
$value time();
    } else {
        
$value intval($value);
    }
    
parent::__construct($caption$name$size25$value);
}

/**
 * Render the Date field
 */
public function render() {
    global 
$icmsConfigPersona;
    
$ele_name $this->getName();
    if(
$icmsConfigPersona['use_jsjalali']) {
        include_once 
ICMS_ROOT_PATH '/include/jalali.php';    
    } 
    if(
$this->getValue(false) !== _DATE_DEFAULT) {
        
$ele_value date(_SHORTDATESTRING$this->getValue(false));
        
$jstime formatTimestamp($this->getValue(false), _SHORTDATESTRING);
        if(
_CALENDAR_TYPE=='jalali') {
            
$jalali_ele_value icms_conv_nr2local(jdate(_SHORTDATESTRING$ele_value));
        } else {
            
$jalali_ele_value $ele_value;
        }
    } else {
        
$ele_value $this->getValue(false);
        
$jstime formatTimestamp(time(), _SHORTDATESTRING);
        
$jalali_ele_value $ele_value;
    }

    include_once 
ICMS_ROOT_PATH '/include/calendar' . ($icmsConfigPersona['use_jsjalali'] == true 'jalali' '') . 'js.php';

    
$result "<input type='text' name='".$ele_name."' id='".$ele_name."' size='".$this->getSize()."' maxlength='".$this->getMaxlength()."' value='".$ele_value."'".$this->getExtra()." />&nbsp;&nbsp;<img src='" ICMS_URL "/images/calendar.png' alt='"._CALENDAR."' title='"._CALENDAR."' id='btn_".$ele_name."' onclick='return showCalendar("".$ele_name."");'>";
        
    if (
$icmsConfigPersona['use_jsjalali']) {
        
$result "<input id='tmp_".$ele_name."' readonly='readonly' size='".$this->getSize()."' maxlength='".$this->getMaxlength()."' value='".$jalali_ele_value."' /><input type='hidden' name='".$ele_name."' id='".$ele_name."' value='".$ele_value."' ".$this->getExtra()." />&nbsp;&nbsp;<img src='" ICMS_URL "/images/calendar.png' alt='"._CALENDAR."' title='"._CALENDAR."' id='btn_".$ele_name."'><script type='text/javascript'>
        Calendar.setup({
            inputField  : 'tmp_"
.$ele_name."',
                   ifFormat    : '%Y-%m-%d',
                   button      : 'btn_"
.$ele_name."',
                   langNumbers : true,
                   dateType    : '"
._CALENDAR_TYPE."',
            onUpdate    : function(cal){document.getElementById('"
.$ele_name."').value = cal.date.print('%Y-%m-%d');}
            });
    </script>"
;
    }
    return 
$result;
}


So basically...check if the date is "" or not, and if so, initialize with the _DATE_DEFAULT constant. Otherwise, do the normal thing we're doing now.

When rendering the box, check if the value is the _DATE_DEFAULT text or not, and if it is, then set things up to draw the box on screen with that text in it, and with the initialization date for the calendar set to today's date. If the value is a real date, do exactly what we're doing now.

There's some extra conditions and stuff in there to account for the slightly different way the jalali calendar does things, but basically that's it. If you do a diff of this against the 1.3 code, you'll see all the little differences.

4. include/calendarjs.php

There are a couple changes here, to make the calendar respect the Monday First flag, and to avoid trying to parse a non-date value as if it were a date. Here's the original code:


function showCalendar(id) {
  var 
el xoopsGetElementById(id);
  if (
calendar != null) {
    
calendar.hide();
  } else {
    var 
cal = new Calendar(true"' . $time . '"selectedcloseHandler);
    
calendar cal;
    
cal.setRange(20002015);
    
calendar.create();
  }
  
calendar.sel el;
  
calendar.parseDate(el.value);
  
calendar.showAtElement(el);
  
Calendar.addEvent(document"mousedown"checkCalendar);
  return 
false;
}


And the same block with the necessary changes:


function showCalendar(id) {
  var 
el xoopsGetElementById(id);
  if (
calendar != null) {
    
calendar.hide();
  } else {
    var 
cal = new Calendar('._CAL_MONDAYFIRST.'"' . $time . '"selectedcloseHandler); // THIS LINE CHANGED
    
calendar cal;
    
cal.setRange(20002015);
    
calendar.create();
  }
  
calendar.sel el;
  if (
el.value != "" && el.value != "'._DATE_DEFAULT.'") { // calendar.parseDate(el.value) is now inside a condition
      
calendar.parseDate(el.value);
  } else {
    
calendar.parseDate("'.$time.'");
  }
  
calendar.showAtElement(el);
  
Calendar.addEvent(document"mousedown"checkCalendar);
  return 
false;
}


That's it. I think this would be a great addition to Impress, addressing a very long standing issue. And there should be no effect on existing modules at all, this simply introduces the possibility of being precise about what the user meant by the value they submit in a datebox.

As a complement to this, it may be worth supporting an additional value in the initialization of date box elements: {TODAY} or something like that, which can be used if you truly want the current date to be the default value. Supporting {TODAY+7} and other notations like that would be pretty trivial too.

--Julian

Posted on: 2011/12/19 5:16
_________________
Technical Architect - Freeform Solutions
Formulize - ad hoc forms and reports for ImpressCMS
Transfer the post to other applications Transfer


Re: Allowing a non-date default value for date boxes in forms
Home away from home
Joined:
2007/12/4 9:00
Posts: 4108
You've been rather busy, I see! Thanks for all the feedback and suggestions, Julian!

The only question I have about this is allowing the date format to be defined in a constant or as a preference in the db, so it can follow the date formatting for the rest of the site. Do you see a way to do that?

Posted on: 2011/12/19 22:31
_________________
Steve
Twitter: @skenow
Facebook: Steve Kenow
Transfer the post to other applications Transfer


Re: Allowing a non-date default value for date boxes in forms
Just can't stay away
Joined:
2007/12/28 22:23
From Toronto, Canada
Posts: 79
Well the _SHORTDATEFORMAT constant or whatever its called, is still being respected, so that's not a problem. You could presumably make the _DATE_DEFAULT constant whatever you wanted, and in synch with the style of your short date format.

Or am I misunderstanding what you're getting at?

I think altering the constructor as below would be worthwhile, to continue to allow the current date to be used as the default, if that's truly what people want/require. Although, as written above any non-numeric value would also still default to the current date. Overall, the only logical change in this patch is altering the meaning of blank/empty initialization values, so that the box is correspondingly initialized with a blank/empty value.


if($value === "") {
  
$value _DATE_DEFAULT;
// check for {TODAY}, {TODAY-14} etc
} elseif(ereg_replace("[^A-Z{}]",""$value) === "{TODAY}") {
  
$number ereg_replace("[^0-9+-]",""$value);
   
$value mktime(000date("m") , date("d")+$numberdate("Y"));
} elseif(!
is_numeric($value)) { 
  
$value time();
} else {
  
$value intval($value);
}


Thanks many years ago to Formulize user dpicella who first wrote that handy date parsing regular expression goodness.

--Julian

Posted on: 2011/12/20 0:18
_________________
Technical Architect - Freeform Solutions
Formulize - ad hoc forms and reports for ImpressCMS
Transfer the post to other applications Transfer


Re: Allowing a non-date default value for date boxes in forms
Home away from home
Joined:
2007/12/4 9:00
Posts: 4108

Could you just replace _DATE_DEFAULT with _SHORTDATESTRING and eliminate the need for another constant?


The question about using a consistent date format is more a factor with the jscalendar - it uses its own patterns and returns a format different than the globally defined format.


Posted on: 2011/12/20 18:40
_________________
Steve
Twitter: @skenow
Facebook: Steve Kenow
Transfer the post to other applications Transfer


Re: Allowing a non-date default value for date boxes in forms
Just can't stay away
Joined:
2007/12/28 22:23
From Toronto, Canada
Posts: 79

The _SHORTDATESTRING uses the PHP codes for defining how the date should look, and they are not human readable in all cases.  So I think using another value makes more sense.  The _SHORTDATESTRING codes are also English-centric.  Y for year, for example, which may not be the right letter to use in other languages.


--Julian


Posted on: 2011/12/20 18:48
_________________
Technical Architect - Freeform Solutions
Formulize - ad hoc forms and reports for ImpressCMS
Transfer the post to other applications Transfer


Re: Allowing a non-date default value for date boxes in forms
Just can't stay away
Joined:
2007/12/28 22:23
From Toronto, Canada
Posts: 79
Also, some users might want to use "year-month-day" as the default. Or conversely..."no date selected" to be very explicit about the semantics. Afterall, you don't really need to show the user the format, you need to indicate that there's no date in the box. The date will auto-fill-in when they use the calendar, so telling them the format is kind of not-necessary. YYYY-mm-dd just implicitly says that there's no active date right now, which is really the point. Communicating the year-month-day format is completely secondary and superfluous really.

--Julian

Posted on: 2011/12/20 19:35
_________________
Technical Architect - Freeform Solutions
Formulize - ad hoc forms and reports for ImpressCMS
Transfer the post to other applications Transfer


Re: Allowing a non-date default value for date boxes in forms
Home away from home
Joined:
2007/12/4 9:00
Posts: 4108
Good points.

I've been trying to see this in action on my local server - can't quite get it all right. I'm using the trunk of Formulize as my base for this and I've pulled your changes from your standalone core for ImpressCMS 1.3.

My premise is I can create a form with a date select field and set the option to a default value to something like {TODAY+7}. However, this is inserting "" into the db for the field default and then the field renders with a date equivalent of 0 (1970/1/1).

Posted on: 2011/12/22 2:06
_________________
Steve
Twitter: @skenow
Facebook: Steve Kenow
Transfer the post to other applications Transfer


Re: Allowing a non-date default value for date boxes in forms
Just can't stay away
Joined:
2007/12/28 22:23
From Toronto, Canada
Posts: 79
Hi Steve,

That should work in general...though getting the {TODAY} thing to work probably can't be done from in Formulize right now, since if you make a formulize form and add a date element and try to configure it to have anything other than a date as the default value, then it will default itself to YYYY-mm-dd. I still need to alter Formulize to take advantage of this new {TODAY} functionality in terms of setting default dates.

So...

You could try this kind of proof of concept code...I think it will work...


include "mainfile.php";

// sorry, not sure what the official way to do this in impress is...
include ICMS_ROOT_PATH."/class/xoopsformloader.php"

// not sure of the exact name of the class, but you get the idea...
$testElement = new XoopsTextFormDateSelect('test element''testelement'15'{TODAY-7}');

print 
$testElement->render();


With the above core changes, that should render a datebox on screen that has the date one week ago in it. Without the above changes, it would render a box with the current date.

Similarly, if you pass in '' as the date, then it would render with the _DATE_DEFAULT constant.

If you pass in any number it will try to treat it as timestamp. If you pass in any other non-numeric value, it will use today's date.

Makes sense?

--Julian

Posted on: 2011/12/23 1:12
_________________
Technical Architect - Freeform Solutions
Formulize - ad hoc forms and reports for ImpressCMS
Transfer the post to other applications Transfer


Re: Allowing a non-date default value for date boxes in forms
Home away from home
Joined:
2009/3/3 4:18
From Belgium
Posts: 1751
Hi Julian,

thanks for your work on this. I think this is a very good candidate for the next version (and also the LTS version).

This kind of core change can make a huge difference to module developers, enabling them to do more things, and do them more easily.

More suggestions like this are always appreciated, certainly it they are as good documented as this one

Don't stop!

Posted on: 2011/12/28 15:10
_________________
ImpressCMS.TV - Video Tutorials
d-log - My personal site

Me on Ohloh
Transfer the post to other applications Transfer






You can view topic.
You cannot start a new topic.
You cannot reply to posts.
You cannot edit your posts.
You cannot delete your posts.
You cannot add new polls.
You cannot vote in polls.
You cannot attach files to posts.
You cannot post without approval.

[Advanced Search]