mirror of
https://github.com/humhub/humhub.git
synced 2025-03-04 07:08:58 +01:00
352 lines
9.9 KiB
JavaScript
352 lines
9.9 KiB
JavaScript
/*
|
||
* SpacePicker
|
||
* Version 1.0.0
|
||
* Written by: Andreas Strobel
|
||
*
|
||
* @property String $inputId is the ID of the input HTML Element
|
||
* @property Int $maxSpaces the maximum of users in this dropdown
|
||
* @property String $spaceSearchUrl the url of the search, to find the spaces
|
||
* @property String $currentValue is the current value of the parent field.
|
||
* @property String $templates.inputStructure is the HTML structure to replace the original input element.
|
||
*
|
||
* License: MIT License - http://www.opensource.org/licenses/mit-license.php
|
||
*/
|
||
|
||
|
||
var chosen = "";
|
||
var spaceCount = 0;
|
||
|
||
$.fn.spacepicker = function (options) {
|
||
|
||
// set standard options
|
||
options = $.extend({
|
||
inputId: "",
|
||
maxSpaces: 0,
|
||
searchUrl: "",
|
||
placeholder: "",
|
||
currentValue: "",
|
||
}, options);
|
||
|
||
// add input structure template
|
||
options = $.extend({
|
||
templates: {
|
||
inputStructure: '<div class="space_picker_container"><ul class="tag_input" id="space_tags"><li id="space_tag_input"><input type="text" id="space_input_field" class="tag_input_field" value="" autocomplete="off" placeholder="'+options.placeholder+'"></li></ul><ul class="dropdown-menu" id="spacepicker" role="menu" aria-labelledby="dropdownMenu"></ul></div>'
|
||
}
|
||
}, options);
|
||
|
||
|
||
init();
|
||
|
||
|
||
function init() {
|
||
|
||
// remove picker if existing
|
||
$('.space_picker_container').remove();
|
||
|
||
// insert the new input structure after the original input element
|
||
$(options.inputId).after(options.templates.inputStructure);
|
||
|
||
// hide original input element
|
||
$(options.inputId).hide();
|
||
|
||
if (options.currentValue != "") {
|
||
|
||
// restore data from database
|
||
restoreSpaceTags(options.currentValue);
|
||
}
|
||
|
||
// simulate focus in
|
||
$('#space_input_field').focusin(function () {
|
||
$('#space_tags').addClass('focus');
|
||
})
|
||
|
||
// simulate focus out
|
||
$('#space_input_field').focusout(function () {
|
||
$('#space_tags').removeClass('focus');
|
||
})
|
||
}
|
||
|
||
function restoreSpaceTags(html) {
|
||
|
||
// add html structure for input element
|
||
$('#space_tags').prepend(html);
|
||
|
||
// create function for every space tag to remove the element
|
||
$('#space_tags .spaceInput i').each(function () {
|
||
|
||
$(this).click(function () {
|
||
|
||
// remove user tag
|
||
$(this).parent().remove();
|
||
|
||
// reduce the count of added spaces
|
||
spaceCount--;
|
||
|
||
})
|
||
|
||
// raise the count of added spaces
|
||
spaceCount++;
|
||
|
||
})
|
||
|
||
|
||
}
|
||
|
||
|
||
// Set focus on the input field, by clicking the <ul> construct
|
||
jQuery('#space_tags').click(function () {
|
||
|
||
// set focus
|
||
$('#space_input_field').focus();
|
||
})
|
||
|
||
$('#space_input_field').keydown(function (event) {
|
||
|
||
// by pressing the tab key an the input is empty
|
||
if ($(this).val() == "" && event.keyCode == 9) {
|
||
|
||
//do nothing
|
||
|
||
// by pressing enter, tab, up or down arrow
|
||
} else if (event.keyCode == 40 || event.keyCode == 38 || event.keyCode == 13 || event.keyCode == 9) {
|
||
|
||
// ... disable the default behavior to hold the cursor at the end of the string
|
||
event.preventDefault();
|
||
|
||
}
|
||
|
||
// if there is a space limit and the user didn't press the tab key
|
||
if (options.maxSpaces != 0 && event.keyCode != 9) {
|
||
|
||
// if the max space count is reached
|
||
if (spaceCount == options.maxSpaces) {
|
||
|
||
// show hint
|
||
showHintSpaces();
|
||
|
||
// block input events
|
||
event.preventDefault();
|
||
}
|
||
}
|
||
|
||
})
|
||
|
||
$('#space_input_field').keyup(function (event) {
|
||
|
||
// start search after a specific count of characters
|
||
if ($('#space_input_field').val().length >= 3) {
|
||
|
||
// set spacepicker position in bottom of the space input
|
||
$('#spacepicker').css({
|
||
position: "fixed",
|
||
top: $('#space_input_field').offset().top + 30,
|
||
left: $('#space_input_field').offset().left + 2
|
||
})
|
||
|
||
if (event.keyCode == 40) {
|
||
|
||
// select next <li> element
|
||
if (chosen === "") {
|
||
chosen = 1;
|
||
} else if ((chosen + 1) < $('#spacepicker li').length) {
|
||
chosen++;
|
||
}
|
||
$('#spacepicker li').removeClass('selected');
|
||
$('#spacepicker li:eq(' + chosen + ')').addClass('selected');
|
||
return false;
|
||
|
||
} else if (event.keyCode == 38) {
|
||
|
||
// select previous <li> element
|
||
if (chosen === "") {
|
||
chosen = 1;
|
||
} else if (chosen > 0) {
|
||
chosen--;
|
||
}
|
||
$('#spacepicker li').removeClass('selected');
|
||
$('#spacepicker li:eq(' + chosen + ')').addClass('selected');
|
||
return false;
|
||
|
||
} else if (event.keyCode == 13 || event.keyCode == 9) {
|
||
|
||
var href = $('#spacepicker .selected a').attr('href');
|
||
// simulate click event when href is not undefined.
|
||
if (href !== undefined) {
|
||
window.location.href = href;
|
||
}
|
||
|
||
} else {
|
||
|
||
// save the search string to variable
|
||
var str = $('#space_input_field').val();
|
||
|
||
// show spacepicker with the results
|
||
$('#spacepicker').show();
|
||
|
||
// load spaces
|
||
loadSpaces(str);
|
||
}
|
||
} else {
|
||
|
||
// hide spacepicker
|
||
$('#spacepicker').hide();
|
||
}
|
||
|
||
|
||
})
|
||
|
||
|
||
$('#space_input_field').focusout(function () {
|
||
|
||
// set the plain text including user guids to the original input or textarea element
|
||
$(options.inputId).val(parseSpaceInput());
|
||
})
|
||
|
||
|
||
function loadSpaces(string) {
|
||
|
||
// remove existings entries
|
||
$('#spacepicker li').remove();
|
||
|
||
// show loader while loading
|
||
$('#spacepicker').html('<li><div class="loader"><div class="sk-spinner sk-spinner-three-bounce"><div class="sk-bounce1"></div><div class="sk-bounce2"></div><div class="sk-bounce3"></div></div></div></li>');
|
||
|
||
jQuery.getJSON(options.searchUrl.replace('-keywordPlaceholder-', string), function (json) {
|
||
|
||
// remove existings entries
|
||
$('#spacepicker li').remove();
|
||
|
||
|
||
if (json.length > 0) {
|
||
|
||
|
||
for (var i = 0; i < json.length; i++) {
|
||
|
||
var _guid = json[i].guid;
|
||
var _title = addslashes(htmlDecode(json[i].title));
|
||
var _image = $('<div/>').text(json[i].image).html();
|
||
_image = _image.replace(/"/g, '\\\'');
|
||
|
||
// build <li> entry
|
||
var str = '<li><a tabindex="-1" href="javascript:addSpaceTag(\'' + _guid + '\', \'' + _image + '\', \'' + _title + '\');">' + json[i].image + ' ' + _title + '</a></li>';
|
||
|
||
console.log(str);
|
||
|
||
// append the entry to the <ul> list
|
||
$('#spacepicker').append(str);
|
||
|
||
}
|
||
|
||
// reset the variable for arrows keys
|
||
chosen = "";
|
||
|
||
} else {
|
||
|
||
// hide spacepicker, if no space was found
|
||
$('#spacepicker').hide();
|
||
}
|
||
|
||
|
||
// remove hightlight
|
||
$("#spacepicker li").removeHighlight();
|
||
|
||
// add new highlight matching strings
|
||
$("#spacepicker li").highlight(string);
|
||
|
||
// add selection to the first space entry
|
||
$('#spacepicker li:eq(0)').addClass('selected');
|
||
|
||
})
|
||
}
|
||
|
||
function showHintSpaces() {
|
||
|
||
// remove hint, if exists
|
||
$('#maxSpaceHint').remove();
|
||
|
||
// build html structure
|
||
var _html = '<div id="maxSpaceHint" style="display: none;" class="alert alert-danger"><button type="button" class="close" data-dismiss="alert">×</button><strong>Sorry!</strong> You can add a maximum of ' + options.maxSpaces + ' default spaces for this group.</div>';
|
||
|
||
// add hint to DOM
|
||
$('#space_tags').after(_html);
|
||
|
||
// fadein hint
|
||
$('#maxSpaceHint').fadeIn('fast');
|
||
}
|
||
|
||
}
|
||
|
||
// Add a space tag for invitation
|
||
function addSpaceTag(guid, image, name) {
|
||
|
||
// Building a new <li> entry
|
||
var _tagcode = '<li class="spaceInput" id="' + guid + '">' + image + ' ' + name + '<i class="fa fa-times-circle"></i></li>';
|
||
|
||
|
||
// insert the new created <li> entry into the <ul> contruct
|
||
$('#space_tag_input').before(_tagcode);
|
||
|
||
|
||
// remove tag, by clicking the close icon
|
||
$('#' + guid + " i").click(function () {
|
||
|
||
// remove space tag
|
||
$('#' + guid).remove();
|
||
|
||
// reduce the count of added spaces
|
||
spaceCount--;
|
||
|
||
})
|
||
|
||
// hide space results
|
||
$('#spacepicker').hide();
|
||
|
||
// set focus to the input element
|
||
$('#space_input_field').focus();
|
||
|
||
// Clear the textinput
|
||
$('#space_input_field').val('');
|
||
|
||
// raise the count of added spaces
|
||
spaceCount++;
|
||
|
||
|
||
}
|
||
|
||
function parseSpaceInput() {
|
||
|
||
// create and insert a dummy <div> element to work with
|
||
$('#space_tags').after('<div id="spaceInputResult"></div>')
|
||
|
||
// set html form input element to the new <div> element
|
||
$('#spaceInputResult').html($('#space_tags').html());
|
||
|
||
|
||
$('#spaceInputResult .spaceInput').each(function () {
|
||
|
||
// add the space guid as plain text
|
||
$(this).after(this.id + ",");
|
||
|
||
// remove the link
|
||
$(this).remove();
|
||
})
|
||
|
||
// save the plain text
|
||
var result = $('#spaceInputResult').text();
|
||
|
||
// remove the dummy <div> element
|
||
$('#spaceInputResult').remove();
|
||
|
||
// return the plain text
|
||
return result;
|
||
|
||
}
|
||
|
||
function addslashes(str) {
|
||
|
||
return (str + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
|
||
}
|
||
|
||
function htmlDecode(value) {
|
||
return $("<textarea/>").html(value).text();
|
||
} |