How to use dijit.Calendar directly in a form (rather than as a popup)

4.5k Views Asked by At

I'd like to have a dijit.form.Calendar embedded directly in my dojo form, rather than appearing as a popup (as dijit.form.DateTextBox provides; this is because the form is already a dropdown selector and just choosing a date would be much more natural than having to click again on the text box)

What's the easiest way to do this? I don't mind if the text box still appears and is editable (although that's not a requirement) - but the dijit.Calendar docs say explicitly that you can't use it as a form element because it doesn't provide an input.

2

There are 2 best solutions below

0
On BEST ANSWER

What I actually did was to create a new dijit widget that stores the value in a hidden text field. The basic idea follows in javascript and template, although the full implementation is more complex as it also includes using a custom calendar widget that also displays the time.

This has been cut down and not tested in this incarnation. I found that handling the constraints being passed through correctly and the value being fed back to the input was not a trivial task. Also widgetsInTemplate was critical to get this to load the calendar widget properly:

dojo.provide("custom.DateSelector");
dojo.require("dijit.form.DateTextBox");
dojo.declare("custom.DateSelector", dijit.form._DateTimeTextBox, {
    baseClass: "dijitTextBox dijitDateTextBox",
    _selector: "",
    type: "hidden",
    calendarClass: "dijit.Calendar",
    widgetsInTemplate: true,
    i18nModule: "custom",
    i18nBundle: "DateSelector",
    templateString: dojo.cache("custom", "template/DateSelector.html")
    _singleNodeTemplate: '<input class=dijit dijitReset dijitLeft dijitInputField" dojoAttachPoint="textbox,focusNode" autocomplete="off" type="${type}" ${!nameAttrSetting} />',
    value: new Date(),
    postCreate: function() {
        this.calendar.parentTextBox = this.textbox;
        this.inherited(arguments);
    }
});

Then the template looks roughly like this:

<div class="dijit dijitReset dijitInline dijitLeft" waiRole="presentation">
    <div class="dijitReset dijitInputField dijitInputContainer">
                <input class="dijitReset dijitInputInner" dojoAttachPoint='textbox,focusNode' autocomplete="off" ${!nameAttrSetting} type='${type}' constraints="{datePattern: '${constraints.datePattern}', timePattern: '${constraints.timePattern}'}"/>
                <div dojoType='${calendarClass}' dojoAttachPoint='calendar' id="${id}_calendar" constraints="{datePattern: '${constraints.datePattern}', timePattern: '${constraints.timePattern}'}" value='${value}'/>
        </div>
</div>
0
On

First Check out http://docs.dojocampus.org/dijit/Calendar

You are correct that this implementation of the calendar does not produce a form input. Here's how I have done it. Essentially when the user clicks a date we respond to the click by saving off the value to be used later.

//This function is called from via a "dojo.addOnLoad"
//It creates the calendar and defines an event for "onValueSelected"
function initCalendar() {
    dojo.declare("BigCalendar", dijit.Calendar, {
        onValueSelected: function(date){calendarDateClicked(date);}
    });

    bigCalendar = dojo.byId("calendarEvents");
    bigCalendar.setAttribute("dojoType", "BigCalendar");
    dojo.parser.parse(bigCalendar.parentNode);
}



function calendarDateClicked(date) {
// Here you can either take the date and put in into a text box (maybe hidden?) or save it off into an internal variable that you can later use in an ajax call or however you see fit.
}