星期一, 10月 27, 2014

星期四, 10月 23, 2014

[Raphael.js ] 讓Morrisjs 支援Pie chart與水平bar chart

最近要套用morrisjs這套基於Raphael.js 的畫圖函式庫,發現了缺少了Pie Chart與水平bar chart功能,不過已經有二個fork這專案的人實作了,有興趣的人可以自已把這二個需求合在一起 :D

Pie Chart

https://github.com/tiraeth/morris.js

提供Pie chart的新圖形實作,不過不是merged到最新的master,使用的話,donut chart的hover顯示的文件位置會不一樣

PR Issue:
https://github.com/morrisjs/morris.js/pull/149

Bar Chart

https://github.com/JelteF/morris.js
支援水平的bar chart

星期一, 10月 20, 2014

星期四, 10月 16, 2014

[AngularJS] currency 去除小數點decimal-cents

今天用到Angular預設的currency filter時,發現都會在小數點後多二個 00,
查了一下可以透過自定的currency來解決,請參考以下這篇討論串:

http://stackoverflow.com/questions/14782439/removing-angularjs-currency-filter-decimal-cents


星期一, 10月 13, 2014

[CSS] 語話氣球產生器 Word Ballonns

今天剛好在找參考的css,就找到了這個好用的工具 CSS Arrow Please
透過GUI點一點就會產生樣式了

星期六, 10月 11, 2014

[WordPress plugin] 顯示所有產品類別title過長的問題

今天發現使用顯示產品類別的short code中的title好像會長出很多換行空白,
因為就順便找一個原始碼的呼叫方式,進入點可以從這個檔案 includes/class-wc-shortcodes.php 開始, 所以就順利找到對應的產品列表原始碼位置 templates/content-product_cat.php 更詳細的資訊可以透過 http://oik-plugins.eu/woocommerce-a2z/ 來協助你追原始碼 :D

星期日, 10月 05, 2014

[WordPress Plugin] Woocomerce 顯示產品分類到首頁

Woocommerce內建提供簡單的語法讓使用者可以在自訂的頁面顯示產品分類
找到這篇討論串的解法: https://wordpress.org/support/topic/show-only-top-level-product-category-on-home-page


***
[product_categories number="12" parent="0"]
Set the parent paramater to 0 to only display top level categories.

如果要秀全部的分類的話,把number設 number="" 即可
***
經過測試是可以正常執行的,官方shortcode的文件裡面也找的到這行指令XD (RTFM)
顯示的效果如下:
當然預設的指令碼只會顯示如上圖的效果,如果模更進階的顯示的話,Wootheme提供你額外付錢的外掛:D,效果就比較靈活,如下圖所示。


有這樣需求的朋友可至此購買 










星期四, 10月 02, 2014

[jQuery Plugin] 撰寫jQuery plugin的寫作樣式

太久沒寫jQuery外掛了,找了一些資料來複習一下。
這篇文章記錄一下自已喜歡用的jquery plugin寫作方式。
初學者建議讀一下這篇: http://learn.jquery.com/plugins/

外掛功能


  1. 保持jQuery物件鏈結 (非常重要)
  2. 提供公有方法(有時候在init plugin之後,可能會需要公有方法能變更plugin的行為或屬性)
  3. 提供預設的參數設定
  4. 儲存產生plugin 物件的參考 (基於第二個方法)

方法一: 類似bootstrap的解法

最後參考這篇 Things I learnt creating a jQuery Plugin (Part I),作者也基於這個寫作方式,寫了一個bootstrap的tagger外掛: https://github.com/acanimal/tagger.js

;(function($) {
    //define plugin name
    var pluginName =  'jqueryPlugin';
    
    //create plugin class
    function Plugin (element,options){
        
        this.el = element;
        this.$el = $(element);
        
        this.options = $.extend({}, $.fn[pluginName].defaults, options);
       
        //constrctor
        this.init();
        
        return this;
    };
    
    Plugin.prototype.name = pluginName;
    Plugin.prototype.version =  '0.0.1';
    
    Plugin.prototype = {
        
        init : function(){
            
            var plugin = this;
        },
        
        /**
         * The 'destroy' method is were you free the resources used by your plugin:
         * references, unregister listeners, etc.
         *
         * Remember to unbind for your event:
         *
         * @example
         * this.$someSubElement.off('.' + pluginName);
         *
         * Above example will remove any listener from your plugin for on the given
         * element.
         */
        destroy: function() {

            // Remove any attached data from your plugin
            this.$el.removeData();
        },
        
         /**
         * Write public methods within the plugin's prototype. They can 
         * be called with:
         *
         * @example
         * $('#element').jqueryPlugin('somePublicMethod','Arguments', 'Here', 1001);
         *  
         * @param  {[type]} foo [some parameter]
         * @param  {[type]} bar [some other parameter]
         * @return {[type]}
         */
        pubMethod : function(){
            
        }
        
    }
 
    /**
     * This is a real private method. A plugin instance has access to it
     * @return {[type]}
     */
    var privateMethod = function() {
        console.log("privateMethod");
        console.log(this);
    };
    
    // Plugin wrapper around the constructor,
    $.fn[pluginName] = function(options) {
        
        var args = arguments;

        if (options === undefined || typeof options === 'object') {
            // Create a plugin instance for each selected element.
            return this.each(function() {
                if (!$.data(this, 'plugin_' + pluginName)) {
                    $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
                }
            });
        } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
            // Call a pluguin method for each selected element.
            if (Array.prototype.slice.call(args, 1).length == 0 && $.inArray(options, $.fn[pluginName].getters) != -1) {
                // If the user does not pass any arguments and the method allows to
                // work as a getter then break the chainability
                var instance = $.data(this[0], 'plugin_' + pluginName);
                return instance[options].apply(instance, Array.prototype.slice.call(args, 1));
            } else {
                // Invoke the speficied method on each selected element
                return this.each(function() {
                    var instance = $.data(this, 'plugin_' + pluginName);
                    if (instance instanceof Plugin && typeof instance[options] === 'function') {
                        instance[options].apply(instance, Array.prototype.slice.call(args, 1));
                    }
                });
            }
        }
    }

     /**
     * Names of the pluguin methods that can act as a getter method.
     * @type {Array}
     */
    $.fn[pluginName].getters = ['pubMethod'];
    
     /**
     * Default options
     */
    $.fn[pluginName].defaults = {
         defaultOption: "I'm a default option"
    };
    
})(jQuery);