UNPKG

zui

Version:

一个基于 Bootstrap 深度定制开源前端实践方案,帮助你快速构建现代跨屏应用。

255 lines (232 loc) 9.25 kB
/* ======================================================================== * ZUI: ColorPicker.js [1.5.0+] * http://zui.sexy * ======================================================================== * Copyright (c) 2016 cnezsoft.com; Licensed MIT * ======================================================================== */ (function($) { 'use strict'; var name = 'zui.colorPicker'; // modal name var TEAMPLATE = '<div class="colorpicker"><button type="button" class="btn dropdown-toggle" data-toggle="dropdown"><span class="cp-title"></span><i class="ic"></i></button><ul class="dropdown-menu clearfix"></ul></div>'; var LANG = { zh_cn: { errorTip: "不是有效的颜色值" }, zh_tw: { errorTip: "不是有效的顏色值" }, en: { errorTip: "Not a valid color value" } }; // The ColorPicker modal class var ColorPicker = function(element, options) { this.name = name; this.$ = $(element); this.getOptions(options); this.init(); }; // default options ColorPicker.DEFAULTS = { colors: ['#00BCD4', '#388E3C', '#3280fc', '#3F51B5', '#9C27B0', '#795548', '#F57C00', '#F44336', '#E91E63'], pullMenuRight: true, wrapper: 'btn-wrapper', tileSize: 30, lineCount: 5, optional: true, tooltip: 'top', icon: 'caret-down', updateBtn: 'auto' // btnTip: 'Tool tip in button' }; ColorPicker.prototype.init = function() { var that = this; var options = that.options; var $input = that.$; var $parent = $input.parent(); var createdPicker = false; if ($parent.hasClass('colorpicker')) { that.$picker = $parent; } else { that.$picker = $(options.template || TEAMPLATE); createdPicker = true; } that.$picker.addClass(options.wrapper).find('.cp-title').toggle(options.title !== undefined).text(options.title); that.$menu = that.$picker.find('.dropdown-menu').toggleClass('pull-right', options.pullMenuRight); that.$btn = that.$picker.find('.btn.dropdown-toggle'); that.$btn.find('.ic').addClass('icon-' + options.icon); if(options.btnTip) { that.$picker.attr('data-toggle', 'tooltip').tooltip({title: options.btnTip, placement: options.tooltip, container: 'body'}); } $input.attr('data-provide', null); if (createdPicker) { $input.after(that.$picker); } // init colors that.colors = {}; $.each(options.colors, function(idx, rawColor) { if($.zui.Color.isColor(rawColor)) { var color = new $.zui.Color(rawColor); that.colors[color.toCssStr()] = color; } }); that.updateColors(); that.$picker.on('click', '.cp-tile', function() { that.setValue($(this).data('color')); }); var setInputColor = function() { var val = $input.val(); var isColor = $.zui.Color.isColor(val); $input.parent().toggleClass('has-error', !isColor && !(options.optional && val === '')); if(isColor) { that.setValue(val, true); } else { if(options.optional && val === '') { $input.tooltip('hide'); } else if(!$input.is(':focus')) { $input.tooltip('show', options.errorTip); } } } if($input.is('input:not([type=hidden])')) { if(options.tooltip) { $input.attr('data-toggle', 'tooltip').tooltip({trigger: 'manual', placement: options.tooltip, tipClass: 'tooltip-danger', container: 'body'}); } $input.on('keyup paste input change', setInputColor); } else { $input.appendTo(that.$picker); } setInputColor(); }; ColorPicker.prototype.addColor = function(color) { if(!(color instanceof $.zui.Color)) { color = new $.zui.Color(color); } var hex = color.toCssStr(), options = this.options; if(!this.colors[hex]) { this.colors[hex] = color; } var $a = $('<a href="###" class="cp-tile"></a>', { titile: color }).data('color', color).css({ 'color': color.contrast().toCssStr(), 'background': hex, 'border-color': color.luma() > 0.43 ? '#ccc' : 'transparent' }).attr('data-color', hex); this.$menu.append($('<li/>').css({width: options.tileSize, height: options.tileSize}).append($a)); if(options.optional) { this.$menu.find('.cp-tile.empty').parent().detach().appendTo(this.$menu); } }; ColorPicker.prototype.updateColors = function(colors) { var $picker = this.$picker, $menu = this.$menu.children('li:not(.heading)').remove(), options = this.options, colors = colors || this.colors, that = this; var bestLineCount = 0; $.each(colors, function(idx, color) { that.addColor(color); bestLineCount++; }); if(options.optional) { var $li = $('<li><a class="cp-tile empty" href="###"></a></li>').css({width: options.tileSize, height: options.tileSize}); this.$menu.append($li); bestLineCount++; } $menu.css('width', Math.min(bestLineCount, options.lineCount) * options.tileSize + 6); }; ColorPicker.prototype.setValue = function(color, notSetInput) { var that = this; var options = that.options; var $btn = that.$btn; that.$menu.find('.cp-tile.active').removeClass('active'); var hex = ''; var updateBtn = options.updateBtn; if (updateBtn === 'auto') { var $btnBar = $btn.find('.color-bar'); updateBtn = $btnBar.length ? function(hexColor) { $btnBar.css('background', hexColor || ''); } : true; } if(color) { var c = new $.zui.Color(color); hex = c.toCssStr().toLowerCase(); if (updateBtn) { if ($.isFunction(updateBtn)) { updateBtn(hex, $btn, that); } else { $btn.css({ background: hex, color: c.contrast().toCssStr(), borderColor: c.luma() > 0.43 ? '#ccc' : hex }); } } if(!that.colors[hex]) { that.addColor(c); } if(!notSetInput && that.$.val().toLowerCase() !== hex) { that.$.val(hex).trigger('change'); } that.$menu.find('.cp-tile[data-color="' + hex + '"]').addClass('active'); that.$.tooltip('hide'); that.$.trigger('colorchange', c); } else { if (updateBtn) { if ($.isFunction(updateBtn)) { updateBtn(null, $btn, that); } else { $btn.attr('style', null); } } if(!notSetInput && that.$.val() !== '') { that.$.val(hex).trigger('change'); } if(options.optional) { that.$.tooltip('hide'); } that.$menu.find('.cp-tile.empty').addClass('active'); that.$.trigger('colorchange', null); } if(options.updateBorder) { $(options.updateBorder).css('border-color', hex); } if(options.updateBackground) { $(options.updateBackground).css('background-color', hex); } if(options.updateColor) { $(options.updateColor).css('color', hex); } if(options.updateText) { $(options.updateText).text(hex); } }; // Get and init options ColorPicker.prototype.getOptions = function(options) { var thisOptions = $.extend({}, ColorPicker.DEFAULTS, this.$.data(), options); if(typeof thisOptions.colors === 'string') thisOptions.colors = thisOptions.colors.split(','); var lang = (thisOptions.lang || $.zui.clientLang()).toLowerCase(); if(!thisOptions.errorTip) { thisOptions.errorTip = LANG[lang].errorTip; } if(!$.fn.tooltip) thisOptions.btnTip = false; this.options = thisOptions; }; // Extense jquery element $.fn.colorPicker = function(option) { return this.each(function() { var $this = $(this); var data = $this.data(name); var options = typeof option == 'object' && option; if(!data) $this.data(name, (data = new ColorPicker(this, options))); if(typeof option == 'string') data[option](); }); }; $.fn.colorPicker.Constructor = ColorPicker; // Auto call colorPicker after document load complete $(function() { $('[data-provide="colorpicker"]').colorPicker(); }); }(jQuery));