Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Archive /

Our old forums are still available as a read-only archive.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo

adding a tag dropdown field to the blog module


Go to End


3 Posts   2272 Views

Avatar
Anatol

126 Posts

29 August 2008 at 4:54pm

Edited: 29/08/2008 5:00pm

Hi,

if anyone is interested in this: I didn't always want to check in the frontend if an existing tag might suit to a new blog entry, so I added a dropdown field to my blog module that gives me a list of all existing tags. The dropdown field then adds the selected tag to the comma separated tag list. It's quite straightforward:

In /blog/code/BlogEntry.php add this to the BlogEntry::getCMSFields() method before the "Tags" textfield definition:

$fields->addFieldToTab("Root.Content.Main", new DropdownField("ExistingTags", "Add existing tag/s",$this->TagsCollectionArray()), "Content");

(This field uses Javascript only and does not require a database field.)

Add the following function to the BlogEntry class to create an array with all existing tags except the ones that are already used for the blog entry:

function TagsCollectionArray() {

		// get the tags from all blog entries from the database
		$tags = DB::query("SELECT Tags FROM BlogEntry WHERE Tags != '';");

		// create a string with all tags (comma separated)	
		foreach($tags as $tag){
			$tagString .= $comma.$tag['Tags'];
			$comma = ',';
		}

		// creat an array from the comma separated string
		$allTags = explode(',',$tagString);
		
		// make sure there is no whitespace before or after the tag
		foreach($allTags as &$tag) {
			$tag = trim($tag);
		}

		// remove duplicates
		$allTags = array_unique($allTags);
		
		// get the tags from the selected blog entry
		$itemTags = split(" *, *", trim($this->Tags));

		// remove tags from the array that are already assigned to the blog entry
		$allTags = array_diff($allTags, $itemTags);
		
		// order the array alphabetically
		natcasesort($allTags);

		// add a 'select a tag' text as the first option
		array_unshift($allTags, 'select a tag');

		return $allTags;
	}

Now all that's left is to add some javascript. Still in /blog/code/BlogEntry.php add this line to the BlogEntry::getCMSFields() method to load an external Javascript file:

Requirements::javascript('blog/javascript/eventbehaviours.js');

Create the new file /blog/javascript/eventbehaviours.js:

// register an onchange behaviour
Behaviour.register({
	'#Form_EditForm_ExistingTags': {
		onchange: function() {
			Tags = document.getElementById("Form_EditForm_Tags");
			var comma = '';

			// the first option in the dropdown list is the text 'select a tag', so ignore this option
			if (this.selectedIndex > 0) {

				// add the selected tag, separated with a comma (if necessary)
				if (Tags.value != '') {
					comma = ', ';
				}
				Tags.value += comma + this.options[this.selectedIndex].innerHTML;
				
				// after the tag has been added to the blog entry remove it from the dropdown list
				this.options[this.selectedIndex] = null;
			}
		},
		initialize: function() {
			this.onchange();
		}
	}
});

That's it. Now just reload the CMS backend.

Cheers!
Anatol

Avatar
Willr

Forum Moderator, 5523 Posts

29 August 2008 at 10:36pm

Might want to add this as a recipe on the wiki to make it easy to find :D

http://doc.silverstripe.com/doku.php?id=recipes:start

Avatar
Anatol

126 Posts

30 August 2008 at 9:36am

Will do some time next week.

Cheers!
Anatol