2013-07-24 7 views
10

Ich verwende HandsOnTable, um die Bearbeitung von Datenbanktabellen auf meiner Website interaktiver zu gestalten.Handsontable Ersetzen Sie die Werte für die automatische Vervollständigung durch einen Schlüssel, bevor Sie die Nachricht senden.

HandsOnTable erfüllt fast alle meine Anforderungen mit der Ausnahme, dass einige Spalten in meiner Datenbank tatsächlich Fremdschlüssel statt lokale Zeichenfolgenwerte speichern.

In der Benutzeroberfläche möchte ich, dass diese Spalten als Dropdown-Menüs angezeigt werden, in denen der Benutzer einen lesbaren Wert auswählt, der dem zuvor erwähnten Fremdschlüssel zugeordnet ist (z. B. so etwas wie ein HTML-Name/Wert select).

Leider hat HandsOnTable keinen solchen Zelltyp. Die nächste Sache ist autocomplete. Dadurch kann ich ein Dropdown-Menü erstellen, das jedoch nur Werte enthält. keine entsprechenden Schlüssel. Hier ist, wie es erstellt:

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

Also, was ich will, ist zwei Json Strings vom Server zu senden:

Einer der Parameter benötigt von HandsOnTable enthält die Tabelle zu machen:

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

Die zweite Kartierschlüssel auf Werte

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

so weit so gut. Jetzt für den schwierigen Teil:

HandsOnTable hat eine Funktion (getData()), die ich die Tabellen Daten als JSON-String bereit abrufen kann an den Server gesendet werden, zurück:

var jdata = myHandsOnTable.getData(); 

Wo jdata etwas aussehen würde dies wie: Jetzt

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

vor der Veröffentlichung, würde ich ersetzen möchte, dass die Werte für den Customer Knoten mit ihren zusammenpassendes Paar Schlüssel innerhalb des mappings json String.

Wie kann ich dies am besten in JavaScript/JQuery erreichen?

Gibt es eine Funktion, die etwas wie folgt ?:

jdata.replaceNode('node', mappings) 

Dank

Antwort

8

Ich hatte ein ähnliches Problem und hier funktioniert, was ich tat ...

Für jede Fremdschlüsselspalte, Ich habe 2 Werte in handsontable gespeichert; eine für die ID selbst, die ich als versteckte Spalte einstelle und die andere ist der benutzerfreundliche lesbare Textwert als Dropdown-Liste.

Jedes Mal, wenn der Wert eines Dropdowns geändert wird, ändere ich auch die entsprechende versteckte ID. In meinem Fall habe ich ein Dropdown außerhalb der Hände als Filter, die ich verwenden, um Schlüssel/Wert-Paare zuzuordnen, aber Sie könnten Hashtables oder etwas anderes verwenden.

Jetzt der Code ...

Handsontable Config:

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

Nach Änderungsereignis (genannt jedes Mal eine Änderung in der Tabelle):

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

So ändern Sie die Fremdschlüssel wie Sie und müssen nicht alles vor dem Speichern durchlaufen. Außerdem können Sie die Tabellendaten so einfach wie möglich zum Server senden.

In Zusammenfassung,

  • Der Benutzer interagiert mit CategoryName Spalte (die vom Typ ist autocomplete).
  • Die CatgoryID Spalte ist für den Benutzer durch Einstellen der Spaltenbreite auf 0 unter Verwendung der colWidths Option von Handsontable verborgen.
  • Wenn sich das Feld CategoryName ändert, verwenden Sie das Ereignis afterChange, um die entsprechende Spalte festzulegen. In meinem Fall verwende ich ein Dropdown-Feld an anderer Stelle auf der Seite, um Name => ID zuzuordnen, aber Sie können auch andere Methoden wie eine Hashtabelle verwenden.

Ich hoffe, dass es Sinn macht ...

+0

Dank @PostureOfLearning, könnten Sie folgendes klarstellen: Eine erweiterte Demo-bedingten Optionen in Ihrem Drop-Down-Verwendung finden Sie unter Wenn ich richtig der Benutzer interagiert mit dem 'CategoryName' verstehen Spalte mit dem Typ 'Autocomplete' und die externe' Dropdown/Auswahl '' #CategoriesFilterDropdown' ist für den Benutzer nicht sichtbar, sondern wird verwendet, um den Mapping-Prozess zu vereinfachen. Wie verstecken Sie die Spalte 'CategoryID'? Verwenden Sie einfach einen 'Renderer' und setzen Sie die css' Sichtbarkeit' Eigenschaft auf 'hidden'? – Chopo87

+1

@ Chopo87, siehe die Zusammenfassung, die ich hinzugefügt habe. Als mein "Mapping-Tool" benutze ich CategoriesFilterDropdown, das sichtbar ist und sich irgendwo auf der Seite befindet. Ich mache das, weil ich das Dropdown für andere Zwecke sichtbar brauchte und die Notwendigkeit nicht hatte, die Daten zu duplizieren. In Ihrem Fall möchten Sie vielleicht eine Hashtabelle verwenden, um stattdessen die IDs zu suchen. – PostureOfLearning

+0

Toll, vielen Dank @ PostureOfLearning !!! – Chopo87

0

jExcel ist eine Alternative Plugin für handsontable, die für k => v Dropdown-Listen volle Unterstützung hat. 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>