星期一, 7月 08, 2013

[Java] 監看誰呼叫了目前的程式

今天要找一個奇怪的bug,需要追踨整個Java Class呼叫的Stack

StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace()
According to the Javadocs:
The last element of the array represents the bottom of the stack, which is the least recent method invocation in the sequence.
StackTraceElement has getClassName()getFileName()getLineNumber() andgetMethodName().
You will have to experiment to determine which index you want (probably stackTraceElements[1] or[2]).

星期三, 6月 26, 2013

[Java] 計算Concurrent User

客戶希望能看到網站目前的在線人數有哪些,
網路上大家都使用HttpSessionListener與HttpSessionBindingListener
二者的用法有點不一樣,但都可以達到一樣的效果。


細節的說明可以參考這篇:

這次的測試用HttpSessionBindingListener的示範:

星期四, 5月 30, 2013

[Javascript] 透過prototype的方法存取private member

記錄一下先前遇到的事情,
某一天在寫類別的時候,遇到想要用prototype去存取private member的成員,
就偷懶直接把private member改為public member XD,
查了一下Stackflow javascript - accessing private member variables from prototype-defined functions

No, there's no way to do it. That would essentially be scoping in reverse.
Methods defined inside the constructor have access to private variables because all functions have access to the scope in which they were defined.
Methods defined on a prototype are not defined within the scope of the constructor, and will not have access to the constructor's local variables.
You can still have private variables, but if you want methods defined on the prototype to have access to them, you should define getters and setters on the this object, which the prototype methods (along with everything else)will have access to.

function Dog(_dogName){
    var that = this;
    
    var dogname = _dogName || "dog" ;//default setting
  
    that._getName = function(){
       return dogname;
    };
    
    that._setName = function(newName){
         dogname = newName;
    };

};
//use getName to access private member
Dog.prototype.getName = function(){
    return  this._getName();
};
Dog.prototype.setName = function(newName){
    return  this._setName(newName);
};
    
var myDog = new Dog();
console.log("mydog:" + myDog.getName());

var tomDog = new Dog("tom");
console.log("tomDog:" + tomDog.getName());
tomDog.setName("mary");
console.log("tomDog2:" + tomDog.getName());


Fiddle看範例: Go

Reference:
Private Members in JavaScript

星期五, 5月 24, 2013

[jQuery plugins] 超激推 qtip plugin,讓錯誤訊息的位置不會撐爆XD

jquery validate是一個幾乎每個網站都會採用的外掛,
但是常常會因為錯誤訊息讓版面整個錯亂,
最近為了這個問題,找到了qtip2這個外掛,
強力的支援各種jquery plugin的tooptip外掛。

http://craigsworks.com/projects/qtip2/

為了方便使用就支接寫了一個擴充的方法,避免專案太多地方引用重覆的程式碼
原則上只是把範例的程式包起來而已...XD

//移除qtip2
 $.validator.prototype.qtipDestory = function(element){
      if( $(element).valid()){
       $(element).filter(".valid").qtip("destroy"); 
      }
    };
//顯示qtip2
$.validator.prototype.qtip = function(error,element,my,at){
  // Set positioning based on the elements position in the form
  var elem = $(element),  
  corners = ["right center", "bottom left"],
  flipIt = elem.parents("span.right").length > 0;

  if(my == "undefined" && at != "undefined"){
   corners = [my,at];
  }
  
  // Check we have a valid error message
  if(!error.is(":empty")) {
    // Apply the tooltip only if it isn"t valid
    elem.filter(":not(.valid)").qtip({
     overwrite: false,
     content: error,
     position: {
      my: corners[ flipIt ? 0 : 1 ],
      at: corners[ flipIt ? 1 : 0 ],
      viewport: $(window)
     },
     show: {
      event: false,
      ready: true
     },
     hide: false,
     style: {
      classes: "qtip-red" // Make it red... the classic error colour!
     }
    })

    // If we have a tooltip on this element already, just update its content
    .qtip("option", "content.text", error);
  } 
  // If the error is empty, remove the qTip
  else { elem.qtip("destroy"); }
 }

接著就照老樣子在errorPlacement補上一刀
...省略
errorPlacement:function(error,element){  
  $your_validated.qtip(error,element);
},
//驗證成功會把qtip消除
success:$.noop,

有時候你需要手動清除qtip(自已遇到關掉dialog要手動清除qtip)
//別忘了reset
$your_validated.resetForm();
$(".qtip").each(function(){
   $(this).data("qtip").destroy();
})

星期一, 5月 13, 2013

[Eclipse] bitbucket not authorized

先前把flicklinkr的原始碼改放在bitbucket,
今天要checkout的時候遇到not authorized錯誤
原來使用HTTPS將專案拉回的時候,要輸入你bitbucket上的帳號密碼XD

星期四, 5月 09, 2013

[jQuery Plugins] jquery form ajaxsubmit前修正欄位的名稱或值

jquery form是一個很常用的外掛,
能讓我們簡單做到ajax form的效果,
今天有一個需求想要在送出的時候多加一個欄位時該怎麼處理
只要在beforeSubmit的callback event下,
擴充form欄位的array就可以了。

參考stackoverflow
http://stackoverflow.com/questions/247284/modifying-form-values-with-beforesubmit-with-jquery-ajaxsubmit

範例如下

$(form).ajaxSubmit({
       url: apiEndpoint,
       type: "post",
//       data: postData,
       dataType:  "json", 
       beforeSubmit: function(arr, $form, options){
        

       //The array of form data takes the following form: 
       //$.console(arr);
       arr[arr.length] = { name:"draft", value:draft};
}
});

不過在測試multiform/data post的時候似乎不管用,殘念!!

[jQuery API] removeData 一直都拿不掉資料 WTF

今天發生一很怪的bug,想要用removeData移除先前暫存的資料一直移不掉(某些特別的key:user_jmeter-slave1-user1),如果像是簡單一點的ken,jack倒是沒問題。
想說是不是這個key,對$data方法會有bug發生。

結果寫了測試的方法也沒問題!!,範例如下

http://jsfiddle.net/e92s6/2/

但是在 瀏覽器下的console執行js code也不行。

最後發現jquery官方找到了另一條思路的解法(http://jsfiddle.net/rwaldron/AvqeW/9/),
就是再把資料設成null就好了

範例如下:
//清掉資料
$.data("your_key",null)

//判斷資料還存不存在,如果沒存過第一次是會找到undefined!!
var queryUserData = $.data("your_key",null)
if(typeof (queryUserData) == "undefined" || queryUserData == null){
      //做你要幹的事
  //.....
}



星期三, 5月 08, 2013

[Eclispe] 設定utf-8



開發專案前請記得請大家的環境統一設定UTF-8編碼,避免一些中文註解爆了XD
General/WorkSpace/Other: UTF-8


星期三, 4月 24, 2013

[jQuery plugin] 實作Shift + Click多選行為

如果要模擬window shift鍵多選的行為,可以參考以下這篇文章。
Snippet: Shift + Click List Items with jQuery
主要的邏輯是記錄最後一個選擇的項目
$parentNode.delegate("li","click",function(event){
    
    var $currLI = $(this);
   
    if($currLI.hasClass("select_this")){
     
     //unselected
     $.console("[UserList.render] delegate:unselected user");
     
     if(event.shiftKey){
      //just unselected
      $currLI.removeClass("select_this");
     }else{
      //re-locate last selected/unselected
      $currLI.removeClass("select_this");
      $currLI.addClass("last_selected");
      
      $lastSelected.removeClass("last_selected");
      
      //change last selected
      $lastSelected = $currLI;
     }
    }else{
     
     //selected 
     $.console("[UserList.render] delegate:selected user");
    
     //
     // SHIFT + CLICK
     //
     
     var $shiftSelected = [];//record seleted items by shfit key
     if(event.shiftKey){
      
      //shift + click logic 
      if($lastSelected.length > 0){//first click
       
       if($lastSelected == $currLI){
        $.console("[UserList.render] same selection");
        
        return false;
        
       }else{
        
        //detect foward or back
        direction = $currLI.nextAll(".last_selected").length > 0 ? "forward" : "back";
        $.console("[UserList.render] last_selected count:" + $currLI.nextAll(".last_selected").length);
        $.console("[UserList.render] direction:" + direction);
        
        if(direction == "forward"){
         $shiftSelected = $currLI.nextUntil($lastSelected);
        }else{
         //back
         $shiftSelected = $lastSelected.nextUntil($currLI);
        }
        
//        $.console("$shiftSelected:" + $shiftSelected.length);
        $LICollection.removeClass("select_this");//reset pre selected
        
        //final selected items
        $shiftSelected.addClass("select_this");//highlight shift selected
        $lastSelected.addClass("select_this");//highlight last selected
                 $currLI.addClass("select_this");//highlight current selected
                 
       }
       
      }else{
       
       $lastSelected = $currLI;
       $currLI.addClass("select_this last_selected");
      }
      
     }else{
      
      //record last selected
      $lastSelected = $currLI;
      $currLI.addClass("select_this last_selected");
  
     }
     
    }
    
    //for debug
//    $.console("lastselected username:" + $lastSelected.find(".usr_name").html());
    
    if(userlist.selecteEventHandler && typeof(userlist.selecteEventHandler) === "function"){
     userlist.selecteEventHandler($currLI,userlist.getSelectedItems());
    }
   });

星期五, 4月 19, 2013

[jQuery API] append加上fadeIn的效果

今天要遇到想要在append新元素時,加入fadein的效果。
筆記一下..
//userElem為html tag
$(userElem).hide().appendTo($parentNode).fadeIn(1000);

星期日, 4月 14, 2013

[Alfresco] 如何取得webscript的參數

這篇記錄如何從webscript取得QueryString、Path parameter of URL與Post body

QueryString
<url>/people/search/email?filter={email}</url>
function main()
{
   var filter = args["filter"];
}


Path parameter
<url>/person/{userName}</url>
function main()
{
   // Get the user name of the person to get
   var userName = url.extension;
}

Post Body
function main(){
 
//invalid input
if(!json.has("users")){
    status.setCode(status.STATUS_BAD_REQUEST, "The request body format is error.");
    return;
}

var usersIndex ;
var users = json.get("users");//json array
for (usersIndex = 0; usersIndex < users.length(); usersIndex++){
 //Get user val 
 var currentUser = users.get(usersIndex);
    

}

其他補充

url

A host object providing access to the URL (or parts of the URL) that triggered the web script.
context
Alfresco context path, for example /alfresco
serviceContext
Alfresco service context path, for example /alfresco/service
service
Web script path, for example /alfresco/service/blog/search
full
Web script URL, for example /alfresco/service/blog/search?q=tutorial
templateArgs
a map of substituted token values (within the URI path) indexed by token name
args
Web script URL arguments, for example q=tutorial
match
The part of the web script URL that matched the web script URL template
extension
The part of the web script URL that extends beyond the match path (if there is no extension, an empty string is returned)

For example, imagine a web script URL template of
/user/{userid}
and a web script request URL of
/alfresco/service/user/fred?profile=full&format=html
The url root object will respond as follows:
  • url.context => /alfresco
  • url.serviceContext => /alfresco/service
  • url.service => /alfresco/service/user/fred
  • url.full => /alfresco/service/user/fred?profile=full&format=html
  • url.args => profile=full&format=html
  • url.templateArgs['userid'] => fred
  • url.match => /user/
  • url.extension => fred
Reference:
http://wiki.alfresco.com/wiki/Web_Scripts_Examples#URL_Argument_Handling

星期四, 4月 11, 2013

[Java] Filter Url-Pattern 筆記

久久用一下常常會忘記怎麼正確的設定Filter Url-Pattern,
趁著昨天需要用到,筆記一遍。

第一種解法(舊方法):
http://fecbob.pixnet.net/blog/post/38258307-tomcat-default-servlet-%E7%9A%84url-pattern

filter-mapping在web.xml中定義的順序相同。
在web.xml檔中,以下語法用於定義映射:
  1.  以」/’開頭和以」/*」結尾的是用來做路徑映射的。
  2.  以首碼」*.」開頭的是用來做擴展映射的。
  3. 「/」 是用來定義default servlet映射的。
  4.  剩下的都是用來定義詳細映射的。比如: /aa/bb/cc.action


所以,為什麼定義」/*.action」這樣一個看起來很正常的匹配會錯?因為這個匹配即屬於路徑映射,也屬於擴展映射,導致容器無法判斷。

第二種解法:
http://k2java.blogspot.in/2011/04/servlet-filter-mapping-exclude-pattern.html

透過設定init-parm的方式帶入忽略的URL,並透過Regex來處理

Servlet filter mapping exclude pattern

Once you apply a filter to a URL pattern:
<filter-mapping>
    <filter-name>theFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
/*
there's no option in web.xml to exclude a more specific pattern such as: /public/*.

But you can put the exclusion logic in the filter itself:


<filter>
    <filter-name>theFilter</filter-name>
    <filter-class>org.demo.CustomServletFilter</filter-class>
    <init-param>
 <param-name>excludePatterns</param-name>
 <param-value>public/*</param-value>
    </init-param>
</filter>
org.demo.CustomServletFilter excludePatterns public/*

And in the filter code:
public void init(FilterConfig cfg) throws ServletException {
 this.excludePatterns = cfg.getInitParameter("excludePatterns");
 .
 .
 .
}

public void doFilter(ServletRequest request,
           ServletResponse response,
    FilterChain chain) 
 throws IOException, ServletException {
 String url = request.getRequestURL().toString();
 if (matchExcludePatterns(url)) {
     chain.doFilter(request, response);
     return;
 }
 .
 .
 .
}

[Eclispe] eGIT 建立一個repository

建立一個location repo的擷圖,如果要直接丟到Github上的話,請參考這個



星期二, 4月 02, 2013

[Eclipse] 使用eGIT取回Github上面的專案

前言:
由於平常都使用eclispe開發,所以直接安裝git plugin來存取Github的repo是比較方便的,
感覺把一些sample code放在這,比放在blog上好維護多了xd
所以記錄一下如何從github取回專案 :D

前置處理:
1.請先安裝Egit pluign:

Help->Install New Software
EGit - http://download.eclipse.org/egit/updates
記得二個都打勾!!

星期六, 3月 30, 2013

[jQuery plugin] 通知訊息外掛測試

今天試了二個有關訊息通知的外掛,分別是noty跟notify


http://needim.github.com/noty/ (還是github上2012的前十名 :D)
noty的功能比較強大,不過你要怎麼客制化訊息的位置都非常方便。
此外還有queue的功能。


http://redeyeoperations.com/plugins/Notify/
Notify相較之下就比較簡便了,訊息只能秀在最上方,
也沒有queue的功能,如果你有訊息可能會一直出現時,
原本的區塊就會被取代了。


星期一, 3月 25, 2013

[Eclipse] 搜尋取代大量字串

今天需要將一個東西重新命名一下,但整個專案很多地方有引用,需要一個快速取代的方法。
記錄一下eclipse的操作xd,


1.先搜尋要取代的字,指定搜尋範圍






2.接著在搜尋的結果集按右鍵,就可以看到replace all嚕

星期二, 3月 19, 2013

[jQuery] 如何觸發超連結click動作

今天在模擬使用File API下載檔案,需要一個觸發超連結引發下載的動作,筆記一下。
//dom api
document.getElementById('dllink').click(); 
//jquery api
$("#dllink")[0].click();

[Java] Java Javascript/CSS Asset pipeline

將js有效的模組化具有許多維護上的好處,但缺點但js模組多的時候,頁面載入的時間也就愈長,雖然能在產品前將所有的js打包成一份(用linux指令),但感覺流程上並不適用目前的專案。

目前找到pack-tag這個開源軟體,試用過後感覺非常試合導入專案中,不會影響目前Developer的開發,只需替換掉原本的script標籤,並支援javascript minify。

pack-tag

A JSP Taglib for delivering minified, combined and gzip-compressed resources (JavaScript and CSS).

https://github.com/galan/packtag



[jQuery plugin] 不透過submit觸發jquery validation驗證

jquery validation真是不可或缺的好物,每次用往往有很多用法都會忘記。
趁熱筆記一下。
如果想要不透過submit來觸發驗證的話,可以透過.valid()這個方法。
除了整個form全部驗證之外,也可驗證表單內某一要驗證的元件


$("#myform").validate();
$("a.check").click(function() {
    alert("Valid: " + $("#myform").valid());
    return false;
});

Reference: How do I use jQuery Validate directly, without the submit button?

星期三, 3月 13, 2013

[jQuery API] 偵測關閉網頁使用者點選ok或cancel

為了避免使用者在網頁處理中關閉網頁的話,可以綁定onbeforeunload事件來偵測,
但更進一步的應用,可能需要了解使用者到底是按ok還是cancel!!
找到以下這篇所用到的解法,有需要的人可以參考看看。

Way to know if user clicked Cancel on a Javascript onbeforeunload Dialog?
The code within the first setTimeout method has a delay of 1ms. This is just to add the function into the UI queue. Since setTimeout runs asynchronously the Javascript interpreter will continue by directly calling thereturn statement, which in turn triggers the browsers modal dialog. This will block the UI queue and the code from the first setTimeout is not executed, until the modal is closed. If the user pressed cancel, it will trigger another setTimeout which fires in about one second. If the user confirmed with ok, the user will redirect and the second setTimeout is never fired.

$(function(){ 
 
 $(window).bind("beforeunload", function(e) {
  setTimeout(function() {
  
            setTimeout(function() {
                $("body").css('background-color', 'red').html("User click cancel button");
            }, 1000);
        },1);
        return 'are you sure';
 });
 
 //按ok處理
 $(window).unload( function () { 
  console.log('bye bye :)');
  
 } );
 
});

星期日, 3月 10, 2013

[Java] Regex驗證不符合的windows檔案名稱

威猛的範例,參考stackoverfolw這篇討論:
 http://stackoverflow.com/questions/6730009/validate-a-file-name-on-windows
public static boolean isValidName(String text)
{
    Pattern pattern = Pattern.compile(
        "# Match a valid Windows filename (unspecified file system).          \n" +
        "^                                # Anchor to start of string.        \n" +
        "(?!                              # Assert filename is not: CON, PRN, \n" +
        "  (?:                            # AUX, NUL, COM1, COM2, COM3, COM4, \n" +
        "    CON|PRN|AUX|NUL|             # COM5, COM6, COM7, COM8, COM9,     \n" +
        "    COM[1-9]|LPT[1-9]            # LPT1, LPT2, LPT3, LPT4, LPT5,     \n" +
        "  )                              # LPT6, LPT7, LPT8, and LPT9...     \n" +
        "  (?:\\.[^.]*)?                  # followed by optional extension    \n" +
        "  $                              # and end of string                 \n" +
        ")                                # End negative lookahead assertion. \n" +
        "[^<>:\"/\\\\|?*\\x00-\\x1F]*     # Zero or more valid filename chars.\n" +
        "[^<>:\"/\\\\|?*\\x00-\\x1F\\ .]  # Last char is not a space or dot.  \n" +
        "$                                # Anchor to end of string.            ", 
        Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.COMMENTS);
    Matcher matcher = pattern.matcher(text);
    boolean isMatch = matcher.matches();
    return isMatch;
}

星期五, 3月 08, 2013

[jQuery plugin] Clearable textbox

想要提供使用者方便清空textbox的plugin嗎
找到一個符合這個需求的clear textbox plugin

http://viralpatel.net/blogs/clearable-textbox-jquery/

Demo site:
http://viralpatel.net/blogs/demo/jquery/clearable-textboxes/

星期二, 3月 05, 2013

[Javascript] Date.parse在safari NaN解決方法


最近在Safari使用Date.parse的NaN問題,不過以下這個解法,少算了時分秒。
The behavior of the Date.parse method is implementation dependent, on ECMAScript 5, this method can parse ISO8601 formatted dates, but I would recommend you to make the parsing manually.
Some time ago I've made a simple function, that can handle a format specifier argument:
function parseDate(input, format) {
  format = format || 'yyyy-mm-dd'; // default format
  var parts = input.match(/(\d+)/g), 
      i = 0, fmt = {};
  // extract date-part indexes from the format
  format.replace(/(yyyy|dd|mm)/g, function(part) { fmt[part] = i++; });

  return new Date(parts[fmt['yyyy']], parts[fmt['mm']]-1, parts[fmt['dd']]);
}

parseDate('06.21.2010', 'mm.dd.yyyy');
parseDate('21.06.2010', 'dd.mm.yyyy');
parseDate('2010/06/21', 'yyyy/mm/dd');
parseDate('2010-06-21');
Also you could detect the ECMAScript 5 behavior to parse ISO formatted dates, you can check if theDate.prototype.toISOString is available, e.g.:
if (typeof Date.prototype.toISOString == "function") {
  // ES5 ISO date parsing available
}

星期日, 2月 24, 2013

[Alfresco] 在java backed取得post request body

先前已經用過javascript webscript取的post request body
這次要改用javabacked的方式取得。
範例如下:

public void execute(WebScriptRequest req, WebScriptResponse response) {
     
 
     
     InputStream inputBody = req.getContent().getInputStream();
     String requestBody = RequestBODY.get(inputBody,Charset.forName("utf-8"));

//requestBody:{"parentUUID":"23d97062-5310-4b80-864a-a2232238fd11","uuids":[]}

     System.out.println("requestBody:" + requestBody);

}

星期五, 2月 22, 2013

[Alfresco] 下載Zip

原本的alfresco不支援下載多個檔案與資料夾,可以透過自已實作java backed的方式實現。
以下是找到的範例,不過用的alfresco似乎跟我的不一樣:)
http://code.google.com/p/alfresco-application-samples/

[jQuery plugin] 浮水印+驗證器

浮水印加在inputbox是常見的功能需求,但有時候需要與驗證器整合。

function notWatermark(value, element){
        return value != 'enter text...';
    }

    $.validator.addMethod("notWatermark", notWatermark, "Field cannot be empty.");

    $('#SearchForm').validate({
        rules: {
            SomeField: {
                required: true,
                notWatermark: true
            }
         },

Reference:jQuery Watermarked input and validation

星期二, 2月 19, 2013

[jQuery plugin] 多檔下載

目前專案有需求要達到多檔下載的需求,目前看過mega雲端儲存的作法個人是比較喜歡。
以下是找到現成的外掛

multiDownload
http://biesiad.github.com/multiDownload/

jQuery File Download Plugin for Ajax like, feature rich file downloads
http://johnculviner.com/post/2012/03/22/Ajax-like-feature-rich-file-downloads-with-jQuery-File-Download.aspx

模擬頻寬限制軟體

有時候需要模擬客戶端超級爛的網路頻寬的議題XD
Slowyapp可以幫我們快速的完成這件事。

不過只支援Mac OS
http://slowyapp.com/

[jQuery plugin] Text Edit 文字編輯器元件

http://markitup.jaysalvat.com/home/

星期一, 2月 18, 2013

[Javascript] Regex group

實作拖拉上傳資料夾時,
需判斷客戶端使用的瀏覽器是否支援。
使用了regex group的功能,做個group的使用筆記。
chrome version :24.0.1312.57
var browserVersionFullNumber = $.getBrowserVersion();
 var myRegexp = /([\d]+)/g;
 var match = myRegexp.exec(browserVersionFullNumber);
 browserVersion = match[1];  // abc


星期三, 2月 06, 2013

[Alfresco] 檢查當前節點下的路徑是否存在


今天想要提升一下目前上傳元件的功能,需要支援拖拉資料夾的上傳。
昨天已經成功上傳所有目錄檔案,只差建資料夾的整合。

需要一個api來自動建立不存在的資料夾!!,之前已經有實作直接建資料夾的webscript。
目前需要一個如何判斷一個資料夾是否存在的方法。
以下是簡單的範例

星期二, 2月 05, 2013

[jQuery] jQuery countdown

在使用jquery countdown的時候,發生IE8不能正常執行。 發生在轉換Date Object時,Date.parse轉換的格式會因不同的瀏覽器吃的string格式會不一樣。

var expiredDate = $(obj).text();
     $.console("pre expiredDate:" + expiredDate);
     
     expiredDate = expiredDate.replace(/-/g,"/");
     $.console("expiredDate:" + expiredDate);
     
     var bmExpiredDate = new Date(Date.parse(expiredDate)); 
     
     $.console(bmExpiredDate);
    
輸出的結果:

日誌: pre expiredDate:2013-02-17 11:18:31
日誌: expiredDate:2013/02/17 11:18:31
日誌: Sun Feb 17 11:18:31 UTC+0800 2013

 Reference: JavaScript and Dates, What a Mess!

星期一, 2月 04, 2013

[jQuery] 上傳資料夾

目前Chrome瀏覽器在21版以後支援使用者上傳資料夾

多檔上傳
var dropzone = document.getElementById('dropzone');

dropzone.ondrop = function(e) {
  var length = e.dataTransfer.files.length;
  for (var i = 0; i < length; i++) {
    var file = e.dataTransfer.files[i];
    ... // do whatever you want
  }
};

上傳資料夾

dropzone.ondrop = function(e) {
  var length = e.dataTransfer.items.length;
  for (var i = 0; i < length; i++) {
    var entry = e.dataTransfer.items[i].webkitGetAsEntry();
    if (entry.isFile) {
      ... // do whatever you want
    } else if (entry.isDirectory) {
      ... // do whatever you want
    }
  }
};

Notice that a big difference here is that you can treat a dropped object as Entry (FileEntry or DirectoryEntry) by using new function called getAsEntry (webkitGetAsEntry).
After obtaining access to the Entry object, you can use standard file handling methods that were introduced in the FileSystem API specification. For example, this example shows how you can detect if a dropped object is a file or a directory by examining the .isFile(or the .isDirectory) field.

[Testing] modern IE

http://www.modern.ie/virtualization-tools

星期三, 1月 30, 2013

[Alfresco] Tomcat/temp 的上傳暫存檔無法清除

alfresco:3.4.5 深埋很久的bug,用javascript webscript/java backed都會產生暫存檔無法清除的問題 有找到一些討論的訊息 https://issues.alfresco.com/jira/browse/ALF-2363

 =====
 Alfresco QA Team added a comment - 19-May-10 03:23 PM Validated against 3.3.0 beta 39. 
Temp files are removed according to tempFileCleanerTrigger settings in scheduled-jobs-context.xml.

 =====

 alfresco會透過tempFileCleanerTrigger 來清除檔案,相關設定在scheduled-jobs-context.xml。 設定檔路徑在以下/usr/local/TOMCAT/webapps/alfresco/WEB-INF/classes/alfresco

星期五, 1月 25, 2013

[JSP] jsp session getAttribute跟setAttribute都爆炸了 XD

機器上測試用OpenJDK做的session操作整個爆掉(不能取/不能建session)。
都會噴以下二個exception:
setAttribute: Session already invalidated
getAttribute: Session already invalidated

以下是成功於正常的Oracle JDK成功操作session的測試碼,移到新的環境就會爆掉XD

//try{

 HttpSession httpsession = request.getSession(false);
 
 if(httpsession == null){
  System.out.println("HttpSession null");
 }else{
  System.out.println("HttpSession:" + httpsession.getId());
 }
 
  if(httpsession.getAttribute("test") == null){
 
   //throw getAttribute: Session already invalidated
 //if(session.getAttribute("test") == null) { 
   System.out.println("Session not found");
   
   try{
    
    System.out.println("Start to craete session");
    
    //request.getSession(true).setAttribute("test", "HelloSession");
    //session.setAttribute("test", "HelloSession");
    //httpsession.setAttribute("test", "HelloSession");
    
    HttpSession newSession = request.getSession(true);
    if(newSession.isNew()){
     System.out.println("isNew session id:" + newSession.getId());
    }else{
     System.out.println("old session id:" + newSession.getId());
    }
   
    newSession.setAttribute("test", "HelloSession");
    
    System.out.println("Suceed to craete session");
  
    
   }catch(IllegalStateException illeagalStateEx){
    System.out.println("Fail to craete session:" 
          + illeagalStateEx.getMessage());
   }
   
  }else{
   
   System.out.println("Session found");
   
   String sessionValue = 
     (String)httpsession.getAttribute("test");
   
   System.out.println("sessionValue:" + sessionValue);
   
  }
//}catch(Exception ex){
 
 //System.out.println("Global Exception:" + ex.getMessage());

//}

星期一, 1月 21, 2013

[jQuery API] beforeunload 偵測頁面關閉或刷新

有時候你需要偵測使用者刷新或關閉頁面進行一些處理,可以使用beforeunload事件。 //refesh page event
 $(window).bind("beforeunload", function() {
   return "Are you sure?";
 });

When you add return false, a confirmation dialog shows up, delaying the page unload. Meanwhile, the AJAX request finishes. When no return statement is included, the page will immediately unloads, terminating all active connections (and breaking your AJAX request). 

目前測試發現如果使用者按上一頁的話雖會執行這個事件,但卻會造成正在執行的連線中斷(例如:上傳) 不過眼尖發現這個confirm dialog的按鈕其實長的不一樣XD 


[jQuery API] 取得$元素的內容

有時候取要取得目前jquery物件的html是什麼, 目前找到以下解法,如果有其他方法就跪求了XD
var $container = $("<div/>");
var content = $container.append($TargetElem).clone()).html();

[TOMCAT] 設定 session逾期時間

如何設定tomcat的 session逾期時間
單位:分鐘!!
 <session-config>
    <session-timeout>5</session-timeout>
  </session-config>
如果要設定成秒數的話要另外實作,根據下述的資料參考
http://www.velocityreviews.com/forums/t146162-tomcat-5-0-config-timeout-in-seconds.html

That's a strange question. Why do you want to do it?
Anyway, no, it's not possible. Not directly at least. You will have to
implement a session listener and call setMaxInactiveInterval on every
new session. There you can specify the interval in seconds

星期三, 1月 16, 2013

[jQuery plugin] jQuery File Upload

用了一陣子的jQuery File Upload,發現在FF使用小於2MB的檔案,Progress bar無法正常的讀取file bytes XD

See also:
https://github.com/blueimp/jQuery-File-Upload/issues/1905

星期五, 1月 11, 2013

[jQuery plugin] 秒 轉換 為時:分:秒格式

找到的秒數轉時分秒格式的範例
jQuery.fn.time_from_seconds = function() {
    return this.each(function() {
        var t = parseInt($(this).text(), 10);
        $(this).data('original', t);
        var h = Math.floor(t / 3600);
        t %= 3600;
        var m = Math.floor(t / 60);
        var s = Math.floor(t % 60);
        $(this).text((h > 0 ? h + ' hour' + ((h > 1) ? 's ' : ' ') : '') +
                     (m > 0 ? m + ' minute' + ((m > 1) ? 's ' : ' ') : '') +
                     s + ' second' + ((s > 1) ? 's' : ''));
    });
};
加強一下可以支援多國語言
/**
 * Time from seconds
 * Refer from 
 * @author ken tsai
 * @date 2013/1/13
 **/
;(function($) {
 
 $.fn.time_from_seconds = function() {
     return this.each(function() {
         var t = parseInt($(this).text(), 10);
         $(this).data('original', t);
         $(this).text($.timeFromSeconds(t));
     });
 };
 
 $.timeFromSeconds = function(t){
  
    var h = Math.floor(t / 3600);
       t %= 3600;
       var m = Math.floor(t / 60);
       var s = Math.floor(t % 60);
       
//       var conv = (h > 0 ? h + ' hour' + ((h > 1) ? 's ' : ' ') : '') +
//       (m > 0 ? m + ' minute' + ((m > 1) ? 's ' : ' ') : '') +
//       s + ' second' + ((s > 1) ? 's' : '');
       var hour = "", minute = "", second = "";
       if($.timeFromSeconds.defaults.plural){
        hour = (h > 0 ? h + " " + $.timeFromSeconds.defaults.hours + ((h > 1) ? "s " : " ") : " ");
        minute =  (m > 0 ? m + " " + $.timeFromSeconds.defaults.minutes + ((m > 1) ? "s " : " "):" ");
        second =  (s > 0 ? s + " " + $.timeFromSeconds.defaults.seconds + ((s > 1) ? "s " : " "): " ");
       }else{
        hour = (h > 0 ? h + " " + $.timeFromSeconds.defaults.hours: " ");
        minute =  (m > 0 ? m + " " + $.timeFromSeconds.defaults.minutes: " ");
        second =  (s > 0 ? s + " " + $.timeFromSeconds.defaults.seconds: " ");
       }
       return hour + minute + second;
 };

 $.timeFromSeconds.setDefaults = function(defaults){
  $.timeFromSeconds.defaults = defaults;
 };
 
 $.timeFromSeconds.defaults = {
  hours:"hour",
  minutes:"minute",
  seconds:"second",
  plural:true
 };
 
 
})(jQuery);

星期一, 12月 31, 2012

[jQuery UI] autocomplete 控制項

試很久才正常的自動完成控制項, 一開始用keyup的事件綁定後,向後端拿資料,再初始化自動完成控制項, 但就是會有異常的情況,包含後端包出來的JSON的客製的,別頁又可以正常work。 最後終於試了正常的方向,在這記錄一下,以免下次要用又搞很久Orz。 測試版本為jquery ui 1.9.1版
 $( "#user" ).autocomplete({
            source: function( request, response ) {
                $.ajax({
                    url: iANGEL + "manageuser/search/" + $("#user").val(),
     cache: false,
     type:"GET",
     dataType:"json",
                    success: function( data ) {
      //check response data 
      if(data.user_data.status == 200){
       response($.map( data.user_data.result, function( item ) {
        return item;
      
       }));
      }
                       
                    }
                });
            },
   select:function(event,ui){
    $.console("[AUTOCOMPLETE] select");
    //$.console(ui.item);
    $(this).val( ui.item.User_NickName).attr("data",ui.item.User_ID);
    return false;
   }
        }).data( "autocomplete" )._renderItem = function( ul, item ) {
       //$.console(item);
       
       return $( "<li>" )
        .data( "item.autocomplete", item )
        .append( "<a>" + item.User_NickName + "</a>" )
        .appendTo(ul);
  };

星期五, 12月 21, 2012

[jQuery] 頁面刷新處理 (F5鍵)

找了一些偵側頁面被觸發刷新的檢查的二個範例 第一種是補捉按鍵的keycode但是如果按瀏覽器的重新整理無法偵測
$(document).bind("keypress keydown keyup", function(e) {
 
   if(e.which === 116) {
         
         return false;
      }
      if(e.which === 82 && e.ctrlKey) {
       
      
          return false;
      }
 
 });
第二種是比較好的方法,連上一頁跟下一頁都能一起觸發
$(window).bind('beforeunload', function() {

    return "Are u sure to reload?";
});

星期四, 12月 20, 2012

[jQuery API] ajaxPrefilter

//before ajax request handler
<>
$.ajaxPrefilter(function( options, originalOptions, jqXHR ){
  $.console("[ajaxPrefilter] ajax url:" + options.url);  

 });

星期日, 12月 16, 2012

[Javascript] 日期計算的應用


常常會用到又會忘記的日期格式運算。
找了一些文章說用format("yyyy-MM-dd")可以格式化但一直爆炸XD
找到的應用會直接更新在這篇。



//取得現在的日期
var currentTime = new Date(); 
//往前推30天
currentTime.setDate(currentTime.getDate() + (-30));
//第一天跟最後一天
var date = new Date();
var firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);

 
//格式化yyyy/mm/dd
function dateFormat(date){
  var d  = date.getDate();
  var day = (d < 10) ? '0' + d : d;
  var m = date.getMonth() + 1;
  var month = (m < 10) ? '0' + m : m;
  var yy = date.getYear();
  var year = (yy < 1000) ? yy + 1900 : yy;
  
  var finalDate = year + "-" + m + "-" + d;
  return finalDate;
};

//日期相差的天數
function getDiffDays(endDate){
 var date1 = new Date();
  var date2 = new Date(Date.parse(endDate.replace("-", "/")));
  var date3 = date2.getTime() - date1.getTime();//時間差的毫秒数  
  var days = Math.floor(date3/(24*3600*1000));//相差天數
  return days;
};

星期一, 12月 10, 2012

[Javascript] Detect flash version

偵測客戶端目前有沒有裝Flash的外掛。

I agree with Max Stewart. SWFObject is the way to go. I'd like to supplement his answer with a code example. This ought to to get you started:
if(swfobject.hasFlashPlayerVersion("9.0.115"))
{
    alert("You have the minimum required flash version (or newer)");
}
else
{
    alert("You do not have the minimum required flash version");
}
Replace "9.0.115" with whatever minimum flash version you need. I chose 9.0.115 as an example because that's the version that added h.264 support.
If the visitor does not have flash, it will report a flash version of "0.0.0", so if you just want to know if they have flash at all, use:
if(swfobject.hasFlashPlayerVersion("1"))
{
    alert("You have flash!");
}
else
{
    alert("You do not flash :-(");
}

星期日, 12月 09, 2012

[Javascript] setTimeout

經常會使用的setTimeout方法,做個筆記

設定Timeout,預設只會執行一次,毫秒為單位

setTimeout(function() { myFunc(); }, 4000)

重覆執行setTimeout

function myFunc(){
  setTimeout(function(){ myFunc();},4000)
}

取消setTimeout

var timerID = setTimeout(function(){ myFunc();},4000)
clearTimeout(timerID );


設定條件停止


function myFunc(){
if(flag == true){
  setTimeout(function(){ myFunc();},4000)
}
}

其他你感興趣的文章

Related Posts with Thumbnails