2013/11/04

[ExtJS] 選取textfield部分文字

如果你想要用程式的方式去選取textfield裡特定的文字,各瀏覽器有自己的實作方法,我們使用ExtJS包裝起來,方便開發者使用。

使用案例:
我們使用ExtJS做一個FTP client,在實作"建立新資料夾"的功能時,將會跳出一個Window,裡面包含了一個path field。
參考Filezliia的做法,假設原本的資料夾叫foder1,它會在其後加上/New_Folder當作是新的資料夾名稱,並且會將New_Folder反白起來。因此,使用者可以直接使用這個資料夾名稱。或者直接輸入自定的資料夾名稱,原本預設的資料夾名稱則會被取代。


實作程式碼:
Ext.define('Ext.enhance.form.field.Text', {
 override : 'Ext.form.field.Text',
 selectText : function(start, end) {
  var field = this.inputEl.dom;
  if (field.createTextRange) {
   var selRange = field.createTextRange();
   selRange.collapse(true);
   selRange.moveStart('character', start);
   selRange.moveEnd('character', end);
   selRange.select();
  } else if (field.setSelectionRange) {
   field.setSelectionRange(start, end);
  } else if (field.selectionStart) {
   field.selectionStart = start;
   field.selectionEnd = end;
  }
  field.focus();
 }
});

使用範例:
Ext.define('TonyTuan.CreateFolderWin', {
     extend : 'Ext.window.Window',
     width : 300,
     layout : {
           type : 'fit'
     },
     title : 'Window',
     initComponent : function() {
           var me = this; 
           me.defaultFocus = 'path'; // set focus before call selectText() 
           me.items = [ {
                xtype : 'form',
                bodyPadding : 10,
                layout : 'anchor',
                defaultType : 'textfield',
                items : [ {
                     fieldLabel : 'path',
                     name : 'path',
                     itemId : 'path'
                } ]
           } ];
           me.callParent(); 
           me.on({
                // set default value for path
                show : function() {          
                           me.down('#path').setValue('folder1/New_Folder');
                          me.down('#path').selectText(6,18);         
                }
           });
     }
});

PS: 即使沒有要用selectText,養成設定defaultFocus的習慣,可讓使用者開啟視窗的時候直接輸入,不用再用滑鼠點擊field。

2013/08/21

[ExtJS] 移除File Field出現"No file chosen"(未選擇檔案)提示

當我在用js開發檔案上傳的功能時,我發現當File Field的欄位是空的時候,就會出現"No file chosen"(未選擇檔案)提示。我看了stackoverflow的一些解法,但沒有一個是成功的。



No file chosen
"No file chosen" tooltip

<html>
<head>
</head>
<body>
<input type="file" multiple/>
</body>
</html>



不過我用gmail附件功能時,發現的確是有辦法移除預設的提示,改用自訂的提示。



Gmail可以客製化檔案上傳提示



所以我花了一些時間去trace gamil的source code,發現那個Attach files”按鈕,只是一個div tag,當然可以自訂提示。但是div tag因為安全性因素,是無法trigger檔案選擇器的,一定要file input field才有這個權限。



但是為什麼gmail卻可以做到?其實呢,div tag只是一個wrapper,還是有一個file input field隱藏在背景的。一旦div tag收到click event,我們只要控制程式去trigger file input field的click event可以達到這樣的效果。然後只要在file input field聽onchange event,就可以知道user選哪些檔案了!



以下是ExtJS的範例關於file input field wrapper的範例:



Custom Tooltip for File Uploading in ExtJS



Ext.define('TonyTuan.BrowseButton', {
extend : 'Ext.button.Button',
icon : 'css/images/arrow_up_16x16.png',
text : 'Browse...',
constructor : function(config) {
var me = this;
config.tooltip = 'Attach Files'; // Show custom tooltip instead of "No file chosen".
me.callParent([ config ]);
},
handler : function() {
document.getElementById('upload-field').click(); // To trigger the file field click event
}
});

Ext.define('TonyTuan.FileGrid', {
extend : 'Ext.grid.Panel',
alias : 'widget.fileGrid',
title : 'Files',
store : 'File',
initComponent : function() {
var me = this;
me.columns = [ {
dataIndex : 'filename',
header : 'Filename',
} ];
me.tbar = [ Ext.create('TonyTuan.BrowseButton', {
itemId : 'browseButton'
}) ];
me.callParent(arguments);
}
});

Ext.define('TonyTuan.FilePanel', {
extend : 'Ext.panel.Panel',
title : 'Files',
layout : 'border',
initComponent : function() {
var me = this;
me.items = [ {
region : 'center',
xtype : 'fileGrid',
layout : 'fit',
flex : 3,
margins : '5 5 0 0'
}, {
hidden : true,
region : 'north',
xtype : 'component',
html : '<input type="file" multiple id="upload-field"/>'
} ];
me.callParent(arguments);
me.on({
afterrender : function() {
document.getElementById('upload-field').onchange = function() {
var files = document.getElementById('upload-field').files;
console.log('files', files);
// Add files to your fileGrid store
};
}
});
}
});

2024年React state management趨勢

輕量化 在過去Redux 是 React 狀態管理的首選函式庫。 Redux 提供了強大的功能和靈活性,但也帶來了一定的學習成本和複雜度。 隨著 React 生態的不斷發展,越來越多的開發者開始追求輕量化的狀態管理函式庫。 Zustand 和 Recoil 等庫以其簡單易用、性...