app/assets/javascripts/fcbk.js
/** FCBKcomplete v2.8.9.3 is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> */
(function($, undefined) {
$.fn.fcbkcomplete = function(opt) {
return this.queue(function() {
function init() {
createFCBK();
addInput(0)
}
function createFCBK() {
holder = $('<ul class="holder"></ul>').width(options.width);
if (options.attachto) {
if (typeof(options.attachto) == "object") {
options.attachto.append(holder)
} else {
$(options.attachto).append(holder)
}
} else {
element.after(holder)
}
complete = $('<div class="facebook-auto">').width(options.width);
if (options.complete_text != "") {
var completeText = options.complete_text;
complete.append('<div class="default">' + completeText + '</div>');
if (options.select_all_text) {
complete.children('.default').append(
$('<a href="" class="select_all_items">' + options.select_all_text + '</a>').click(function() {
$(element).trigger('selectAll');
return false
}))
}
}
complete.hover(function() {
complete_hover = 0
},
function() {
complete_hover = 1
});
feed = $('<ul id="' + elemid + '_feed"></ul>').width(options.width);
holder.after(complete.prepend(feed));
elPrepare()
}
function elPrepare() {
name = element.attr("name");
if (options.bricket) {
if (typeof(name) != 'undefined' && name.indexOf("[]") == -1) {
name = name + "[]"
}
}
var temp_elem = $('<' + element.get(0).tagName + ' name="' + name + '" id="' + elemid + '" multiple="multiple" class="' + element.get(0).className + ' hidden">').data('cache', {});
$.each(element.children('option'),
function(i, option) {
option = $(option);
temp_elem.data('cache')[option.val()] = option.text();
if (option.hasClass("selected")) {
var id = addItem(option.text(), option.val(), true, option.hasClass("locked"));
temp_elem.append('<option value="' + option.val() + '" selected="selected" id="opt_' + id + '"class="selected">' + option.text() + '</option>')
}
});
element.after(temp_elem);
element.remove();
element = temp_elem;
$(element).bind("addItem",
function(event, data) {
addItem(data.title, data.value, 0, 0, 0)
});
$(element).bind("removeItem",
function(event, data) {
var item = holder.children('li[rel=' + data.value + ']');
if (item.length) {
removeItem(item)
}
});
$(element).bind("destroy",
function(event, data) {
holder.remove();
complete.remove();
element.show()
});
$(element).bind("selectAll",
function(event, data) {
var currVals = $(element).val() || [];
$.each($(element).data('cache'),
function(key, value) {
if ($.inArray(key, currVals) === -1) {
addItem(value, key, 0, 0, 0)
}
});
feed.parent().hide()
})
}
function addItem(title, value, preadded, locked, focusme) {
if (!maxItems()) {
return false
}
var liclass = "bit-box" + (locked ? " locked": "");
var id = randomId();
var txt = document.createTextNode(xssDisplay(title));
var aclose = $('<a class="closebutton" href="#"></a>');
var li = $('<li class="' + liclass + '" rel="' + value + '" id="pt_' + id + '"></li>').prepend(txt).append(aclose);
holder.append(li);
aclose.click(function() {
removeItem($(this).parent("li"));
return false
});
if (!preadded) {
$("#" + elemid + "_annoninput").remove();
addInput(focusme);
var _item = $('<option value="' + xssDisplay(value, 1) + '" id="opt_' + id + '" class="selected" selected="selected">' + xssDisplay(title) + '</option>');
element.append(_item);
if (options.onselect) {
funCall(options.onselect, _item)
}
element.change()
}
holder.children("li.bit-box.deleted").removeClass("deleted");
clear_feed(1);
return id
}
function removeItem(item) {
if (!item.hasClass('locked')) {
item.fadeOut("fast");
var id = item.attr('id');
if (options.onremove) {
var _item = id ? $("#o" + id + "") : element.children("option[value=" + item.attr("rel") + "]");
funCall(options.onremove, _item)
}
if (id) {
$("#o" + id + "").remove()
} else {
element.children('option[value="' + item.attr("rel") + '"]').remove()
}
item.remove();
element.change();
deleting = 0
}
}
function addInput(focusme) {
var li = $('<li class="bit-input" id="' + elemid + '_annoninput">');
var input = $('<input type="text" class="maininput" size="' + options.input_min_size + '" autocomplete="off">');
if (options.input_tabindex > 0) input.attr("tabindex", options.input_tabindex);
if (options.input_name != "") input.attr("name", options.input_name);
holder.append(li.append(input));
input.focus(function() {
isactive = true;
if (maxItems()) {
complete.fadeIn("fast")
}
});
input.blur(function() {
isactive = false;
if (complete_hover) {
complete.fadeOut("fast")
} else {
input.focus()
}
});
holder.click(function() {
if (options.input_min_size < 0 && feed.length) {
load_feed(xssPrevent(input.val(), 1))
}
input.focus();
if (feed.length && input.val().length > options.input_min_size) {
feed.show()
} else {
clear_feed(1);
complete.children(".default").show()
}
});
input.keypress(function(event) {
if (event.keyCode == _key.enter) {
return false
}
var newsize = (options.input_min_size > input.val().length) ? options.input_min_size: (input.val().length + 1);
input.attr("size", newsize).width(parseInt(input.css('font-size')) * newsize)
});
input.keyup(function(event) {
var etext = xssPrevent(input.val(), 1);
if (event.keyCode == _key.backspace && etext.length == 0) {
clear_feed(1);
if (!holder.children("li.bit-box:last").hasClass('locked')) {
if (holder.children("li.bit-box.deleted").length == 0) {
holder.children("li.bit-box:last").addClass("deleted");
return false
} else {
if (deleting) {
return
}
deleting = 1;
holder.children("li.bit-box.deleted").fadeOut("fast",
function() {
removeItem($(this));
return false
})
}
}
}
if (event.keyCode != _key.downarrow && event.keyCode != _key.uparrow && event.keyCode != _key.leftarrow && event.keyCode != _key.rightarrow && etext.length > options.input_min_size) {
load_feed(etext);
complete.children(".default").hide();
feed.show()
}
});
if (options.oncreate) {
funCall(options.oncreate, input)
}
if (focusme) {
setTimeout(function() {
input.focus();
complete.children(".default").show()
},
1)
}
}
function addMembers(etext, data) {
feed.html('');
if (!options.cache && data != null) {
cache.clear()
}
addTextItem(etext);
if (data != null && data.length) {
$.each(data,
function(i, val) {
cache.set(xssPrevent(val.key), xssPrevent(val.value))
})
}
var maximum = options.maxshownitems < cache.length() ? options.maxshownitems: cache.length();
var content = '';
$.each(cache.search(etext),
function(i, object) {
if (maximum) {
if (options.filter_selected && element.children('option[value="' + object.key + '"]').hasClass("selected")) {} else {
content += '<li rel="' + object.key + '">' + xssDisplay(itemIllumination(object.value, etext)) + '</li>';
counter++;
maximum--
}
}
});
feed.append(content);
if (options.firstselected) {
focuson = feed.children("li:visible:first");
focuson.addClass("auto-focus")
}
if (counter > options.height) {
feed.css({
"height": (options.height * 24) + "px",
"overflow": "auto"
})
} else {
feed.css("height", "auto")
}
if (maxItems() && complete.is(':hidden')) {
complete.show()
}
}
function itemIllumination(text, etext) {
var string_regex_adder = options.filter_begin ? '': '(.*)';
var regex_result = options.filter_begin ? '<em>$1</em>$2': '$1<em>$2</em>$3';
var string_regex = string_regex_adder + (options.filter_case ? "(" + etext + ")(.*)": "(" + etext.toLowerCase() + ")(.*)");
try {
var regex = new RegExp(string_regex, ((options.filter_case) ? "g": "gi"));
var text = text.replace(regex, regex_result)
} catch(ex) {};
return text
}
function bindFeedEvent() {
feed.children("li").mouseover(function() {
feed.children("li").removeClass("auto-focus");
focuson = $(this);
focuson.addClass("auto-focus")
});
feed.children("li").mouseout(function() {
$(this).removeClass("auto-focus");
focuson = null
})
}
function removeFeedEvent() {
feed.unbind("mouseover").unbind("mouseout").mousemove(function() {
bindFeedEvent();
feed.unbind("mousemove")
})
}
function bindEvents() {
var maininput = $("#" + elemid + "_annoninput").children(".maininput");
bindFeedEvent();
feed.children("li").unbind("mousedown").mousedown(function() {
var option = $(this);
addItem(option.text(), option.attr("rel"), 0, 0, 1);
clear_feed(1);
complete.hide()
});
maininput.unbind("keydown");
maininput.keydown(function(event) {
if (event.keyCode != _key.backspace) {
holder.children("li.bit-box.deleted").removeClass("deleted")
}
if ((event.keyCode == _key.enter || event.keyCode == _key.tab || event.keyCode == _key.comma) && checkFocusOn()) {
var option = focuson;
addItem(option.text(), option.attr("rel"), 0, 0, 1);
return _preventDefault(event)
}
if ((event.keyCode == _key.enter || event.keyCode == _key.tab || event.keyCode == _key.comma) && !checkFocusOn()) {
if (options.newel) {
var value = xssPrevent($(this).val());
addItem(value, value, 0, 0, 1);
return _preventDefault(event)
}
if ((options.addontab || options.addoncomma) && options.newel) {
focuson = feed.children("li:visible:first");
var option = focuson;
addItem(option.text(), option.attr("rel"), 0, 0, 1);
return _preventDefault(event)
}
}
if (event.keyCode == _key.downarrow) {
nextItem('first')
}
if (event.keyCode == _key.uparrow) {
nextItem('last')
}
})
}
function nextItem(position) {
removeFeedEvent();
if (focuson == null || focuson.length == 0) {
focuson = feed.children("li:visible:" + position);
feed.get(0).scrollTop = position == 'first' ? 0: parseInt(focuson.get(0).scrollHeight, 10) * (parseInt(feed.children("li:visible").length, 10) - Math.round(options.height / 2))
} else {
focuson.removeClass("auto-focus");
focuson = position == 'first' ? focuson.nextAll("li:visible:first") : focuson.prevAll("li:visible:first");
var prev = parseInt(focuson.prevAll("li:visible").length, 10);
var next = parseInt(focuson.nextAll("li:visible").length, 10);
if (((position == 'first' ? prev: next) > Math.round(options.height / 2) || (position == 'first' ? prev: next) <= Math.round(options.height / 2)) && typeof(focuson.get(0)) != "undefined") {
feed.get(0).scrollTop = parseInt(focuson.get(0).scrollHeight, 10) * (prev - Math.round(options.height / 2))
}
}
feed.children("li").removeClass("auto-focus");
focuson.addClass("auto-focus")
}
function _preventDefault(event) {
complete.hide();
event.preventDefault();
focuson = null;
return false
}
function maxItems() {
return options.maxitems != 0 && (holder.children("li.bit-box").length < options.maxitems)
}
function addTextItem(value) {
if (options.newel && maxItems()) {
feed.children("li[fckb=1]").remove();
if (value.length == 0) {
return
}
var li = $('<li rel="' + value + '" fckb="1">').html(xssDisplay(value));
feed.prepend(li);
counter++
}
return
}
function funCall(func, item) {
var _object = {};
for (i = 0; i < item.get(0).attributes.length; i++) {
if (item.get(0).attributes[i].nodeValue != null) {
_object["_" + item.get(0).attributes[i].nodeName] = item.get(0).attributes[i].nodeValue
}
}
return func.call(func, _object)
}
function checkFocusOn() {
if (focuson == null || focuson.length == 0) {
return false
}
return true
}
function xssPrevent(string, flag) {
if (typeof flag != "undefined") {
for (i = 0; i < string.length; i++) {
var charcode = string.charCodeAt(i);
if ((_key.exclamation <= charcode && charcode <= _key.slash) || (_key.colon <= charcode && charcode <= _key.at) || (_key.squarebricket_left <= charcode && charcode <= _key.apostrof)) {
string = string.replace(string[i], escape(string[i]))
}
}
string = string.replace(/(\{|\}|\*)/i, "\\$1")
}
return string.replace(/script(.*)/g, "")
}
function xssDisplay(string, flag) {
string = string.toString();
string = string.replace('\\', "");
if (typeof flag != "undefined") {
return string
}
return unescape(string)
}
function clear_feed(flag) {
feed.children().remove();
if (flag) {
feed.hide()
}
}
function load_feed(etext) {
counter = 0;
if (options.json_url && maxItems()) {
if (options.cache && json_cache_object.get(etext)) {
addMembers(etext);
bindEvents()
} else {
getBoxTimeout++;
var getBoxTimeoutValue = getBoxTimeout;
setTimeout(function() {
if (getBoxTimeoutValue != getBoxTimeout) return;
$.getJSON(options.json_url, {
"tag": xssDisplay(etext)
},
function(data) {
if (!isactive) return;
addMembers(etext, data);
json_cache_object.set(etext, 1);
bindEvents()
})
},
options.delay)
}
} else {
addMembers(etext);
bindEvents()
}
}
var options = $.extend({
json_url: null,
width: 512,
cache: false,
height: "10",
newel: false,
addontab: false,
addoncomma: false,
firstselected: false,
filter_case: false,
filter_selected: false,
filter_begin: false,
complete_text: "Comece a digitar...",
select_all_text: null,
maxshownitems: 30,
maxitems: 10,
oncreate: null,
onselect: null,
onremove: null,
attachto: null,
delay: 350,
input_tabindex: 0,
input_min_size: 1,
input_name: "",
bricket: true
},
opt);
var holder = null;
var feed = null;
var complete = null;
var counter = 0;
var isactive = false;
var focuson = null;
var deleting = 0;
var complete_hover = 1;
var element = $(this);
var elemid = element.attr("id");
var getBoxTimeout = 0;
var json_cache_object = {
'set': function(id, val) {
var data = element.data("jsoncache");
data[id] = val;
element.data("jsoncache", data)
},
'get': function(id) {
return element.data("jsoncache")[id] != 'undefined' ? element.data("jsoncache")[id] : null
},
'init': function() {
element.data("jsoncache", {})
}
};
var _key = {
'enter': 13,
'tab': 9,
'comma': 188,
'backspace': 8,
'leftarrow': 37,
'uparrow': 38,
'rightarrow': 39,
'downarrow': 40,
'exclamation': 33,
'slash': 47,
'colon': 58,
'at': 64,
'squarebricket_left': 91,
'apostrof': 96
};
var randomId = function() {
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var randomstring = '';
for (var i = 0; i < 32; i++) {
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1)
}
return randomstring
};
var cache = {
'search': function(text, callback) {
var temp = new Array();
var regex = new RegExp((options.filter_begin ? '^': '') + text, (options.filter_case ? "g": "gi"));
$.each(element.data("cache"),
function(i, _elem) {
if (typeof _elem.search === 'function') {
if (_elem.search(regex) != -1) {
temp.push({
'key': i,
'value': _elem
})
}
}
});
return temp
},
'set': function(id, val) {
var data = element.data("cache");
data[id] = val;
element.data("cache", data)
},
'get': function(id) {
return element.data("cache")[id] != 'undefined' ? element.data("cache")[id] : null
},
'clear': function() {
element.data("cache", {})
},
'length': function() {
if (typeof(element.data('cache')) == "object") {
var _length = 0;
for (i in element.data('cache')) {
_length++
}
return _length
} else {
return element.data("cache").length
}
},
'init': function() {
if (element.data("cache") == 'undefined') {
element.data("cache", {})
}
}
};
init();
json_cache_object.init();
cache.init();
return this
})
}
})(jQuery);