2013-07-24 35 views
10

Tôi đang sử dụng HandsOnTable để làm cho các bảng cơ sở dữ liệu chỉnh sửa tương tác hơn trên trang web của tôi.Có thể thay thế được giá trị tự động hoàn thành bằng khóa trước khi đăng

HandsOnTable đáp ứng gần như tất cả các yêu cầu của tôi ngoại trừ một số cột trong cơ sở dữ liệu của tôi thực sự lưu khóa ngoài thay vì giá trị chuỗi cục bộ. Trong giao diện người dùng, tôi muốn các cột này xuất hiện dưới dạng menu thả xuống trong đó người dùng chọn giá trị có thể đọc được ánh xạ tới khóa ngoại đã đề cập trước đó (ví dụ: tên/giá trị HTML select).

Thật không may, HandsOnTable không có loại ô như vậy. Điều gần nhất với nó là autocomplete. Điều này cho phép tôi tạo một menu thả xuống, nhưng nó chỉ chứa các giá trị; không có khóa tương ứng. Sau đây là cách nó được tạo ra:

"source": ["Jebediah", "Bob", "Bill", "Buzz"] 

Vì vậy, những gì tôi đang lên kế hoạch là để gửi hai chuỗi Json từ máy chủ:

Một chứa các thông số cần thiết bởi HandsOnTable để render bảng:

{ 
    "data": [ 
     { "ID": 1, "Description": "Crude", "Volume": 204, "Customer": "jebediah" }, 
     { "ID": 2, "Description": "Hidrogen", "Volume": 513, "Customer": "Bob" }, 
     { "ID": 3, "Description": "Coal", "Volume": '67', "Customer": "Bill" }, 
     { "ID": 4, "Description": "Wood", "Volume": '513', "Customer": "Buzz" } 
    ], 
    "columns": [ 
     { "data": "ID", "type": "numeric" }, 
     { "data": "Description", "type": "text"}, 
     { "data: "Volume", "type": "numeric" }, 
     { "data": "color", "type": "autocomplete", "strict": "true", 
      "source": ["Jebediah", "Bob", "Bill", "Buzz"]} 
    ] 
} 

Các phím lập bản đồ thứ hai để các giá trị

{ 
    "mappings": [ 
     {"key": 0, "value": "Jebediah"}, 
     {"key": 0, "value": "Bob"}, 
     {"key": 0, "value": "Bill"}, 
     {"key": 0, "value": "Buzz"} 
    ] 
} 

cho đến nay rất tốt. Đây là phần khó khăn:

HandsOnTable có một chức năng (getData()) cho phép tôi để lấy dữ liệu bảng như là một chuỗi Json sẵn sàng để được gửi lại cho máy chủ:

var jdata = myHandsOnTable.getData(); 

đâu jdata sẽ giống như thế này:

"data": [ 
    { "ID": 1, "Description": "Crude", "Volume": 204, "Customer": "jebediah" }, 
    { "ID": 2, "Description": "Hidrogen", "Volume": 513, "Customer": "Bob" }, 
    { "ID": 3, "Description": "Coal", "Volume": '67', "Customer": "Bill" }, 
    { "ID": 4, "Description": "Wood", "Volume": '513', "Customer": "Buzz" } 
] 

Bây giờ trước khi gửi bài, tôi muốn thay thế mà giá trị cho các Customer nút với cặp khóa phù hợp của họ trong chuỗi mappings json.

Làm cách nào để đạt được điều này tốt nhất trong JavaScript/JQuery?

Có một chức năng mà làm việc gì đó như sau ?:

jdata.replaceNode('node', mappings) 

Cảm ơn

Trả lời

8

Tôi đã có một vấn đề tương tự và đây là những gì tôi đã làm ...

Đối với mỗi cột chính nước ngoài, Tôi đã lưu trữ 2 giá trị trong handsontable; một cho chính id, mà tôi đặt là cột ẩn và cột kia là giá trị văn bản có thể đọc được thân thiện với người dùng dưới dạng menu thả xuống.

Mỗi lần giá trị của menu thả xuống được thay đổi, tôi cũng thay đổi id ẩn tương ứng. Trong trường hợp của tôi, tôi có một dropdown bên ngoài handsontable như một bộ lọc mà tôi sử dụng để ánh xạ các cặp khóa/giá trị, nhưng bạn có thể sử dụng Hashtables hoặc bất kỳ thứ gì khác.

Bây giờ mã ...

Handsontable cấu hình:

afterChange: function (changes, source) { AfterChange(changes, source); } 

Sau sự kiện thay đổi (gọi mọi có sự thay đổi trong bảng):

function AfterChange(Changes, Source) { 

    if (Source === 'loadData') { 
     return; //don't save this change 
    } 
    var rowIndex = 0, columnID = 1, oldTextVal = 2, newTextVal = 3, ntv = '', nv = ''; 
    $(Changes).each(function() { 
     if (this[columnID] === 'CategoryID') { 
      // Do nothing... 
      //To make sure nothing else happens when this column is set through below 
     } 
     else if (this[columnID] === 'CategoryName') { 
      ntv = this[newTextVal]; 
      //This is where I do my mapping using a dropdown. 
      nv = $('#CategoriesFilterDropdown option').filter(function() { return $(this).text() === ntv; }).val(); 
      //13 is my CategoryID column 
      $container.handsontable('setDataAtCell', this[rowIndex], 13, nv); 
     } 
    }); 
    } 
} 

Bằng cách này, bạn thay đổi các phím nước ngoài như bạn và không cần phải lặp qua tất cả trước khi lưu. Nó cũng làm cho nó dễ dàng để gửi dữ liệu bảng như là trở lại máy chủ.

Trong tóm tắt,

  • Người dùng tương tác với CategoryName cột (mà là loại autocomplete).
  • Cột CatgoryID bị ẩn với người dùng bằng cách đặt chiều rộng cột thành 0 bằng cách sử dụng tùy chọn colWidths có thể đồng bộ được.
  • Khi thay đổi trường CategoryName, hãy sử dụng sự kiện afterChange để đặt cột CategoryID tương ứng. Trong trường hợp của tôi, tôi sử dụng một danh sách thả xuống ở một nơi khác trên trang để ánh xạ Name => ID, nhưng bạn có thể sử dụng các phương tiện khác như một hashtable.

Tôi hy vọng nó có ý nghĩa ...

+0

Cảm ơn @PostureOfLearning, bạn có thể làm rõ như sau: Nếu tôi hiểu đúng người dùng tương tác với 'CategoryName' cột thuộc kiểu 'autocomplete' và' dropdown/select' bên ngoài '# CategoriesFilterDropdown' không hiển thị cho người dùng, mà thay vào đó được sử dụng để đơn giản hóa quá trình ánh xạ. Ngoài ra, làm cách nào để ẩn cột 'Danh mụcID'? Bạn có sử dụng 'renderer' và đặt thuộc tính css' visibility' thành 'hidden' không? – Chopo87

+1

@ Chopo87, xem phần 'tóm tắt' tôi đã thêm vào. Là 'công cụ lập bản đồ' của tôi, tôi sử dụng CategoryFilterDropdown có thể nhìn thấy và đặt ở một nơi khác trên trang. Tôi làm điều này vì tôi cần trình đơn thả xuống hiển thị cho các mục đích khác và không cảm thấy cần phải sao chép dữ liệu. trong trường hợp của bạn, bạn có thể muốn sử dụng một hashtable để tra cứu các ID thay thế. – PostureOfLearning

+0

Tuyệt vời, Cảm ơn bạn rất nhiều @ PostureOfLearning !!! – Chopo87

0

jExcel là một plugin thay thế cho handsontable có hỗ trợ đầy đủ cho Dropdowns k => v. Một bản demo cao cấp hơn sử dụng tùy chọn điều kiện trong danh sách thả xuống của bạn có thể được tìm thấy tại địa chỉ: http://jsfiddle.net/orz8frko/3/

data = [ 
 
    [3, 'Cheese'], 
 
    [1, 'Apples'], 
 
    [2, 'Carrots'], 
 
    [1, 'Oranges'], 
 
]; 
 

 
$('#my').jexcel({ 
 
    data:data, 
 
    colHeaders: ['Model','Color'], 
 
    colWidths: [ 300, 80 ], 
 
    columns: [ 
 
     { type: 'dropdown', source:[ 
 
      {'id':'1', 'name':'Fruits'}, 
 
      {'id':'2', 'name':'Legumes'}, 
 
      {'id':'3', 'name':'General Food'}] 
 
     }, 
 
     { type: 'text' }, 
 
    ] 
 
});
body { background-color:#eee }
<link rel="stylesheet" type="text/css" href="https://bossanova.uk/components/bossanova-ui/css/jquery.jexcel.css"> 
 

 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script type="text/javascript" src="https://bossanova.uk/components/bossanova-ui/js/jquery.jexcel.js"></script> 
 

 
<div id="my"></div>

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