Permalink
Browse files

detrsoy, maxChars, maxCount, allowNotInList, bug : positioning

  • Loading branch information...
1 parent 440b9b7 commit 7f5249072235ca202fe9d6ef86a253c141c078d5 @baio committed Aug 28, 2011
Showing with 191 additions and 7 deletions.
  1. +122 −7 js/tag-it.js
  2. +69 −0 my_example.html
View
@@ -75,7 +75,20 @@
// Event callbacks.
onTagAdded : null,
onTagRemoved: null,
- onTagClicked: null
+ onTagClicked: null,
+
+ //user input restrictions
+ //max number of characters in single tag
+ maxChars : 0,
+ //max number of tags
+ maxCount : 0,
+ //allow tags which are not in tagSource list
+ allowNotInList : true,
+
+ //events raised when user input restrictions occurs
+ onMaxChars : null,
+ onMaxCount : null,
+ onNotAllowed : null
},
@@ -128,6 +141,17 @@
}
});
+ //Set input tag default width
+ this._updateInputTagWidth();
+
+ // Position, must be inherited from original html element (position, top, left, width)
+ this.tagList.css({
@grisevg

grisevg Sep 6, 2011

What is that for?

@baio

baio Sep 6, 2011

Owner

when original element has absolute position, widget must be displayed at the same one

@grisevg

grisevg Sep 6, 2011

Maybe margins should be applied too then? And original 'display' property should be used too.

@baio

baio Sep 7, 2011

Owner

Yes will check it today evening.

+ position : this.element.css("position"),
+ top : this.element.css("top"),
+ left : this.element.css("left"),
+ width : this.element.css("width")
+ });
+
// Add existing tags from the list, if any.
this.tagList.children('li').each(function() {
if (!$(this).hasClass('tagit-new')) {
@@ -167,11 +191,11 @@
} else if (that.options.removeConfirmation) {
that._lastTag().removeClass('remove ui-state-highlight');
}
-
+
// Comma/Space/Enter are all valid delimiters for new tags,
// except when there is an open quote or if setting allowSpaces = true.
// Tab will also create a tag, unless the tag input is empty, in which case it isn't caught.
- if (
+ else if (
event.which == $.ui.keyCode.COMMA ||
event.which == $.ui.keyCode.ENTER ||
(
@@ -192,16 +216,70 @@
)
) {
event.preventDefault();
- that.createTag(that._cleanedInput());
+
+ //if we are here then tag has been created by typing and hence supposed not from list of tags.
+ //Creating tags which are not from list is only available when options.allowNotInList = true
+ if (that.options.allowNotInList !== false){
+ that.createTag(that._cleanedInput());
+ }
+ else{
+ that._trigger("onNotAllowed", event, that);
+ }
+
+ //The bottom comment doesn't valid now. All works without forced 'close'
// The autocomplete doesn't close automatically when TAB is pressed.
// So let's ensure that it closes.
- that._tagInput.autocomplete('close');
+ //that._tagInput.autocomplete('close');
}
+ else{
@grisevg

grisevg Sep 6, 2011

Please, fix that

@baio

baio Sep 6, 2011

Owner

Will check it. When I tested it, all works fine without hat._tagInput.autocomplete('close'); Can you please give me more details why this line necessary (the comment above this line is not valid, I belive)

@grisevg

grisevg Sep 6, 2011

I'm talking about:
}
else{

it just wroooong

@baio

baio Sep 7, 2011

Owner

oh got it

+ var func;
+
+ //check restrictions on maxCharCount and on maxCount
+ if (event.which != $.ui.keyCode.BACKSPACE && event.which != $.ui.keyCode.TAB){
+
+ //check if text in the input tag has length less than options.maxChars
+
+ if(that.options.maxChars && $.trim(that._tagInput.val()).length === that.options.maxChars){
@grisevg

grisevg Sep 6, 2011

What if $.trim(that._tagInput.val()).length > that.options.maxChars ?

@baio

baio Sep 6, 2011

Owner

It just can't be, to assure this of cause can be used $.trim(that._tagInput.val()).length >= that.options.maxChars

@grisevg

grisevg Sep 6, 2011

Copy, Paste 200 chars? It can. And even if it couldn't, still >= would be better, you never can be sure.

@baio

baio Sep 7, 2011

Owner

will fix

+ func = "onMaxChars";
+ }
+
+ //check if number of tags less than options.maxCount
+
+ if(that.options.maxCount && that.assignedTags().length == that.options.maxCount){
+ func = "onMaxCount";
+ }
@grisevg

grisevg Sep 6, 2011

What if both events happened? And you have wrong indentation here.

@baio

baio Sep 7, 2011

Owner

onMaxCount and onMaxChars can't happen simulteniously because if onMaxCount limit reached user just can't input something, hence onMaxChars can't happen.

@grisevg

grisevg Sep 7, 2011

Why it's 2 separate ifs then?

@baio

baio Sep 7, 2011

Owner

You mean it is better use "else if" instead?

@grisevg

grisevg Sep 7, 2011

It's easier to read(Reader will understand only one of ifs can happen) and takes less space.

+ }
+
+ if (func !== undefined){
+ //some restriction has occur
+ if (func){
+ that._trigger(func, null, that);
+ }
+
+ event.preventDefault();
@grisevg

grisevg Sep 6, 2011

Why again? It's already there on line 218

@baio

baio Sep 7, 2011

Owner

In line 218 - another else block

+ }
+ else{
+ //length of the text in input tag changed, update input tag width
+ that._updateInputTagWidth();
+ }
+ }
+
}).blur(function(e){
+ //Widget loose focus, suppose created tag not from list.
+ //Creating tags which are not from list is only available when options.allowNotInList = true
+
// Create a tag when the element loses focus (unless it's empty).
- that.createTag(that._cleanedInput());
- });
+ if (that.options.allowNotInList !== false){
@grisevg

grisevg Sep 6, 2011

Why not "if (that.options.allowNotInList)" ?

@baio

baio Sep 7, 2011

Owner

It is supposed that allowNotInList = unedfined and allowNotInList = null is the same as True. Maybe it is worth to change or make some notes in comments about this.

+ that.createTag(that._cleanedInput());
+ }
+ }).keyup(function(e){
@grisevg

grisevg Sep 6, 2011

Isn't UI Autocomplete already took care of that?

@baio

baio Sep 7, 2011

Owner

Without it, when user will choose something from drop down by up or down arrow, element in input tag will be visually trimmed (if the current width of input tag were smoller than text from the list)

+ if (event.which == $.ui.keyCode.UP ||event.which == $.ui.keyCode.DOWN){
+ //user select some tag from drop down list of autocomplete control by up or down key
+ //should update input tag width in order to selected text fits to the input element width
+ that._updateInputTagWidth();
+ }
+ });
// Autocomplete.
@@ -226,6 +304,42 @@
}
},
+ destroy : function()
+ {
+ //destroy widget
+
@grisevg

grisevg Sep 6, 2011

Please stop putting empty lines everywhere...

+ if (this.element)
+ {
+ this.element.css('display', this.display_orig);
+ }
+
+ $(this.tagList).remove();
+
+ $.Widget.prototype.destroy.apply(this, arguments);
+ },
+
+ _updateInputTagWidth : function()
+ {
+ //function update width of the input tag on the base of the width of text inside.
+
+ //calculate text width
+ var sensor = $('<span />').css({
+ "font-family" : this._tagInput.css("font-family"),
+ "font-size" : this._tagInput.css("font-size"),
+ "font-style" : this._tagInput.css("font-style"),
+ "font-variant" : this._tagInput.css("font-variant"),
+ "font-spacing" : this._tagInput.css("font-spacing"),
+ margin: this._tagInput.css("margin"),
+ padding: this._tagInput.css("padding")});
+ sensor.text(this._tagInput.val() + "W");
+ $("body").append(sensor);
+ var w = sensor.width();
+ sensor.remove();
+
+ //update input tag width
+ this._tagInput.css("width", w);
+ },
+
_cleanedInput: function() {
// Returns the contents of the tag input, cleaned and ready to be passed to createTag
return $.trim(this._tagInput.val().replace(/^"(.*)"$/, '$1'));
@@ -338,6 +452,7 @@
// Cleaning the input.
this._tagInput.val('');
+ that._updateInputTagWidth();
// insert tag
this._tagInput.parent().before(tag);
View
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <title></title>
+ <!-- These 2 CSS files are required: any 1 jQuery UI theme CSS, plus the Tag-it base CSS. -->
+ <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/flick/jquery-ui.css">
+ <link rel="stylesheet" type="text/css" href="css/jquery.tagit.css">
+
+ <!-- This is an optional CSS theme that only applies to this widget. Use it in addition to the jQuery UI theme. -->
+ <link href="css/tagit.ui-zendesk.css" rel="stylesheet" type="text/css">
+
+ <!-- jQuery and jQuery UI are required dependencies. -->
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.js" type="text/javascript" charset="utf-8"></script>
+ <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.12/jquery-ui.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- The real deal -->
+ <script src="js/tag-it.js" type="text/javascript" charset="utf-8"></script>
+
+ <script>
+
+ function create_it()
+ {
+ var sampleTags = ['c++', 'java', 'php', 'coldfusion', 'javascript', 'asp', 'ruby', 'python', 'c', 'scala', 'groovy', 'haskell', 'perl', 'erlang', 'apl', 'cobol', 'go', 'lua'];
+
+ $('#tagField').tagit({
+
+ maxChars : 5,
+ maxCount : 3,
+ allowNotInList: false,
+ availableTags: sampleTags,
+ animate : false,
+ onMaxChars: function(widget, input)
+ {
+ console.log("onMaxChars");
+ },
+ onMaxCount: function()
+ {
+ console.log("onMaxCount");
+ },
+ onNotAllowed: function()
+ {
+ console.log("onNotAllowed");
+ }
+ });
+ }
+
+ function destroy_it()
+ {
+ $("#tagField").tagit("destroy");
+ }
+
+ $(document).ready(function(){
+ //create_it();
+ });
+ </script>
+</head>
+<body>
+<form>
+ <p>
+ If you instantiate Tag-it on an INPUT element, it will default to being singleField, with that INPUT element as the singleFieldNode. This is the simplest way to have a gracefully-degrading tag widget.
+ </p>
+ <input name="tags" id="tagField" value="Apple, Orange" style="top: 200px; width: 300px; position: absolute;">
+
+ </form>
+<button onclick='destroy_it();'>destroy it!</button>
+<button onclick='create_it();'>create it!</button>
+</body>
+</html>

2 comments on commit 7f52490

Found some code in here that I can use locally. Thanks!

Owner

baio replied Sep 13, 2011

@panozzaj you welcome!

Please sign in to comment.