mourningdove/htdocs/js/jquery.iconselector.js

328 lines
13 KiB
JavaScript
Raw Permalink Normal View History

2026-05-24 01:03:05 +00:00
(function($) {
var kwtoicon = {};
var opts;
$.fn.iconselector = function( options ) {
opts = $.extend({}, $.fn.iconselector.defaults, options );
$.fn.iconselector.owner = $(this);
if( opts.selectorButtons ) {
$(opts.selectorButtons)
.click(function(e) {
_open.apply( $.fn.iconselector.owner, [ opts ] );
e.preventDefault();
});
}
return $(this);
};
// selected icon
$.fn.iconselector.selected = null;
// selected keyword
$.fn.iconselector.selectedKeyword = null;
$.fn.iconselector.defaults = {
title: 'Choose Icon',
width: "70%",
height: $(window).height() * 0.8,
selectedClass: "iconselector_selected",
onSelect: function() {},
selectorButtons: null,
// user options
metatext: true,
smallicons: false
};
function _dialogHTML() {
return "<div>\
<div class='iconselector_top'>\
<span class='iconselector_searchbox'>\
Search: <input type='search' id='iconselector_search'>\
</span>\
<span class='image-text-toggle' id ='iconselector_image_text_toggle'>\
<span class='toggle-meta-on'>Meta text / <a href='#' class='no_meta_text'>No meta text</a></span>\
<span class='toggle-meta-off'><a href='#' class ='meta_text'>Meta text</a> / No meta text</span>\
</span>\
<span class='image-size-toggle' id='iconselector_image_size_toggle'>\
<span class='toggle-half-image'>Small images / <a href='#' class='full_image'>Large images</a></span>\
<span class='toggle-full-image'><a href='#' class='half_image'>Small images</a> / Large images</span>\
</span>\
<div class='kwmenu'>\
<label for='iconselector_kwmenu'>Keywords of selected icon:</label>\
<div class='keywords'></div>\
<input id='iconselector_select' disabled='disabled' type='button' value='Select'>\
</div>\
</div>\
<div id='iconselector_icons'><span class='iconselector_status'>Loading...</span></div>\
</div>";
};
function _selectContainer($container, keyword, replaceKwMenu) {
$("#"+$.fn.iconselector.selected).removeClass(opts.selectedClass);
if ( $container.length == 0 ) return;
$.fn.iconselector.selected = $container.attr("id");
$container.addClass(opts.selectedClass);
$container.show();
if ( keyword != null ) {
// select by keyword
$.fn.iconselector.selectedKeyword = keyword;
} else {
// select by picid (first keyword)
$.fn.iconselector.selectedKeyword = $container.data("defaultkw");
}
if ( replaceKwMenu ) {
var $keywords = $container.find(".keywords");
$(".iconselector_top .keywords", $.fn.iconselector.instance)
.replaceWith($keywords.clone());
if ($keywords.length > 0)
$("#iconselector_select").prop("disabled", false);
else
$("#iconselector_select").prop("disabled", true);
} else {
$(".iconselector_top .selected", $.fn.iconselector.instance)
.removeClass("selected");
}
// can't rely on a cached value, because it may have been replaced
$(".iconselector_top .keywords", $.fn.iconselector.instance)
.find("a.keyword")
.filter(function() {
return $(this).text() == $.fn.iconselector.selectedKeyword;
})
.addClass("selected");
}
function _selectByKeyword(keyword) {
var iconcontainer_id = kwtoicon[keyword];
if ( iconcontainer_id )
_selectContainer($("#"+iconcontainer_id), keyword, true);
}
function _selectByKeywordClick(event) {
var $keyword = $(event.target).closest("a.keyword");
if ( $keyword.length > 0 ) {
var keyword = $keyword.text();
var iconcontainer_id = kwtoicon[keyword];
if ( iconcontainer_id )
_selectContainer($("#"+iconcontainer_id), keyword, false);
}
event.stopPropagation();
event.preventDefault();
}
function _selectByClick(event) {
var $icon = $(event.target).closest("li");
var $keyword = $(event.target).closest("a.keyword");
_selectContainer($icon, $keyword.length > 0 ? $keyword.text() : null, true);
event.stopPropagation();
event.preventDefault();
};
function _selectByEnter(event) {
if (event.keyCode && event.keyCode === $.ui.keyCode.ENTER) {
var $originalTarget = $(event.originalTarget);
if ($originalTarget.hasClass("keyword")) {
$originalTarget.click();
} else if ($originalTarget.is("a")) {
return;
}
_selectCurrent();
}
}
function _selectCurrent() {
if ($.fn.iconselector.selectedKeyword) {
$.fn.iconselector.owner.val($.fn.iconselector.selectedKeyword);
$.fn.iconselector.owner.trigger("change");
opts.onSelect.apply($.fn.iconselector.owner[0]);
$.fn.iconselector.instance.dialog("close");
}
}
function _filterPics(event) {
var val = $("#iconselector_search").val().toLocaleUpperCase();
$("#iconselector_icons_list li").hide().each(function(i, item) {
if ( $(this).data("keywords").indexOf(val) != -1 || $(this).data("comment").indexOf(val) != -1
|| $(this).data("alt").indexOf(val) != -1 ) {
$(this).show();
}
});
var $visible = $("#iconselector_icons_list li:visible");
if ( $visible.length == 1 )
_selectContainer($visible, null, true);
};
function _persist( option, value ) {
var params = {};
params[option] = value;
// this is a best effort thing, so be silent about success/error
$.post( "/__rpc_iconbrowser_save", params );
}
function _open () {
if ( ! $.fn.iconselector.instance ) {
$.fn.iconselector.instance = $(_dialogHTML());
$.fn.iconselector.instance.dialog( { title: opts.title, width: opts.width, height: opts.height, dialogClass: "iconselector", modal: true,
close: function() { $("#iconselect").focus(); },
resize: function() {
$("#iconselector_icons").height(
$.fn.iconselector.instance.height() -
$.fn.iconselector.instance.find('.iconselector_top').height()
- 5
);
}
} )
.keydown(_selectByEnter);
$("#iconselector_image_size_toggle a").click(function(e, init) {
if ($(this).hasClass("half_image") ) {
$("#iconselector_icons, #iconselector_image_size_toggle, #iconselector_icons_list").addClass("half_icons");
if ( ! init ) _persist( "smallicons", true );
} else {
$("#iconselector_icons, #iconselector_image_size_toggle, #iconselector_icons_list").removeClass("half_icons");
if ( ! init ) _persist( "smallicons", false );
}
//refocus
$("#iconselector_image_size_toggle a:visible:first").focus();
return false;
}).filter( opts.smallicons ? ".half_image" : ":not(.half_image)" )
.triggerHandler("click", true);
$("#iconselector_image_text_toggle a").click(function(e, init) {
if ($(this).hasClass("no_meta_text") ) {
$("#iconselector_icons, #iconselector_image_text_toggle, #iconselector_icons_list").addClass("no_meta");
if ( ! init ) _persist( "metatext", false );
} else {
$("#iconselector_icons, #iconselector_image_text_toggle, #iconselector_icons_list").removeClass("no_meta");
if ( ! init ) _persist( "metatext", true );
}
// refocus because we just hid the link we clicked on
$("#iconselector_image_text_toggle a:visible:first").focus();
return false;
}).filter( opts.metatext ? ":not(.no_meta_text)" : ".no_meta_text" )
.triggerHandler("click", true);
$("#iconselector_icons").height(
$.fn.iconselector.instance.height() -
$.fn.iconselector.instance.find('.iconselector_top').height()
- 5
);
$("button", $.fn.iconselector.instance.siblings()).prop("disabled", true);
$(":input", $.fn.iconselector.instance).prop("disabled", true);
$("#iconselector_search", $.fn.iconselector.instance).bind("keyup click", _filterPics);
var url = Site.currentJournalBase ? "/" + Site.currentJournal + "/__rpc_userpicselect" : "/__rpc_userpicselect";
$.getJSON(url,
function(data) {
if ( !data ) {
$("#iconselector_icons").html("<h2>Error</h2><p>Unable to load icons data</p>");
return;
}
if ( data.alert ) {
$("#iconselector_icons").html("<h2>Error</h2><p>"+data.alert+"</p>");
return;
}
var $iconslist = $("<ul id='iconselector_icons_list'></ul>");
var pics = data.pics;
$.each(data.ids, function(index,id) {
var icon = pics[id];
var idstring = "iconselector_item_"+id;
var $img = $("<img />").attr( { src: icon.url, alt: icon.alt, height: icon.height, width: icon.width } ).wrap("<div class='icon_image'></div>").parent();
var $keywords = "";
if ( icon.keywords ) {
$keywords = $("<div class='keywords'></div>");
var last = icon.keywords.length - 1;
$.each(icon.keywords, function(i, kw) {
kwtoicon[kw] = idstring;
$keywords.append( $("<a href='#' class='keyword'></a>").text(kw) );
if ( i < last )
$keywords.append(document.createTextNode(", "));
});
}
var $comment = ( icon.comment != "" ) ? $("<div class='icon-comment'></div>").text( icon.comment ) : "";
var $meta = $("<div class='meta_wrapper'></div>").append($keywords).append($comment);
var $item = $("<div class='iconselector_item'></div>").append($img).append($meta);
$("<li></li>").append($item).appendTo($iconslist)
.data( "keywords", icon.keywords.join(" ").toLocaleUpperCase() )
.data( "comment", icon.comment.toLocaleUpperCase() )
.data( "alt", icon.alt.toLocaleUpperCase() )
.data( "defaultkw", icon.keywords[0] )
.attr( "id", idstring );
});
$("#iconselector_icons").empty().append($iconslist);
$("button", $.fn.iconselector.instance.siblings()).prop("disabled", false);
$(":input:not([id='iconselector_select'])", $.fn.iconselector.instance).prop("disabled", false);
$("#iconselector_icons_list")
.click(_selectByClick)
.dblclick(function(e) {
_selectByClick(e);
_selectCurrent();
});
$(".iconselector_top .kwmenu", $.fn.iconselector.instance)
.click(_selectByKeywordClick)
.dblclick(function(e) {
_selectByKeywordClick(e);
_selectCurrent();
});
$("#iconselector_search").focus();
$("#iconselector_select").click(_selectCurrent);
$(document).bind("keydown.dialog-overlay", _selectByEnter);
// initialize
_selectByKeyword($.fn.iconselector.owner.val());
});
} else {
// reinitialize
_selectByKeyword($.fn.iconselector.owner.val());
$.fn.iconselector.instance.dialog("open");
$("#iconselector_search").focus();
$(document).bind("keydown.dialog-overlay", _selectByEnter);
}
};
})(jQuery);
jQuery(function($) {
var browseButton = $("#lj_userpicselect");
if (browseButton.length > 0) {
$("#prop_picture_keyword").iconselector({
selectorButtons: "#lj_userpicselect, .lj_userpicselect_extra",
metatext: browseButton.data("iconbrowserMetatext"),
smallicons: browseButton.data("iconbrowserSmallicons")
});
}
});