星期日, 12月 21, 2014

[jQuery Plugin] required depends 讓驗證欄位基於其他特地條件成立

如果你使用jquery validator要讓required規則依特地條件成立才驗證的話, 可以使用呼叫的depends方法,並自訂規則:D
$('#ProspectDtlFrm').validate({ 
    rules: {
        prsptEmail: {
            required: {
                depends: function(element) {
                    return ($('#prsptHomePhone').val() == '' && 
                            $('#prsptBusinessPhone').val() == '' && 
                            $('#prsptMobilePhone').val() == '');
                }
            }
        }    
    }, 
    messages: { 
        prsptEmail: 'Please enter your first name'
    } 
});

Reference
jquery validate depends rule

[jQuery API] 小心元素undefined的操作,而引起的getAttribute

當操作使用jquery selector操作未定義的物件所引起的getAttribute的錯誤的小地雷


Uncaught TypeError: Cannot read property 'getAttribute' of undefined
var iframe = $("#videoIntro")[0];
       if (typeof(iframe) != "undefined") {
           var player = $f(iframe);
}

星期二, 12月 09, 2014

[jQuery Mobile] 設定select menu的初始化

想要指定select menu的初始化的話只要設定val就好了,但要記得refresh一下

範例:

  $('#frmAnalytics_ReportGroup').val('avg').selectmenu('refresh');

星期四, 12月 04, 2014

[jquery plugin] jquery validator 驗證多個選取盒checkbox

常用的需求,怕忘記直接寫個範例記一下。
以下範例介紹如何透過jquery validator來驗證多個checkboxes,
可以透過minlength參數來指定選取數量

HTML

欲代理區域:
                        <input type="checkbox" id="north" name="area" value="north" /> 北部
                        <input type="checkbox" id="central" name="area" value="central" /> 中部
                        <input type="checkbox" id="south" name="area" value="south" /> 南部
                        <input type="checkbox" id="east" name="area" value="east" /> 東部


JS範例

$validatedContact
   = $("#contactForm").validate({
    rules: {

     //共同 checkbox
     area: {
      required: true
      ,minlength: 2
     }
},
messages:{
area: {
      required: "區域未選取"
      ,minlength: "至少選取二個區域"
     }
},
 submitHandler: function(form) {
}
});


結果



[jQuery plugin] 移除已初始化過的jquery validator

今天有一個頁面需求,需求在切換不同type的時候,變更不同的form的顯示的欄位, 為了方便就是重設jquery validator,可以透過以下範例重設form的validator

範例

$("#contactForm").data("validator", null);
  $("#contactForm").unbind("validate");
  $("#contactForm").removeData("validator")
  $("#contactForm").unbind("submit");//必需移除submit的行為,不然會多重綁定

星期三, 12月 03, 2014

[Javascript] Timer議題: setTimeout 與 setInterval的筆記

最近用timer來實作dashboard相關的機制,順便查一查筆記一下:d

字面上說明

Timeout  ==>逾時
Interval  ==>間隔


定義:

Javascript的計時功能提供了setTimeout與setInterval這兩種用法,執行後會取得一個Timer ID。
要取消計時可以用的分別是clearTimeout()和clearInterval(),然後把執行後取得的Timer ID殺掉即可

兩者差別:


setTimeout()只做一次;setInterval()會不停的的調用函數。



運作原因:

由於javascript是只有單一執行緒,因此只是告訴Js在某一段時間後,再插入執行你指定的函式








星期日, 11月 23, 2014

[jQuery API] Uncaught SyntaxError: Unexpected token )

今天在綁定jquery click事件時,一直會噴Unexpected token的error XD
原來是綁定原始的超連結tag,的href打錯了!! 眼殘的錯誤

I had:
 id="register_hyperlink" href="javascript:void();">Register an account
I changed it to:
 id="register_hyperlink" href="javascript:void(0);">Register an account
So that explains it :-)

星期二, 11月 18, 2014

[PHP] 西元日期轉中文年月日

如果有需要將西元日期轉換的話,可以不用拆解字串的方式。
可參考內建的date函數即可

echo date('Y年n月d日',strtotime('2014-11-18')); 

星期一, 11月 17, 2014

[jQuery API] JSON SyntaxError: Unexpected token s

今天call同事的api,發現http status都是200正確,但都跑到$.ajax的error handler

17 Nov 2014 17:39:07,698 [DEBUG] [frmDeviceMgmt] jqXHR.responsetext: undefined log4javascript.min.js:155
17 Nov 2014 17:39:07,700 [DEBUG] [frmDeviceMgmt] textStatus: parsererror log4javascript.min.js:155
17 Nov 2014 17:39:07,700 [DEBUG] [frmDeviceMgmt] errorThrown: SyntaxError: Unexpected token s

查了一下原來是回傳的JSON格式是驗證錯誤的關係,踩雷共勉之:D

星期四, 11月 13, 2014

[Javascript] 日期增加運算

常用的增加時間運算函式,有興趣的朋友可以選用。可以自行設定Interval,非常方便:D
Reference: http://stackoverflow.com/questions/1197928/how-to-add-30-minutes-to-a-javascript-date-object


 function dateAdd(date, interval, units) {
        var ret = new Date(date); //don't change original date
        switch(interval.toLowerCase()) {
            case 'year'   :
                ret.setFullYear(ret.getFullYear() + units);
                break;
            case 'quarter':
                ret.setMonth(ret.getMonth() + 3*units);
                break;
            case 'month'  :
                ret.setMonth(ret.getMonth() + units);
                break;
            case 'week'   :
                ret.setDate(ret.getDate() + 7*units);
                break;
            case 'day'    :
                ret.setDate(ret.getDate() + units);
                break;
            case 'hour'   :
                ret.setTime(ret.getTime() + units*3600000);
                break;
            case 'minute' :
                ret.setTime(ret.getTime() + units*60000);
                break;
            case 'second' :
                ret.setTime(ret.getTime() + units*1000);
                break;
            default       :
                ret = undefined;
                break;
        }
        return ret;
    }

星期日, 11月 02, 2014

[AngularJS] Retrieve JSON Data的key與data

一般使用ng-repeat的時候,除了有一般Array的結構之外,
有時API回傳的結果可能需要透過JSON DATA內部的Key結構來綁定。

今天的Case是要綁定一個問卷:D 資料結構長這個


為了讓元素的name id不一致也用了nested ng-repeat如何拿$index的方法,範例如下:

使用ng-init可以將第一層的迴圈$index透過 qTitleIndex取得
    

    <form id="investQuestionnaireForm">
     <div id="investQuestionnaireList"
      ng-controller="MyQuestionnaireCtrl" class="dialog-moduleContent msgBoxDetail">
   <div class="question-list">
    <ul >
     <li ng-repeat="(qTitle, ansList) in questionnaireList"
      ng-init="qTitleIndex = $index">
      <div>{{qTitle}}</div>
      <ul class="answerlist">
       <li ng-repeat="ans in ansList">
        <input type="radio" name="{{qTitleIndex}}_ans_{{$index}}" value="{{ans}}" /> {{ans}} <br/>
       </li>
      </ul>
     </li>
    </ul>

   </div>
     </div>
最後示意
 

星期六, 11月 01, 2014

[AngularJS] 使用jquery來呼叫Angular scope 方法與更新變數

想在舊的jQuery專案內呼叫Angular的方法與變數,可以在jquery中使用以下方法取得scope

var ngScope = angular.element(document.getElementById('元素ID')).scope();

ngScope即可以操作原本在ng內的方法與變數了,在透過jquery更新完變數後,記得要呼叫$apply來告知Angular裡面的變數的值已改變了!!

參考以下完整範例:



星期一, 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);

星期五, 9月 19, 2014

[jQuery Mobile] 動態更改jquery mobile 按鈕的圖示

記錄一下如何動態變更jquery mobile 生成的按鈕Icon. http://stackoverflow.com/questions/12627864/change-data-icon-on-click-with-jquery-mobile


$(buttonSelector).attr('data-icon', newIcon)
                 .find('.ui-icon')
                     .addClass('ui-icon-' + newIcon)
                     .removeClass('ui-icon-' + oldIcon);

星期三, 9月 10, 2014

[AngularJS] 如何在UI-Bootstrap取得input file

今天在使用DialogService的時候,在modal那層的controller一直取不到input file的$scope變數,查了一下在以下這篇討論:

http://stackoverflow.com/questions/23913998/how-to-access-file-input-in-controller-using-angular-ui-bootstrap-modal

解法如下:


透過自已新建一個fileService,再新增一個directive語法去記錄檔案改變時,將file存到fileService

[CSS] IE8 透明度寫法

記錄一下如何在萬惡的IE8支援透明度:D

img { opacity: 0.4; filter: alpha(opacity=40); /* For IE8 and earlier */ }

星期二, 9月 09, 2014

[JavaScript] 快快樂樂學log4javascript

log4javascript 是基於Apache log4j的log系統,基本上用過log4j的人應該很快就可以上手。
有興趣的話可以看一下之前的筆記: [Java] 快快樂樂學會log4j

Appender 

提供以下幾種Appender

Appender
AlertAppender =>將log透過alert秀出來
AjaxAppender => 將log寫到Server存起來
PopUpAppender
InPageAppender
BrowserConsoleAppender => 將log印在console上

星期四, 9月 04, 2014

[D3.js] 使用d3.js畫出Google 風格的測量儀器效果

使用d3.js來製作google style的測量儀器效果,用來顯示cpu、mem非常直覺 :D
作者說可以任意用在商業用途上,請參考作者的gist
https://gist.github.com/tomerd/1499279


星期三, 9月 03, 2014

[D3.js] 長在D3.js上面的繪圖函式庫

如果喜歡D3又想要加速繪圖,可以試試以下的基於D3的第三方繪圖函式庫,輕鬆體驗D3畫報表的爽度 :D,目前依Github Start數最高的為Rickshaw。

c3

C3 enables deeper integration of charts into your application.


dimple

An object-oriented API for business analytics powered by d3.

Dc.js (Dimensional Charting Javascript Library)

dc.js is a javascript charting library with native crossfilter support and allowing highly efficient exploration on large multi-dimensional dataset (inspired by crossfilter's demo). It leverages d3 engine to render charts in css friendly svg format. Charts rendered using dc.js are naturally data driven and reactive therefore providing instant feedback on user's interaction. The main objective of this project is to provide an easy yet powerful javascript library which can be utilized to perform data visualization and analysis in browser as well as on mobile device.


xCharts

xCharts is a JavaScript library for building beautiful and custom data-driven chart visualizations for the web using D3.js. Using HTML, CSS, and SVG, xCharts are designed to be dynamic, fluid, and open to integrations and customization.


Rickshaw 

Rickshaw is a JavaScript toolkit for creating interactive time series graphs.


星期二, 9月 02, 2014

[Raphael.js] 基於Raphaeljs 之上的繪圖函式庫

最近由於新的任務要在web上呈現一些數據,
本來想使用d3.js,但任務需求一定要支援可怕的IE 8相容性問題,
google了一下有其他workaround (r2d3.js與aight.js),但可能還有其他未知的問題xd
考慮是否選擇另一套 Raphaeljs (http://raphaeljs.com/),Raphael是一套知名在web上畫出向量圖形的函式庫,主要會依瀏覽器支援的狀況使用SVG(IE 9下不支援)或VML(< IE 8)來進行向量繪圖,不過社群活躍度就不如D3了。

當然主要的任務是畫一些報表的圖形,找了一些基於Raphaeljs上頭的繪圖工具: D

gRaphael (MIT License)

http://g.raphaeljs.com/
較陽春版的charts


星期日, 8月 31, 2014

[AngularJS] NVD3基於D3繪圖的directive module


An AngularJS directive for NVD3 re-usable charting library (based on D3).
Easily customize your charts via JSON API.

NVD3讓你可以透過directive來實現D3的繪圖效果: D,使用Angular需要圖表呈現可以考慮



星期一, 8月 25, 2014

[WordPress] 改wordpress的相關手法筆記

本篇記錄一下簡單幫朋友建置wp的心得

修改siteurl

在資料表wp_options裡面有siteurl的欄位,修改後就能變更網站的固定網址


修改主標題選單

header.php的位置,每次升級themes前請小心header.php被更新後還原

content/themes/<你下載的佈景主題目錄>/header.php

判斷使用者有沒有登入的function


WooCommerce修改側欄選單的項目

外觀->小工具

從可用小工具拖拉WooCommerce到Sidebar即可

WooCommerce修改商品頁先顯示分類


WooCommerce->設定->Tab商品->Shop Page Display->改為顯示子類別



[AngularJS] 實作簡單的multipart uplaod

簡單記錄一下ng處理上傳的相關資源
Please note that solutions that use FormData(), such as the ones presented here in other answers, do not work correctly in older IE browsers.

The correct solution should use a backup strategy for that, such as using iFrames. There are already many angular JS modules to perform file uploading:

http://stackoverflow.com/questions/18571001/file-upload-using-angularjs
http://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
https://egghead.io/lessons/angularjs-file-uploads

星期日, 8月 17, 2014

[Alfresco] 上傳大檔的相關問題筆記


先前處理alfresco上傳的議題
  1. Heap Size issue (Need to increase that) 
  2. JVM memory allocation 
  3. session time out (It will take more time to write the data on created content so need to make sure session timeout does not happens)

[jQuery plugin] 使用同一個驗證規則來驗證多個textobx欄位

今天有個畫面需求,需用驗證多個textbox (也可以動態產生),使用同一個規則。 一般來說jquery validator只會驗證一個元素(假設你有多個name故意一樣,也只有一個會被驗證)

以下這個StackoverFlow討論串有提供另一個解法:

http://stackoverflow.com/questions/15739390/validating-multiple-textbox-having-same-name-with-jquery-validator-validates-onl



星期五, 8月 15, 2014

[AngularJS] 自訂directive控制圖片找不到

如果遇到頁面的圖片載入失敗時,通常會load預設的圖片,避免有叉燒包的情況。
可以自建一個directive來處理此事件

以下是Stackoverflow的解法:
http://stackoverflow.com/questions/16310298/if-a-ngsrc-path-resolves-to-a-404-is-there-a-way-to-fallback-to-a-default


app.directive('errSrc', function() {
  return {
    link: function(scope, element, attrs) {

      scope.$watch(function() {
          return attrs['ngSrc'];
        }, function (value) {
          if (!value) {
            element.attr('src', attrs.errSrc);
          }
      });

      element.bind('error', function() {
        element.attr('src', attrs.errSrc);
      });
    }
  }
})

星期一, 8月 11, 2014

[NetBeans] NetBeans安裝不同的佈景主題

說明如何簡單的更換NetBeans的佈景主題:D
Themes are contained in a .zip archive.
  1. Open the Options window: Tools -> Options (see picture 1)
  2. Press the Import button (see picture 1)
  3. Press the Browse button and select the theme file (a .zip archive).
  4. Tick the checkbox to select all settings (just Fonts & Colors will be fine as well, those are the themes) (see picture 2)
  5. Press OK and accept the confirmation dialog
  6. After restarting, go to Options again and select the theme at Fonts & ColorsProfile (see picture 1)

Options dialog

[Angular] MVC MVVM MVP 說文解字

常見的 MVC MVVM MVP 框架說文解字
取自:
https://plus.google.com/+IgorMinar/posts/DRUAkZmXjNV

Igor Minar

公開分享 - 2012年7月19日


MVC vs MVVM vs MVP. What a controversial topic that many developers can spend hours and hours debating and arguing about.

For several years +AngularJS was closer to MVC (or rather one of its client-side variants), but over time and thanks to many refactorings and api improvements, it'snow closer to MVVM – the $scope object could be considered the ViewModel that is being decorated by a function that we call a Controller.

Being able to categorize a framework and put it into one of the MV* buckets has some advantages. It can help developers get more comfortable with its apis by making it easier to create a mental model that represents the application that is being built with the framework. It can also help to establish terminology that is used by developers.

Having said, I'd rather see developers build kick-ass apps that are well-designed and follow separation of concerns, than see them waste time arguing about MV* nonsense. And for this reason, I hereby declare AngularJS to be MVW framework - Model-View-Whatever. Where Whatever stands for "whatever works for you".

Angular gives you a lot of flexibility to nicely separate presentation logic from business logic and presentation state. Please use it fuel your productivity and application maintainability rather than heated discussions about things that at the end of the day don't matter that much.




其他討論串:

星期五, 8月 08, 2014

[AngularJS] angular 執行順序

這篇文章回應了angular app執行順序:D 附執行範例。

http://stackoverflow.com/questions/20663076/angularjs-app-run-documentation

Here's the calling order:
  1. app.config()
  2. app.run()
  3. directive's compile functions (if they are found in the dom)
  4. app.controller()
  5. directive's link functions (again if found)
Here's a simple demo where you can watch each execute (and experiment if you'd like).
Run blocks - get executed after the injector is created and are used to kickstart the application. Only instances and constants can be injected into run blocks. This is to prevent further system configuration during application run time.
Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the service have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests.
One place you see run blocks used is for authentication
<div ng-app="myApp" ng-controller="myCtrl">
    <div test1 test2> </div>
</div>
var myApp = angular.module('myApp', []);
myApp.factory('aProvider', function() {
   console.log("factory");
});
 
myApp.directive("test1", function() {
    console.log("directive setup");
    return {
        compile: function() {console.log("directive compile");}
    }
});
 
myApp.directive("test2", function() {
    return {
        link: function() {console.log("directive link");}
    }
});
 
myApp.run(function() {
    console.log("app run");
});
 
myApp.config( function() {
    console.log("app config");
});
 
myApp.controller('myCtrl', function($scope) {
    console.log("app controller");
});

星期三, 7月 30, 2014

[Alfresco] impersonate 登入用戶

alfresco提供以下方法讓你可以模仿別的用戶登入的授權。


//get current user
  String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
  String fakeUser = "IAMBIGD";
  LOGGER.debug("currentUser:" + currentUser);
  if (currentUser == null || !currentUser.equals(fakeUser)) {
            // AuthenticationUtil.setCurrentUser(username);
   //set impersonate 
   AuthenticationUtil.setFullyAuthenticatedUser(fakeUser);
  }

星期二, 7月 22, 2014

[AngularJS] 如何使用form validation驗證input=file

原生的ng並不支援file element的validation,可透過自已新增directive來達到這個功能。

directive

app.directive('validFile',function(){
  return {
    require:'ngModel',
    link:function(scope,el,attrs,ngModel){
      //change event is fired when file is selected
      el.bind('change',function(){
        scope.$apply(function(){
          ngModel.$setViewValue(el.val());
          ngModel.$render();
        });
      });
    }
  }
});

HTML


Input is valid: {{myForm.userUpload.$valid}} Selected file: {{filename}}

[AngularJS] 初學者的angular常用語法筆記

最近重回NG的懷抱,
從邊做專案的過程中,
記錄一些常用的手法。避免會忘記XD

ng-class

//設定某個物件被選擇
 ng-class="{true: 'table-row-selected', false: ''}[product.selected]"

Filter

//取得被選擇的使用者數量
  $scope.getSelectedUsers = function() {
   var selectedObjs = $filter("filter")($scope.userList, {
    selected: true
   })
   return selectedObjs;
  };

陣列反轉

//html 
ng-repeat="folder in parentFolders.slice().reverse()


改變url上面的參數

$location.path('/login');

轉頁

$window.open('http://www.yahoo.com.tw');

如果從已知的array移除指定的item

$scope.userList.splice($index, 1);//移除使用者清單內的某一用戶

事件處理$broadcast, $emit, $on


$broadcast:
發送事件的方法,向下分派事件到所有的子scope範圍。此外也可以由$rootScope發送事件,但要慎用。

$emit:
發送事件的方法,向上分派事件到scope階層範圍。

$on 接受事件的方法,發送端可帶入參數至接收端


將$http request加入common的header

由於REST API很流行,大家都會定義呼叫時要帶入application/json,做法如下。
app.run(['$http', function($http) {

// The $http service will automatically add certain HTTP headers to all requests. These defaults can be fully configured by accessing the $httpProvider.defaults.headers configuration object, which currently contains this default configuration:

// $httpProvider.defaults.headers.common (headers that are common for all requests):
// Accept: application/json, text/plain, * / *
// $httpProvider.defaults.headers.post: (header defaults for POST requests)
// Content-Type: application/json
// $httpProvider.defaults.headers.put (header defaults for PUT requests)
// Content-Type: application/json


 $http.defaults.headers.common['Content-Type'] = 'application/json';
}])


$http GET content-type header無法正確送出的解決方法

[AngularJS] $http無法送出 content-type header

如何使用$watch監控JSON 物件

Call $watch with true as the third argument:
 
$scope.$watch('form', function(newVal, oldVal){
    console.log('changed');
}, true);

By default when comparing two complex objects in JavaScript, they will be checked for "reference" equality, which asks if the two objects refer to the same thing, rather than "value" equality, which checks if the values of all the properties of those objects are equal. Per the Angular documentation, the third parameter is for objectEquality: When objectEquality == true, inequality of the watchExpression is determined according to the angular.equals function. To save the value of the object for later comparison, the angular.copy function is used. This therefore means that watching complex objects will have adverse memory and performance implications.

星期日, 7月 20, 2014

[AngularJS] 使用angular ui-bootstrap 發生tooltip 404

今天開另一個專案載入UI-bootstrap使用tooltip時,發生找不到相關的樣版 *.tpls.html 可以透過$templateCache.removeAll();清除後就正常, 之後再把這個註解就沒問題了。
 app.run(['$templateCache',function($templateCache){
  $templateCache.removeAll();
 }]);

星期四, 7月 17, 2014

[Sublime Text] 寫網站的神級編輯器 筆記



剛好趁換新的Mac pro記錄一下安裝Sublime的過程,
目前已用了一年多了,細節大家看網路應該就一堆介紹啦,
所以不再多對它介紹了XD

使用版本:

Sublime Text 3

安裝第一個pluging "Page Control"


View->Show Console

將以下的install code貼到Console

import urllib.request,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404' + 'e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)

星期三, 7月 16, 2014

[Java] 簡單的User authorization機制

常用到的使用者是否有正確的權限存取當前頁面的機制,Java可以透過Filter來達到。
可依個人需求再強化嚕。

This can be handled in a Filter and there are great explanation and example in StackOverflow Servlet-Filter wiki.
Adapting the code there for your problem (note the addition and usage of the needsAuthenticationmethod):
@WebFilter("/*")
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig config)
        throws ServletException {
        // If you have any  in web.xml, then you could get them
        // here by config.getInitParameter("name") and assign it as field.
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
        throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);

        String requestPath = httpServletRequest.getRequestURI();

        if (needsAuthentication(requestPath) ||
            session == null ||
            session.getAttribute("user") == null) { // change "user" for the session attribute you have defined

            response.sendRedirect(request.getContextPath() + "/login"); // No logged-in user found, so redirect to login page.
        } else {
            chain.doFilter(req, res); // Logged-in user found, so just continue request.
        }
    }

    @Override
    public void destroy() {
        // If you have assigned any expensive resources as field of
        // this Filter class, then you could clean/close them here.
    }

    //basic validation of pages that do not require authentication
    private boolean needsAuthentication(String url) {
        String[] validNonAuthenticationUrls =
            { "Login.jsp", "Register.jsp" };
        for(String validUrl : validNonAuthenticationUrls) {
            if (url.endsWith(validUrl)) {
                return false;
            }
        }
        return true;
    }
}
I would recommend to move all the pages that require authentication inside a folder like app and then change the web filter to
@WebFilter("/app/*")
In this way, you can remove the needsAuthentication method from the filter.