2012-10-21 25 views
5

Tôi đã viết một điều khiển UX bọc trong Ext JS 2.x quanh Ext.Form.DateField để xử lý các phím bấm hơi khác nhau. Đặc biệt, khi lịch được hiển thị, tôi muốn phím Tab để chọn ngày được đánh dấu và di chuyển đến trường biểu mẫu tiếp theo.Tab lập trình để điều khiển tiếp theo trong Ext JS

Tôi có trình xử lý khóa hoạt động – nó chọn ngày được đánh dấu và đóng lịch – nhưng tôi không thể chuyển tab đó sang trường tiếp theo.

Tôi có phải tìm ra trường tiếp theo là từ thứ tự tab và cố gắng đặt tiêu điểm của nó không? Điều đó có vẻ khá phức tạp. Hoặc tôi có thể kích hoạt một số sự kiện để tự động điều khiển tab sang trường tiếp theo (ví dụ: chụp Tab nhấn phím trong lịch và xử lý nó, như tôi đang làm, nhưng sau đó chuyển tiếp đến trường ngày cơ bản)?


Edit: Nói tóm lại, là có một Ext (hoặc, ít nhất là cross-platform) cách bắn một sự kiện bàn phím tại một trường mẫu cụ thể không?

+0

bạn có thể sử dụng dispatchEvent(), điều này có thể liên quan: http://stackoverflow.com/questions/596481/simulate-javascript-key-events?lq=1 – pckill

+0

@pckill Điều đó chắc chắn thú vị, mặc dù từ nhận xét có vẻ như nó chỉ hoạt động trên một số trình duyệt nhất định. Có cách nào "Exty" hơn để đạt được điều tương tự không? –

+0

Tôi chưa từng làm việc với ExtJS, nhưng nếu bạn biết trường biểu mẫu tiếp theo là gì, bạn không thể sử dụng phương thức như .focus() hoặc .select() trên nó khi nhấn phím 'Tab'? Sẽ dễ dàng hơn nếu bạn có thể cung cấp một số mã mà bạn đã sử dụng. – micnic

Trả lời

5

Cách tiếp cận I. Chỉ cần không làm event.preventDefault() trong trình xử lý sự kiện nhấn phím/khóa để bạn không chặn trình duyệt thực hiện tác vụ mặc định, tức là điều hướng tab. Ví dụ này hoạt động:

Ext.create('Ext.form.Panel', { 
    title: 'Contact Info', 
    width: 300, 
    renderTo: Ext.getBody(), 
    items: [{ 
     xtype: 'textfield', 
     name: 'name', 
     fieldLabel: 'Name', 
     listeners: { 
      specialkey: function(me, e) { 
       if (e.getKey() == e.TAB) { 
         console.log('Tab key pressed!'); 
         // do whatever you want here just don't do e.preventDefault() or e.stopEvent() if you want the browser tab to next control 
        } 
      } 
     } 
    }, { 
     xtype: 'textfield', 
     name: 'email', 
     fieldLabel: 'Email Address', 
    }] 
}); 

Tôi đã thử nó trong Ext 4 nhưng tất cả các phương pháp cần thiết nên có sẵn từ Ext 2. Nếu bạn vẫn gặp sự cố xin vui lòng chia sẻ một số mã của bạn.

Bắt ra khỏi con đường và cho phép trình duyệt làm công cụ của nó natively thường là tốt nhất và các giải pháp mạnh mẽ nhất ...


Cách tiếp cận II. Nếu bạn có một thành phần phức tạp với nhiều yếu tố, bạn vẫn có thể đạt được các trường hợp Cách tiếp cận I. bởi buộc tập trung vào các yếu tố đầu vào chính (thường là một trường văn bản) trong khi mô phỏng mục tập trung trong một yếu tố cửa sổ bật lên với CSS (một số KeyNav/KeyMap trong phần tử nhập chính sẽ có ích ở đây). Về cơ bản, bạn bắt được tất cả các trường hợp mà người dùng có thể đặt trọng tâm vào cửa sổ bật lên (như nhấp vào nó) và chụp lấy nét lại thành phần tử chính của bạn.

Điều này sẽ vẫn đảm bảo thứ tự tab tự nhiên của các phần tử html, ngay cả khi một số trong số chúng không phải là Thành phần. Tôi tin rằng đó là cách tốt nhất để đi và đáng để đấu tranh để đạt được hầu hết thời gian.

Đó là cách các thành phần như công việc ComboBoxDatePicker (vì bạn có thể thấy sau này luôn đặt trọng tâm thành phần tử chính sau khi vaule được cập nhật. Logic tập trung của ComboBox phức tạp hơn một chút. các liên kết mã nguồn nếu bạn đang nhầm lẫn về cách triển khai nó trong thành phần của bạn, rất sâu sắc.


cách tiếp cận III. khu nghỉ mát cuối. Nếu bạn vẫn cần phải chỉ lập trình tập trung một lĩnh vực (hàng xóm), tương đối dễ làm Mã cho Ext 2.3 (không kiểm tra nó, mặc dù tôi đã sử dụng tài liệu):

var formPanel, // containing form panel 
    currentField, // the field you need to navigate away from 

    fields, 
    currentFieldIdx, 
    nextField; 

fields = formPanel.getForm().items; 
currentFieldIdx = fields.indexOf(currentField); 

if(currentFieldIdx > -1) { 
    nextField = fields.itemAt(currentFieldIdx + 1); 
    nextField && nextField.focus(); 
} 

T.B. Bạn có thể bắn một cách giả tạo Tab nhấn phím qua dispatchEvent() nhưng nó will not trigger hành động điều hướng tab vì lý do bảo mật.

+0

+1 cho PS. Rất tiếc, 'datefield' có hai phần: Tôi đang giữ tab trên lịch nhưng tôi cần nó được xử lý bởi trường văn bản. Tôi không dừng sự kiện một cách giả tạo, nhưng nó không bao giờ được chuyển từ lịch vào trường văn bản. –

+0

đã cập nhật câu trả lời của tôi. HTH. –

+0

Cảm ơn rất nhiều vì đã cập nhật. Phương pháp tiếp cận II và III trông đầy hứa hẹn. Tôi sẽ cung cấp cho họ một thử và báo cáo lại (có lẽ không phải cho đến thứ hai). –

Các vấn đề liên quan