hailwood / jQuery-Tagit

The Jquery Tagit Plugin transforms an html unordered list into a unique tagging plugin.
264 stars 109 forks source link

Feature request: Textfield instead of SelectList #55

Closed bschaf closed 12 years ago

bschaf commented 12 years ago

It would be great if Tagit would have an option to use a text field as its backing store instead of a select list. This would allow for graceful degradation, where a user could use a simple text field to enter tags. Another case is that in my Orchard module, I don't want it to rely on a specific UI, so I want to go with a text field as the default option. Then Orchard Themers can go ahead and leverage Tagit to beautify the tag editing experience. This tagit plugin uses a text field: https://github.com/aehlke/tag-it. The primary reason I am choosing Hailwood Tagit over Aehlke is because I don't think I want to be dependant on jQuery UI's themeroller themes. For the rest I haven't lookedinto depth.

sfmskywalker commented 12 years ago

Sounds like exactly that I need!

hailwood commented 12 years ago

Hi @tanmule and @sfmskywalker While tagit is not primarily designed around text inputs it can be done quite easily!

have a look at this jsfiddle: http://jsfiddle.net/hailwood/u8zj5/

I have also posted the important code below, this should allow you to progressively enhance your input, if tagit does not load then your users can still enter tags in whatever format you expect (maybe one,two,three?)

JS

$(document).ready(function() {

  //The demo tag array
  var availableTags = [
    {value: 1, label: 'tag1'},
    {value: 2, label: 'tag2'},
    {value: 3, label: 'tag3'}];

  //The text input
  var input = $("input#text");

  //The tagit list
  var instance = $("<ul class=\"tags\"></ul>");

  //Store the current tags
  //Note: the tags here can be split by any of the trigger keys
  //      as tagit will split on the trigger keys anything passed  
  var currentTags = input.val();

  //Hide the input and append tagit to the dom
  input.hide().after(instance);

  //Initialize tagit
  instance.tagit({
    tagSource:availableTags,
    tagsChanged:function () {

      //Get the tags            
      var tags = instance.tagit('tags');
      var tagString = [];

      //Pull out only value
      for (var i in tags){
        tagString.push(tags[i].value);
      }

      //Put the tags into the input, joint by a ','
      input.val(tagString.join(','));
    }
  });

  //Add pre-loaded tags to tagit
  instance.tagit('add', currentTags);
});​

HTML

<input type="text" id="text" name="tags" value="one,two,three"/>
sfmskywalker commented 12 years ago

I figured it could be done with custom javascript, I was just hoping that it could maybe be part of the plugin itself. Until then this code is quite useful, thanks!

hailwood commented 12 years ago

Well, I could theoretically modify the plugin so it will check if $(this) is an input, if so run the appropriate code, but I am concerned about the extra overhead there. I unfortunately was not really thinking about progressive enhancement when I created it (I have a terrible habit of working to a "javascript always runs" ideology) as as such, making it run only on the input would break backwards compatibility in ways that would make the plugin un-usable to a lot of people, also, working with only an input means that to pre-populate tags that have a different label than value would be forced to be loaded via Javascript, and it's a pain to output javascript via serverside code as a general rule!

sfmskywalker commented 12 years ago

You're right of course, almost every site depends on javascript. Having a text field is more useful for module development as the default input, enabling theme developers to go fancy and apply Tagit. Then again, Theme developers can easily use the select list as long as they use the correct name. I juts tried and works like a charm. I didn't think about the label/value support, and forcing them to be loaded via Javascript sounds nasty. Please feel free to close this thread.