Hi ajshort,
I tried using Javascript "Behaviour.register" as you suggested and it works perfectly. It's much more flexible than any built-in conditional CMS field would be. I still stick to my solution to add an additional tab to the Content fieldset, but I could use "Bevaviour.register" for a number of other things (e.g. update the initial event name based on the value in the page title field and to create a set of predefined locations). See an example below.
If anyone needs more details about it, this is what I did to add event details to my blog entries. It's just an example which I hope may help someone who is new to extending the Silverstripe CMS:
1. Creating additional database fields
I added event details to the BlogEntry Page Type, but it can be added to any page type with minor adjustments.
In /blog/code/BlogEntry.php in the BlogEntry class, add these lines to the "static $db" array:
"IsEvent" => "Boolean",
"EventName" => "Text",
"EventStartDate" => "Datetime",
"EventEndDate" => "Datetime",
"EventLocation" => "Text",
"EventMapUrl" => "Text"
2. Add the fields to the CMS interface
In the BlogEntry::getCMSFields function (before "return $fields"):
// aditional event information
$fields->addFieldToTab("Root.Content.EventInfo", new CheckboxField("IsEvent", "This is an event"));
$fields->addFieldToTab("Root.Content.EventInfo", new TextField("EventName", "Event Name"));
$fields->addFieldToTab("Root.Content.EventInfo", new PopupDateTimeField("EventStartDate", "Start Date"));
$fields->addFieldToTab("Root.Content.EventInfo", new PopupDateTimeField("EventEndDate", "End Date"));
// optional: quick location chooser: change default values in /blog/javascript/eventbehaviours.js
$quickLocations = array(
1 => "Sample Location #1",
2 => "Sample Location #2"
);
$fields->addFieldToTab("Root.Content.EventInfo", new DropdownField("QuickLocation", "Quick Location Chooser", $quickLocations, $value = false, $form = null, $emptyOption = "select a default location"));
// not optional
$fields->addFieldToTab("Root.Content.EventInfo", new TextAreaField("EventLocation", "Location", 3));
$fields->addFieldToTab("Root.Content.EventInfo", new TextField("EventMapUrl", "Google Maps URL (<a href=\"http://maps.google.com\" target=\"_blank\">open Google Maps</a>)"));
3. Adding Javascript to the CMS
This step is optional, but I find it quite useful.
Add this line /blog/code/BlogEntry.php to the BlogEntry::getCMSFields function:
Requirements::javascript('blog/javascript/eventbehaviours.js');
Content of /blog/javascript/eventbehaviours.js:
// optional: adding values for default locations
Behaviour.register({
'#Form_EditForm_QuickLocation': {
onchange: function() {
EventLocation = document.getElementById("Form_EditForm_EventLocation");
EventMapUrl = document.getElementById("Form_EditForm_EventMapUrl");
switch(this.options.selectedIndex) {
case 1:
EventLocation.value = "Sample Location #1";
EventMapUrl.value = "http://maps.google.com/maps?f=q&hl=en&geocode=&q=etc...complete+link+no.1+here";
break;
case 2:
EventLocation.value = "Sample Location #2";
EventMapUrl.value = "http://maps.google.com/maps?f=q&hl=en&geocode=&q=etc...complete+link+no.2+here";
break;
// etc ...
}
},
initialize: function() {
this.onchange();
}
}
});
Behaviour.register({
'#Form_EditForm_Title': {
onblur: function() {
EventName = document.getElementById("Form_EditForm_EventName");
if(EventName.value == "" || EventName.value == "New BlogEntry"){
EventName.value = this.value;
}
},
initialize: function() {
this.onblur();
}
}
});
Behaviour.register({
'#Form_EditForm_EventStartDate_Date': {
onblur: function() {
EventEndDate_Date = document.getElementById("Form_EditForm_EventEndDate_Date");
if(EventEndDate_Date.value == ""){
EventEndDate_Date.value = this.value;
}
},
initialize: function() {
this.onblur();
}
}
});
Go to your site and rebuild the database http://www.mysilverstripesite.com/db/build/?flush=1 .
4. Adding event infos to the template
Now you can use the created event detail fields in the template, in the /blog/templates/Layout/BlogEntry.ss and/or /blog/templates/Includes/BlogSummary.ss (after the $Content variable). This is a simple example:
<% if IsEvent %>
<div class="eventDetails">
<h3>$EventName</h3>
($EventStartDate.Ago)<br />
$EventStartDate.Nice to $EventEndDate.Nice<br />
$EventLocation
<% if EventMapUrl %>
(<a href="$EventMapUrl.XML" title="View a map">Map</a>)
<% end_if %>
</div>
<% end_if %>
It's then quite easy to make further additions such as a widget that displays future events in the Sidebar, parse the map URL to embed a Map of the event location with e.g. Google Maps API, etc... - but I guess this post is already too long now...
This post is just another example to see how flexible and how easy it is to extend Silverstripe. I hope it's useful for someone.
Cheers!
Anatol