Currently the jscalendar settings (ifFormat, etc...) are set up by adding keys ('#jscalendar_ifFormat' etc... ) to the ROOT of form.

This means one set of settings for all the jscalendar-enabled widgets in the form. This does seem an unnecessary restriction.

Plus this restricts the way you can delegate the form building to helper functions :
$form['my_date_widget'] = the_relevant_function($args);
Here, the_relevant_function might return a jscal-enabled form element, but not specify its settings, since it doesn't have access to the form root.

There are workarounds, obviously, and I even _think_ cck node form building code happens to be compatible with the current behaviour, but wouldn't it be much more natural to have the '#jscalendar_*' keys attached to the form element ?

$form['date_widget'] = array(
  '#type' => 'textfield',
  '#attributes' => array('class' => 'jscalendar'),
  '#jscalendar_ifFormat' => 'whatever',
);

Comments

yched’s picture

Status: Active » Needs review
StatusFileSize
new4.06 KB

Attached patch does that.

yched’s picture

StatusFileSize
new4.8 KB

update - forgot to remove an unnecessary function

yched’s picture

BTW, the jscalendar-enabled contrib modules I'm aware of (that is date.module, event.module) do rely on the 'per widget' settings format.

You can find the following in event.module, for instance :

$form['start_date'] = array(
            '#title' => t('Start Date'),
            '#type' => 'textfield',
            '#attributes' => array('class' => 'jscalendar'),
            '#jscalendar_ifFormat' => '%Y-%m-%d %H:%M',
            '#jscalendar_showsTime' => 'true',
            '#jscalendar_timeFormat' => variable_get('event_ampm', '0') == 0 ? '24' : '12',
            (...)
);

Meaning these settings are currently not taken into account.

karens’s picture

The event and date modules use the per-widget settings because that is what http://drupal.org/node/57981 said to do. I'm going to do some testing with and without this patch to try to confirm what is happening and whether the patch works.

yched’s picture

Look closer :-)
(below is copy / paste from nedjo's comment #5 in the post you mention)

$form['date'] = array(
    '#type' => 'textfield',
    '#attributes' => array('class' => 'jscalendar')
);
$form['#jscalendar_ifFormat'] = '%Y-%m-%d';

the 'jscalendar' class is for $form['date'], and the '#jscalendar_ifFormat' setting is for $form.

Well, it does seem couter-intuitive to me as well :-)

karens’s picture

Status: Needs review » Reviewed & tested by the community

The patch works great, exactly as described. It correctly interprets different settings on a per-widget basis instead of form-wide.

nedjo’s picture

Status: Reviewed & tested by the community » Fixed

Applied, thanks yched for the patch and Karen for the review.

yched’s picture

StatusFileSize
new1.09 KB

Thanks nedjo.
Here's the corresponding patch for README.txt

It seems you applied that to the HEAD branch. Maybe you could also apply it to 4.7 as well ?

yched’s picture

Status: Fixed » Reviewed & tested by the community

status for the README patch...

nedjo’s picture

Status: Reviewed & tested by the community » Fixed

Thanks, applied the changes to the readme and applied the patches also to 4.7.

Any further improvements you might want to contribute would be very welcome!

binford2k’s picture

This does not appear to be working correctly. This is what I have in my module:

<code>
    $form['startdate'] = array(
                    '#type' => 'textfield',
                    '#title' => t('Starting date'),
                    '#default_value' => $startdate,
                    '#size' => 60,
                    '#maxlength' => 255,
                    '#description' => t('Please enter the starting date for this position in the form <em>mont
h/day/year</em>, for example <em>6/27/1980</em>.'),
                    '#attributes' => array('class' => 'jscalendar'),
                    '#jscalendar_ifFormat' => '%m/%d/%Y',
                    '#jscalendar_showsTime' => 'false',
                );


and this is what appears in the HTML output:

<div class="form-item">
 <label for="edit-startdate">Starting date: </label>
 <input type="text" maxlength="255" name="edit[startdate]" id="edit-startdate"  size="60" value="09/30/2006" class="form-text jscalendar" />
 <div class="description">Please enter the starting date for this position in the form <em>month/day/year</em>, for example <em>6/27/1980</em>.</div>
</div>

In an entirely different part of the form, this appears:

<input type="hidden" name="edit[ifFormat]" id="edit-ifFormat" value=""  />
<input type="hidden" name="edit[showsTime]" id="edit-showsTime" value=""  /

In the jscalendar.js file, it looks to me as if it's looking for an id of edit-startdate_jscalendar-ifFormat, not edit-ifFormat.

I just downloaded jstools-cvs and updated Drupal core to the latest tarball today.

Am I missing something?

yched’s picture

@binford2k :
are you using drupal 4.7 or drupal HEAD (5.0) ?
I think Jstools-cvs is for HEAD.
With drupal 4.7 you should use http://ftp.osuosl.org/pub/drupal/files/projects/jstools-4.7.0.tar.gz
(listed in the "other releases" section on the jstools project page.

@nedjo : maybe it would be best if the "default" download package on the project page was 4.7 instead of HEAD ?

karens’s picture

I think it will work if you add '#tree' => true to your form array.

binford2k’s picture

@yched: I tried 4.7.0 and cvs and both had the same behaviour

@KarenS: '#tree' => true had no effect.

What should I check next?

karens’s picture

Where did you put tree=>true? It needs to be under 'startdate', not elsewhere in the form array.

karens’s picture

OK, I can replicate this problem, too. Like you, I am getting those hidden fields with no field name in them. Initially I thought #tree was fixing it, but I guess not. I think the forms api is misunderstanding something about what should be created here but I'm not sure what else to try, either.

karens’s picture

I had that backward. #tree=>TRUE needs to be *above* the element in the array to get the hidden values to work right. That tells the forms api not to collapse the form down to the name of the last element in the array. In my tests, adding #tree->TRUE to the parent of the element I am adding jscalendar to will create the right hidden value in the form.

Don't know if that fixes the problem, but I think it will create the right hidden value in the form.

karens’s picture

OK, I can confirm that adding #tree=>TRUE to the parent of my jscalendar element fixes the problems I was having. I think we should fix the documentation to indicate that the form array must have #tree set somewhere above the jscalendar element. (I started playing around with the idea of having jscalendar.module set it when it creates the hidden field, but there are lots of ways that might break the form, so fixing the documentation is probably a better solution).

yched’s picture

Status: Fixed » Needs review
StatusFileSize
new820 bytes

There was in fact a problem - thanks binford2k for finding this.

This patch _should_ take care of the #tree thing without messing with the form.
It seems to works on my test form, on the date.module jscal widgets (blink Karen), and on the jscal widget used by some Views filters (which currently don't use jscal options, but I tried to add some just to see...)

Could you both please test this on your own test forms ?

Patch if against 4.7.

yched’s picture

I mean "Patch IS against 4.7"...

karens’s picture

Status: Needs review » Reviewed & tested by the community

Works fine on my test form. I didn't check the date.module forms since you said you tested them :-)

stefano73’s picture

StatusFileSize
new2.02 KB

I made a patch for jsCalendar to make the Unix timestamp readily available when users choose a different date through the calendar. The timestamp is updated by the calendar and saved in a hidden field, and it can be read in the submit function by the $_POST variable (seems that the $form_values gets the original values for hidden fields, so the changes are available in $_POST only...).
Here I explain my changes.

In the jscalendar.module I added the "timestamp" hidden field, and set the other fileds as disabled, as the submit doesn't need them.

function jscalendar_form_alter($form_id, &$form) {
  ........
      $settings = array('timestamp', 'ifFormat', 'showsTime', 'timeFormat');
      foreach ($settings as $setting) {
	if (isset($form[$key]['#jscalendar_'.$setting])) {
	  $form[$key.'_jscalendar']['#tree'] = true;
          $form[$key.'_jscalendar'][$setting] = array(
            '#type' => 'hidden',
            '#value' => $form[$key]['#jscalendar_'.$setting],
          );
	  if ($setting != 'timestamp') {
	    // disable values not necessary in form submit
	    $form[$key.'_jscalendar'][$setting]['#attributes']['disabled'] = TRUE;
	  }
          unset($form[$key]['#jscalendar_'.$setting]);
        }
      }
    }
............
  }
}

In the jscalendar.js I passed the timestamp field as a parameter, and added the code to fire when the calendar is updated. The cal.date.print('%s') is the unix timestamp for the chosen date.

        Calendar.setup(
          {
            inputField  : input.id,
            ifFormat    : settings['ifFormat'],
            button      : input.getAttribute('id') + '-button',
            showsTime   : settings['showsTime'],
            timeFormat  : settings['timeFormat'],
            timestamp   : $(input.id+'_jscalendar-timestamp'),
            onUpdate    : calendarUpdated
          }
        );

function calendarUpdated(cal) {
  // update timestamp hidden value
  var timestamp = cal.params.timestamp;
  if (timestamp) timestamp.value = cal.date.print('%s');
}

In the form submit function the unix timestamp is available by the $_POST variable:

$start_date = $_POST['startdate_jscalendar']['timestamp'];

PS: the attached patch was made on the fly from my cvs version, hope there's no bug in it. In next follow up I'll post the cvs updated patch with the jquery code.

stefano73’s picture

StatusFileSize
new6.52 KB

Here is the patch to make it work with latest cvs version.

yched’s picture

stefano73 : I'm sorry but unless I'm missing something, this has nothing to in this thread - please submit your patch in a separate issue. Let's not mix patches :-)

The RTBC patch for "per widget jscal settings" is in comment #19

binford2k’s picture

@yched: works for me too. Thanks much!

nedjo’s picture

Status: Reviewed & tested by the community » Fixed

@yched thanks, applied.

@stefano73: thanks for the suggested patch, please do move it to a new issue. You can just post the patch there with a quick explanation and reference this issue, e.g., "moved from http://drupal.org/project/comments/add/80746".

Anonymous’s picture

Status: Fixed » Closed (fixed)