Skip to content
Browse files

ENHANCEMENT Refactored SiteTreeURLSegmentField JS to a more selector …

…based approach (future proof field for reusability e.g. in ModelAdmin with custom DataObject URL previews)
  • Loading branch information...
1 parent 526120d commit 1863bb00db764ef4a1695273816a8110c8f64ab9 @chillu chillu committed May 10, 2012
View
3 code/controllers/CMSMain.php
@@ -67,7 +67,8 @@ public function init() {
CMS_DIR . '/javascript/CMSMain.AddForm.js',
CMS_DIR . '/javascript/CMSPageHistoryController.js',
CMS_DIR . '/javascript/CMSMain.Tree.js',
- CMS_DIR . '/javascript/SilverStripeNavigator.js'
+ CMS_DIR . '/javascript/SilverStripeNavigator.js',
+ CMS_DIR . '/javascript/SiteTreeURLSegmentField.js'
),
Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang', true, true)
)
View
7 code/forms/SiteTreeURLSegmentField.php
@@ -20,6 +20,11 @@ class SiteTreeURLSegmentField extends TextField {
static $allowed_actions = array(
'suggest'
);
+
+ function Field($properties = array()) {
+ Requirements::javascript(CMS_DIR . '/javascript/SiteTreeURLSegmentField.js');
+ return parent::Field($properties);
+ }
function suggest($request) {
if(!$request->getVar('value')) return $this->httpError(405);
@@ -76,7 +81,7 @@ function getURLPrefix(){
function Type() {
- return 'text sitetreeurlsegment';
+ return 'text urlsegment';
}
}
View
11 code/model/SiteTree.php
@@ -168,6 +168,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
'Title',
'Content',
);
+
+ static $field_labels = array(
+ 'URLSegment' => 'URL'
+ );
/**
* @see SiteTree::nested_urls()
@@ -1829,7 +1833,12 @@ function getCMSFields() {
$url = (strlen($baseLink) > 36) ? "..." .substr($baseLink, -32) : $baseLink;
$urlsegment = new SiteTreeURLSegmentField("URLSegment", $this->fieldLabel('URLSegment'));
$urlsegment->setURLPrefix($url);
- $urlsegment->setHelpText(self::nested_urls() && count($this->Children()) ? $this->fieldLabel('LinkChangeNote'): false);
+ $helpText = (self::nested_urls() && count($this->Children())) ? $this->fieldLabel('LinkChangeNote') : '';
+ if(!URLSegmentFilter::$default_allow_multibyte) {
+ $helpText .= $helpText ? '<br />' : '';
+ $helpText .= _t('SiteTreeURLSegmentField.HelpChars', ' Special characters are automatically converted or removed.');
+ }
+ $urlsegment->setHelpText($helpText);
$fields = new FieldList(
$rootTab = new TabSet("Root",
View
12 css/screen.css
@@ -21,14 +21,10 @@
.cms-content-tools #cms-content-treeview .cms-tree .badge, .cms-content-tools #cms-content-treeview .cms-tree a > .jstree-icon { display: none; }
/** ------------------------------------------------------------------ URLSegment field ----------------------------------------------------------------- */
-.URLPrefix, .URLSegmentHolder { padding-top: 8px; display: inline-block; }
-
-.URLPrefix { color: #777; }
-
-#Form_EditForm_URLSegment { margin-left: 7px; }
-#Form_EditForm_URLSegment.disabled { color: #444; padding-left: 0px; margin-left: 0px; background: none; border-color: transparent; }
-
-#Form_EditForm_URLSegment_Cancel, #Form_EditForm_URLSegment_Update, #Form_EditForm_URLSegment_Edit { margin-left: 7px; }
+.field.urlsegment.disabled { color: #444; padding-left: 0px; margin-left: 0px; background: none; border-color: transparent; }
+.field.urlsegment .prefix, .field.urlsegment .preview { padding-top: 8px; display: inline-block; }
+.field.urlsegment .prefix { color: #777; }
+.field.urlsegment .cancel, .field.urlsegment .update, .field.urlsegment .edit { margin-left: 7px; }
.cms .AssetAdmin .cms-content-fields { overflow: hidden; }
.cms .AssetAdmin .cms-content-fields .cms-edit-form.AssetAdmin { overflow-y: auto; }
View
223 javascript/CMSMain.EditForm.js
@@ -16,227 +16,6 @@
});
/**
- * Class: .cms-edit-form input[name=URLSegment]
- *
- * Input validation on the URLSegment field
- */
- $('.cms-edit-form input[name=URLSegment]').entwine({
-
- /**
- * Constructor: onmatch
- */
- onmatch : function() {
- var self = this;
-
- // add elements and actions for editing
- self._addActions();
- // toggle
- self.edit();
- // set width of input field
- self._autoInputWidth();
-
- this._super();
- },
-
- /**
- * Function: edit
- *
- * Toggles the edit state of the field
- *
- * Return URLSegemnt val()
- *
- * Parameters:
- * (Bool) external (optional)
- */
- edit: function(external) {
-
- var self = this,
- holder = $('#URLSegmentHolder'),
- edit = $('#Form_EditForm_URLSegment_Edit'),
- update = $('#Form_EditForm_URLSegment_Update'),
- cancel = $('#Form_EditForm_URLSegment_Cancel');
-
- // transfer current value to holder
- holder.text(self.val());
-
- // toggle elements
- if (self.is(':visible')) {
- update.hide();
- cancel.hide();
- self.hide();
- holder.show();
- edit.show();
- } else {
- edit.hide();
- holder.hide();
- self.show();
- update.show();
- cancel.show();
- }
-
- // field updated from another fields value
- // reset to original state
- if (external) {
- self.edit();
- }
-
- return self.val();
- },
-
- /**
- * Function: update
- *
- * Commits the change of the URLSegment to the field
- * Optional: pass in another element to use its value
- * to update the URLSegment (ex. from Title)
- *
- * Parameters:
- * (jQuery Wrapped DOM element) field (optional)
- */
- update: function(field) {
-
- var self = this,
- holder = $('#URLSegmentHolder'),
- currentVal = holder.text(),
- updateVal,
- external = null;
-
- if (field && field.val() != "") {
- updateVal = field.val();
- external = true;
- } else {
- updateVal = self.val();
- }
-
- if (currentVal != updateVal) {
-
- self.suggest(updateVal, function(data) {
- var newVal = decodeURIComponent(data.value);
- self.val(newVal);
- self.edit(external);
- });
-
- } else {
-
- self.edit();
- }
- },
-
- /**
- * Function: cancel
- *
- * Cancels any changes to the field
- *
- * Return URLSegemnt val()
- *
- */
- cancel: function() {
-
- var self = this,
- holder = $('#URLSegmentHolder');
- self.val(holder.text());
- self.edit();
-
- return self.val();
- },
-
- /**
- * Function: suggest
- *
- * Return a value matching the criteria.
- *
- * Parameters:
- * (String) val
- * (Function) callback
- */
- suggest: function(val, callback) {
-
- $.get(
- this.parents('form:first').attr('action') +
- '/field/URLSegment/suggest/?value=' + encodeURIComponent(val),
- function(data) {
- callback.apply(this, arguments);
- }
- );
-
- },
-
- /**
- * Function: _addActions
- *
- * Utility to add edit buttons and actions
- *
- */
- _addActions: function() {
-
- var self = this,
- holder,
- editAction,
- updateAction,
- cancelAction;
-
- // element to display non-editable text
- holder = $('<span />', {
- 'id': 'URLSegmentHolder'
- });
-
- // edit button
- editAction = $('<button />', {
- 'id': 'Form_EditForm_URLSegment_Edit',
- 'class': 'ss-ui-button',
- 'text': 'Edit',
- 'click': function(e) {
- e.preventDefault();
- self.edit();
- }
- });
-
- // update button
- updateAction = $('<button />', {
- 'id': 'Form_EditForm_URLSegment_Update',
- 'text': 'OK',
- 'click': function(e) {
- e.preventDefault();
- self.update();
- }
- });
-
- // cancel button
- cancelAction = $('<a />', {
- 'id': 'Form_EditForm_URLSegment_Cancel',
- 'href': '#',
- 'text': 'cancel',
- 'click': function(e) {
- e.preventDefault();
- self.cancel();
- }
- });
-
- // insert elements
- holder.insertAfter('.URLPrefix');
- editAction.insertAfter(self);
- cancelAction.insertAfter(self);
- updateAction.insertAfter(self);
- },
-
- /**
- * Function: _autoInputWidth
- *
- * Sets the width of input so it lines up with the other fields
- *
- */
- _autoInputWidth: function() {
- var self = this,
- prefix_width,
- new_width;
-
- prefix_width = $('.URLPrefix').width();
- new_width = ((self.width() + 9) - prefix_width);
- self.width(new_width);
- }
- });
-
- /**
* Class: .cms-edit-form input[name=Title]
*
* Input validation on the Title field
@@ -255,7 +34,7 @@
self.updatePageTitleHeading();
self.parents('form').find('input[name=MetaTitle], input[name=MenuTitle]').val(self.val());
// update the URLSegment
- URLSegment.update(self);
+ URLSegment.closest('.urlsegment').update(self);
} else {
return;
}
View
208 javascript/SiteTreeURLSegmentField.js
@@ -0,0 +1,208 @@
+(function($) {
+ $.entwine('ss', function($) {
+ /**
+ * Class: .field.urlsegment
+ *
+ * Input validation on the URLSegment field
+ */
+ $('.field.urlsegment').entwine({
+
+ /**
+ * Constructor: onmatch
+ */
+ onmatch : function() {
+ this._addActions(); // add elements and actions for editing
+ this.edit(); // toggle
+ this._autoInputWidth(); // set width of input field
+
+ this._super();
+ },
+
+ /**
+ * Function: edit
+ *
+ * Toggles the edit state of the field
+ *
+ * Return URLSegemnt val()
+ *
+ * Parameters:
+ * (Bool) external (optional)
+ */
+ edit: function(external) {
+
+ var field = this.find(':text'),
+ holder = this.find('.preview'),
+ edit = this.find('.edit'),
+ update = this.find('.update'),
+ cancel = this.find('.cancel'),
+ help = this.find('.help');
+
+ // transfer current value to holder
+ holder.text(field.val());
+
+ // toggle elements
+ if (field.is(':visible')) {
+ update.hide();
+ cancel.hide();
+ field.hide();
+ holder.show();
+ edit.show();
+ help.hide();
+ } else {
+ edit.hide();
+ holder.hide();
+ field.show();
+ update.show();
+ cancel.show();
+ help.show();
+ }
+
+ // field updated from another fields value
+ // reset to original state
+ if (external) this.edit();
+
+ return field.val();
+ },
+
+ /**
+ * Function: update
+ *
+ * Commits the change of the URLSegment to the field
+ * Optional: pass in another element to use its value
+ * to update the URLSegment (ex. from Title)
+ */
+ update: function() {
+
+ var self = this,
+ field = this.find(':text'),
+ holder = this.find('.preview'),
+ currentVal = holder.text(),
+ updateVal,
+ external = null;
+
+ if (field && field.val() !== "") {
+ updateVal = field.val();
+ external = true;
+ } else {
+ updateVal = field.val();
+ }
+
+ if (currentVal != updateVal) {
+ self.suggest(updateVal, function(data) {
+ var newVal = decodeURIComponent(data.value);
+ field.val(newVal);
+ self.edit(external);
+ });
+ } else {
+ self.edit();
+ }
+ },
+
+ /**
+ * Function: cancel
+ *
+ * Cancels any changes to the field
+ *
+ * Return URLSegemnt val()
+ *
+ */
+ cancel: function() {
+ var field = this.find(':text'),
+ holder = this.find('.preview');
+ field.val(holder.text());
+ this.edit();
+
+ return field.val();
+ },
+
+ /**
+ * Function: suggest
+ *
+ * Return a value matching the criteria.
+ *
+ * Parameters:
+ * (String) val
+ * (Function) callback
+ */
+ suggest: function(val, callback) {
+ var field = this.find(':text');
+ $.get(
+ this.closest('form').attr('action') +
+ '/field/' + field.attr('name') + '/suggest/?value=' + encodeURIComponent(val),
+ function(data) {
+ callback.apply(this, arguments);
+ }
+ );
+
+ },
+
+ /**
+ * Function: _addActions
+ *
+ * Utility to add edit buttons and actions
+ *
+ */
+ _addActions: function() {
+ var self = this,
+ field = this.find(':text'),
+ preview,
+ editAction,
+ updateAction,
+ cancelAction;
+
+ // element to display non-editable text
+ preview = $('<span />', {
+ 'class': 'preview'
+ });
+
+ // edit button
+ editAction = $('<button />', {
+ 'class': 'ss-ui-button ss-ui-button-small edit',
+ 'text': 'Edit',
+ 'click': function(e) {
+ e.preventDefault();
+ self.edit();
+ self.find(':text').focus();
+ }
+ });
+
+ // update button
+ updateAction = $('<button />', {
+ 'class': 'update ss-ui-button-small',
+ 'text': 'OK',
+ 'click': function(e) {
+ e.preventDefault();
+ self.update();
+ }
+ });
+
+ // cancel button
+ cancelAction = $('<button />', {
+ 'class': 'cancel ss-ui-action-minor ss-ui-button-small',
+ 'href': '#',
+ 'text': 'cancel',
+ 'click': function(e) {
+ e.preventDefault();
+ self.cancel();
+ }
+ });
+
+ // insert elements
+ preview.insertAfter('.prefix');
+ editAction.insertAfter(field);
+ cancelAction.insertAfter(field);
+ updateAction.insertAfter(field);
+ },
+
+ /**
+ * Function: _autoInputWidth
+ *
+ * Sets the width of input so it lines up with the other fields
+ */
+ _autoInputWidth: function() {
+ var field = this.find(':text');
+ field.width((field.width() + 9) - this.find('.prefix').width());
+ }
+ });
+ });
+}(jQuery));
View
2 lang/en.yml
@@ -351,7 +351,7 @@ en:
TABMETA: Metadata
TOPLEVEL: 'Site Content (Top Level)'
TOPLEVELCREATORGROUPS: 'Top level creators'
- URLSegment: 'URL Segment'
+ URLSegment: 'URL'
VIEWERGROUPS: 'Viewer Groups'
VIEW_ALL_DESCRIPTION: 'View any page'
VIEW_ALL_HELP: 'Ability to view any page on the site, regardless of the settings on the Access tab. Requires the "Access to Site Content" permission'
View
31 scss/_CMSMain.scss
@@ -90,30 +90,27 @@
/** ------------------------------------------------------------------
* URLSegment field
* ----------------------------------------------------------------- */
-.URLPrefix,
-.URLSegmentHolder {
- padding-top: 8px;
- display: inline-block;
-}
-
-.URLPrefix {
- color: #777;
-}
+.field.urlsegment {
-#Form_EditForm_URLSegment {
- margin-left: 7px;
-
&.disabled {
color: #444;
padding-left: 0px;
margin-left: 0px;
background: none;
border-color: transparent;
}
-}
-#Form_EditForm_URLSegment_Cancel,
-#Form_EditForm_URLSegment_Update,
-#Form_EditForm_URLSegment_Edit {
- margin-left: 7px;
+ .prefix,
+ .preview {
+ padding-top: 8px;
+ display: inline-block;
+ }
+
+ .prefix {
+ color: #777;
+ }
+
+ .cancel, .update, .edit {
+ margin-left: 7px;
+ }
}
View
2 templates/forms/SiteTreeURLSegmentField.ss
@@ -1,4 +1,4 @@
-<span class="URLPrefix">$URLPrefix</span><input $AttributesHTML />
+<span class="prefix">$URLPrefix</span><input $AttributesHTML />
<% if HelpText %>
<p class="help">$HelpText</p>
<% end_if %>

0 comments on commit 1863bb0

Please sign in to comment.
Something went wrong with that request. Please try again.