2013-07-24 10 views
10

Używam programu HandsOnTable do edytowania tabel bazy danych bardziej interaktywnych w mojej witrynie.Ręczne wymienianie Zastąp wartości autouzupełniania kluczem przed opublikowaniem

HandsOnTable spełnia prawie wszystkie moje wymagania, z tym że niektóre kolumny w mojej bazie danych faktycznie przechowują klucze obce zamiast lokalnych wartości łańcuchowych.

W interfejsie użytkownika chciałbym, aby te kolumny były wyświetlane jako menu rozwijane, w których użytkownik wybiera czytelną wartość odwzorowaną na poprzednio wymieniony klucz obcy (tj. Coś takiego jak nazwa/wartość HTML select).

Niestety HandsOnTable nie ma takiego typu komórki. Najbliższą rzeczą jest autocomplete. To pozwala mi utworzyć menu rozwijane, ale zawiera tylko wartości; brak odpowiednich kluczy. Oto w jaki sposób tworzony jest:

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

Więc co mam zamiar to wysłać dwa ciągi JSON z serwera:

jeden zawierający parametry potrzebne HandsOnTable do renderowania tabeli:

{ 
    "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"]} 
    ] 
} 

drugi klucze do mapowania wartości

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

tej pory tak dobrze. Teraz najtrudniejsza część:

HandsOnTable ma funkcję (getData()), który umożliwia mi do pobierania danych tabele ciąg Json gotowe do wysłania z powrotem do serwera:

var jdata = myHandsOnTable.getData(); 

Gdzie jdata będzie wyglądać mniej tak:

"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" } 
] 

teraz przed wysłaniem, chciałbym wymienić, że wartości dla węzła z kluczem ich dopasowanie pary w ciągu mappings json Customer.

Jak najlepiej to osiągnąć w JavaScript/JQuery?

Czy istnieje funkcja, która działa mniej więcej następująco ?:

jdata.replaceNode('node', mappings) 

Dzięki

Odpowiedz

8

miałem podobny problem i oto co zrobiłem ...

Dla każdej kolumny klucza obcego, Przechowałem 2 wartości w trybie ręcznym; jeden dla samego id, który ustawiam jako ukrytą kolumnę, a drugi jest przyjazną dla użytkownika wartością tekstu jako rozwijanymi.

Za każdym razem, gdy zmieni się wartość rozwijanego menu, zmieniam również odpowiedni ukryty identyfikator. W moim przypadku rozwijam listę poza polem ręcznym jako filtr, którego używam do mapowania par klucz/wartość, ale możesz użyć Hashtables lub cokolwiek innego.

Teraz kod ...

Handsontable config:

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

Po zmiana wydarzenie (tzw każdym nastąpiła zmiana w tabeli):

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); 
     } 
    }); 
    } 
} 

ten sposób można zmienić klucze obce jak ty i nie trzeba przechodzić przez to wszystko przed zapisaniem. Ułatwia to również wysyłanie danych tabeli z powrotem do serwera.

W Podsumowując,

  • Użytkownik współdziała z CategoryName kolumnie (który jest związkiem typu autocomplete).
  • Kolumna CatgoryID jest ukryta dla użytkownika, ustawiając szerokość kolumny na 0, korzystając z opcjido ręcznego ustawiania.
  • Gdy zmieni się pole CategoryName, należy użyć zdarzenia afterChange, aby ustawić odpowiednią kolumnę . W moim przypadku używam menu rozwijanego gdzieś indziej na stronie, aby zamapować Name => ID, ale możesz użyć innych środków, takich jak hashtable.

Mam nadzieję, że to ma sens ...

+0

Dzięki @PostureOfLearning, można wyjaśnić, co następuje: Jeśli dobrze rozumiem użytkownik wchodzi w interakcję z 'CategoryName' kolumna, która jest typu 'autouzupełniania' i zewnętrzna' dropdown/select' '# CategoriesFilterDropdown' nie jest widoczna dla użytkownika, ale służy do uproszczenia procesu mapowania. Jak ukryć kolumnę 'CategoryID'? Czy po prostu używasz 'renderer' i ustawiasz css' visible visibility' na 'hidden'? – Chopo87

+1

@ Chopo87, zobacz "streszczenie", które dodałem. Jako moje "narzędzie do mapowania" używam CategoriesFilterDropdown, które jest widoczne i znajduje się gdzie indziej na stronie. Robię to, ponieważ potrzebowałem menu widocznego dla innych celów i nie odczuwałem potrzeby duplikowania danych. w twoim przypadku możesz użyć hashtable zamiast szukać identyfikatorów. – PostureOfLearning

+0

Świetnie, bardzo dziękuję @ PostureOfLearning !!! – Chopo87

0

JExcel jest alternatywą dla wtyczki handsontable że posiada pełne wsparcie dla k => V rozwijanego menu. Bardziej zaawansowany demo używając opcji warunkowych w swoim liście rozwijanej można znaleźć na stronie: 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>

Powiązane problemy