/*!
Name:NiceTaggingPlugin
Description:Creates a nicer interface for adding and removing TiddlyWiki. Ideal for tiddly novices.
Version:0.6.6
Date:October 2010
Source:http://svn.tiddlywiki.org/Trunk/contributors/JonRobson/plugins/niceTagging/plugins/NiceTaggingPlugin.js
Author:Jon Robson
License:BSD open source license
CoreVersion:2.3
Dependencies:

Usage

<<niceTagger tags>> or <<niceTagger field>>

Additional Parameters

splitOn: <character>
valuesSource: <tiddler title>
textcase: <lower>

StyleSheet

.tip {font-style:italic;font-weight:bold;}
input.dp-applied {width: 140px; float: left;}
.niceTagger input {width:200px; float:left;}
.deleter {color:red; font-weight:bold; padding:2px; cursor:pointer;}
.ac_results {padding: 0px;border: 1px solid black;background-color: white;overflow: hidden;z-index: 99999;}
.ac_results ul {width: 100%;list-style-position: outside;list-style: none;padding: 0;margin: 0;}
.ac_results li {margin: 0px;padding: 2px 5px;cursor: default;display: block;font: menu;font-size: 12px;line-height: 16px;overflow: hidden;}
.ac_loading {background: white url('indicator.gif') right center no-repeat;}
.niceTaggerAdder input {width:auto; display: inline;}
.ac_odd {background-color: #eee;}
.ac_over {background-color: #0A246A;color: white;}
  • /
(function($) {

config.shadowTiddlers.NiceTaggingStyle = store.getTiddlerText(tiddler.title + "##StyleSheet");
store.addNotification("NiceTaggingStyle", refreshStyles);

String.prototype.toJSON = function(){
	var namedprms = this.parseParams(null, null, true);
	var options ={};
	for(var i=0; i < namedprms.length;i++){ 
		var nameval = namedprms[i];
		if(nameval.name) {
			options[nameval.name] = nameval.value;
		}
	}
	return options;
};

var macro = config.macros.niceTagger = {
	lingo:{
		add: "add"
	},
	twtags: {},
	initialised:{},
	init: function(field){
		field = !field ? 'tags' : field;
		if(this.initialised[field]){
			if(field == 'tags') {
				var numTags = store.getTags();
				if(numTags.length == this.twtags[field].length) {
					return;
				}
			} else {
				return;
			}
		}
		var tiddlers= store.getTiddlers();
		macro.twtags[field] = [];
		var uniqueSuggestions = [];
		for(var i=0; i < tiddlers.length; i++){
			var tid = tiddlers[i];
			var values;
			if(field=='tags') {
				values = tid.tags;
			} else {
				values= tid.fields[field];
				values = values ? values : "";
				values = values.readBracketedList();
			}
			for(var j=0; j < values.length; j++){
				uniqueSuggestions.pushUnique(values[j]);
			}
			
		}
		macro.twtags[field] = uniqueSuggestions;
		this.initialised[field] =true;
	},
	save: function(title, field, listvalues, place, autosavechanges) {
		var tiddler = store.getTiddler(title);
		var tiddlerEl = story.getTiddler(title);
		var valueToSave;
		valueToSave = String.encodeTiddlyLinkList(listvalues);
		var el = $("[edit=%0]".format([field]), tiddlerEl);
		if(el.length === 0) {
			el = $("<input />").attr("type", "hidden").attr("edit", field).appendTo(place);
		}
		el.val(valueToSave);

		var dummy = new Tiddler(title);
		if(field == "tags") {
			dummy.tags = listvalues;
		} else {
			dummy.fields[field] = valueToSave;
		}
		return dummy;
	},
	refreshFieldDisplay: function(place, tiddler, field) {
		var container = $(".niceTagger", place);
		container.empty();
		var values;
		if(!field || field == 'tags') {
			values = tiddler.tags;
		} else {
			values = tiddler.fields[field] ? tiddler.fields[field].readBracketedList() : [];
		}
		for(var t = 0; t < values.length; t++){
			var tag = values[t];
			$("<span />").addClass("tag").text(tag).appendTo(container);
			$("<span />").addClass("deleter").text("x").attr("deletes", escape(tag)).appendTo(container);
		}

		$(".deleter", place).click(function(ev){
			var todelete = $(ev.target).attr("deletes");
			var newValues = [];
			for(var i = 0; i < values.length; i++){
				var value = values[i];
				if(escape(value) != todelete) {
					newValues.push(value);
				}
			}
			tiddler = macro.save(tiddler.title, field, newValues, place, tiddler.autosavechanges);
			macro.refreshFieldDisplay(place, tiddler, field);
		});
	},
	saveNewValue: function(tiddler, field, value, container, splitChar) {
		var tiddlerEl = story.getTiddler(tiddler.title);
		var editEl = $("[edit=%0]".format([field]), tiddlerEl);
		var adder = $(".niceTaggerAdder input[type=text]", container);
		var saveThis;
		if(editEl.length > 0) {
			saveThis = editEl.val() || "";
			saveThis = saveThis.readBracketedList();
		} else {
			if(field == 'tags') {
				saveThis = tiddler.tags;
			} else {
				var val = tiddler.fields[field];
				val = val ? val : "";
				saveThis = val.readBracketedList();
			}
		}
		value = typeof(value) == 'string' ? value.trim() : value;
		if(value.length === 0) {
			return;
		}
		var newValues;
		if(splitChar && value && value.indexOf(splitChar) != -1){
			newValues = value.split(splitChar);
		} else {
			newValues = [value];
		}
		for(var i = 0; i < newValues.length;i++){
			var svalue = newValues[i];
			saveThis.pushUnique(svalue);
		}
		tiddler = macro.save(tiddler.title, field, saveThis, container, tiddler.autosavechanges);

		macro.refreshFieldDisplay(container, tiddler, field);
		$(adder).val("");
	},
	getSuggestionsFromTiddler: function(srcTiddler, textcase){
		var suggestions = [];
		if(srcTiddler){
			var src = store.getTiddler(srcTiddler);
			var text = src.text;
			var tempdiv = document.createElement("div");
			wikify(text, tempdiv, null, src);
			var html = $(tempdiv).html();
			suggestions = html.split(/<br\/?>/gi);
		}
		var finalSuggestions = [];
		for(var i=0; i < suggestions.length; i++){
			var val = suggestions[i].trim();
			if(textcase && textcase == "lower") {
				val = val.toLowerCase();
			}
			finalSuggestions.pushUnique(val);
		}
		return finalSuggestions;
	},
	removeFromList: function(list,removeList){
		var uniqueSuggestions = [];
		for(var i=0; i < list.length; i++){
			var s =list[i];
			if(s && typeof(s) == 'string'){
				if(uniqueSuggestions.indexOf(s) ==-1 && removeList.indexOf(s) ==-1){
					uniqueSuggestions.push(s);
				}
			}
		}
		return uniqueSuggestions;
	},
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var options = paramString.toJSON();
		var args = paramString.parseParams("anon")[0];
		if(options.autoSaveChanges) {
			tiddler.autosavechanges = true;
		}
		if(!options.field) {
			options.field = args.anon ? args.anon[0] : "tags";
		}
		this.init(options.field);
		var container = $("<div />").addClass("niceTaggerContainer").attr("field", options.field).
			appendTo(place)[0];
		var displayer = $("<div />").addClass("niceTagger").appendTo(container)[0];
		macro.refreshFieldDisplay(container, tiddler, options.field);
		var tagplace = $("<div />").addClass("niceTaggerAdder").appendTo(container)[0];
		var splitChar = options.splitOn;
		var adder;

		if($().autocomplete){
			params = paramString.parseParams("anon", null, true, false, false);
			var textcase = getParam(params, "case");
			var srcTiddler = getParam(params, "valuesSource");
			var suggestions;
			if(srcTiddler) {
				suggestions = macro.getSuggestionsFromTiddler(srcTiddler, textcase);
			} else {
				suggestions = [];
			}
			var tagsoff = getParam(params,"nostoretags");
			if(!tagsoff) {
				suggestions = suggestions.concat(macro.twtags[options.field]);
			}

			var ignoreList = paramString.parseParams("exclude", null, true, false, true);
			if(ignoreList && ignoreList[0] && ignoreList[0].exclude) {
				ignoreList = ignoreList[0].exclude;
			} else {
				ignoreList = ["excludeList"];
			}
			suggestions = macro.removeFromList(suggestions, ignoreList);

			var addtaghandler = function(v) {
				macro.saveNewValue(tiddler, options.field, $(v).val(), container, splitChar);
			};
			$("<input type='text' name=\""+options.field+"\" value=\"\"/>").autocomplete(suggestions,{ matchContains: true, selectFirst:false }).result(addtaghandler).appendTo(tagplace);
			adder = $("input", tagplace)[0];
		} else {
			adder = document.createElement("input");
			tagplace.appendChild(adder);
		}
		$(adder).keypress(function (ev) {
			ev.stopPropagation();
			if(ev.which == 13){
				var results = $(".ac_over",".ac_results"); //is anything highlighted in autocomplete plugin ?
				var value;
				if(results.length === 0) {
					value = $(ev.target).val();
				} else {
					value = $(results[0]).val();
				}
				macro.saveNewValue(tiddler, options.field, value, container, splitChar);
			}
		});
		var addbutton = document.createElement("input");
		addbutton.type = "button";
		addbutton.value = macro.lingo.add;
		addbutton.className = "adder";
		tagplace.appendChild(addbutton);
		$(addbutton).click(function(e){
			var val = $(adder).val() || "";
			macro.saveNewValue(tiddler, options.field, val, container, splitChar);
		});
	}	
};

_setTiddlerField = Story.prototype.setTiddlerField;
Story.prototype.setTiddlerField = function(title, value, mode, field) {
	var tiddler = store.getTiddler(title) || new Tiddler(title);
	var container = $(".niceTaggerContainer[field=%0]".format([field]), 
		story.getTiddler(title));
	if(container.length > 0) {
		macro.saveNewValue(tiddler, field, value, container[0]);
	} else {
		_setTiddlerField.apply(this, arguments);
	}
	
};
})(jQuery); //end alias
bag
nicetagging_public
created
Wed, 29 Sep 2010 18:28:47 GMT
creator
jon
modified
Fri, 10 Jun 2011 12:13:19 GMT
modifier
jon
tags
excludeLists
excludeSearch
systemConfig