问题 Handsontable在发布之前用密钥替换自动完成值


我正在使用HandsOnTable在我的网站上使编辑数据库表更具交互性。

HandsOnTable几乎满足了我的所有要求,除了我的数据库中的某些列实际存储外键而不是本地字符串值。

在UI中,我希望这些列显示为下拉菜单,用户可以选择映射到前面提到的外键的可读值(即,类似于HTML名称/值的内容) select)。

不幸的是HandsOnTable没有这样的细胞类型。最接近它的是 autocomplete。这允许我创建一个下拉列表,但它只包含值;没有相应的钥匙。以下是它的创建方式:

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

所以我计划从服务器发送两个Json字符串:

一个包含HandsOnTable渲染表所需的参数:

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

第二个映射键到值

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

到现在为止还挺好。现在是棘手的部分:

HandsOnTable有一个功能(getData())允许我将表数据检索为准备发送回服务器的Json字符串:

var jdata = myHandsOnTable.getData();

其中jdata看起来像这样:

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

现在发布之前,我想替换为的值 Customer 节点及其匹配的对键 mappings json字符串。

我怎样才能在JavaScript / JQuery中实现这一目标?

是否有一个功能如下?:

jdata.replaceNode('node', mappings)

谢谢


9022
2017-07-24 16:18


起源



答案:


我有类似的问题,这就是我做的......

对于每个外键列,我在handontable中存储了2个值;一个用于id本身,我将其设置为隐藏列,另一个是用户友好的可读文本值作为下拉列表。

每次更改下拉列表的值时,我也会更改相应的隐藏ID。在我的情况下,我在handontable外面有一个下拉列表作为过滤器,我用它来映射键/值对,但你可以使用Hashtables或其他任何东西。

现在代码......

Handsontable配置

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

改变事件后 (每当表中有变化时调用):

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

这样,您可以像保存一样更改外键,而无需在保存之前循环显示所有外键。它还可以很容易地将表数据发送回服务器。

概要

  • 用户与之交互 CategoryName 列(属于类型 autocomplete)。
  • CatgoryID 通过使用设置列宽为0,用户可以隐藏列 colWidths 选择的方式。
  • 当。。。的时候 CategoryName 字段更改,使用 afterChange 事件设置相应的 CategoryID 柱。在我的例子中,我使用页面上其他位置的下拉列表来映射Name => ID,但是您可以使用其他方法,例如哈希表。

我希望它有意义......


8
2017-07-25 07:42



谢谢@PostureOfLearning,您能澄清以下内容:如果我理解正确,用户会与之交互 CategoryName 列的类型 autocomplete 和外部的 dropdown/select  #CategoriesFilterDropdown 对用户来说是不可见的,而是用来简化映射过程。另外,你怎么隐藏 CategoryID 柱?你刚才使用了吗? renderer 并设置它css visibility 财产 hidden? - Chopo87
@ Chopo87,看到我添加的'摘要'。作为我的“映射工具”,我使用的是CategoriesFilterDropdown,它可见并位于页面的其他位置。我这样做是因为我需要将下拉列表用于其他目的,并且不需要复制数据。在您的情况下,您可能希望使用哈希表来查找ID。 - PostureOfLearning
太好了,非常感谢@ PostureOfLearning !!! - Chopo87
不幸的是,只有在没有重复的情况下才有效 CategoryName drodpdown中的值(具有不同的ID)。在大多数情况下应该没问题,但不是全部。 - Steven de Salas
@StevendeSalas,你是对的,但为什么你会在场景背后有一个具有不同ID的多个相同显示值的下拉列表?用户不知道他们选择了哪一个。 - PostureOfLearning


答案:


我有类似的问题,这就是我做的......

对于每个外键列,我在handontable中存储了2个值;一个用于id本身,我将其设置为隐藏列,另一个是用户友好的可读文本值作为下拉列表。

每次更改下拉列表的值时,我也会更改相应的隐藏ID。在我的情况下,我在handontable外面有一个下拉列表作为过滤器,我用它来映射键/值对,但你可以使用Hashtables或其他任何东西。

现在代码......

Handsontable配置

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

改变事件后 (每当表中有变化时调用):

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

这样,您可以像保存一样更改外键,而无需在保存之前循环显示所有外键。它还可以很容易地将表数据发送回服务器。

概要

  • 用户与之交互 CategoryName 列(属于类型 autocomplete)。
  • CatgoryID 通过使用设置列宽为0,用户可以隐藏列 colWidths 选择的方式。
  • 当。。。的时候 CategoryName 字段更改,使用 afterChange 事件设置相应的 CategoryID 柱。在我的例子中,我使用页面上其他位置的下拉列表来映射Name => ID,但是您可以使用其他方法,例如哈希表。

我希望它有意义......


8
2017-07-25 07:42



谢谢@PostureOfLearning,您能澄清以下内容:如果我理解正确,用户会与之交互 CategoryName 列的类型 autocomplete 和外部的 dropdown/select  #CategoriesFilterDropdown 对用户来说是不可见的,而是用来简化映射过程。另外,你怎么隐藏 CategoryID 柱?你刚才使用了吗? renderer 并设置它css visibility 财产 hidden? - Chopo87
@ Chopo87,看到我添加的'摘要'。作为我的“映射工具”,我使用的是CategoriesFilterDropdown,它可见并位于页面的其他位置。我这样做是因为我需要将下拉列表用于其他目的,并且不需要复制数据。在您的情况下,您可能希望使用哈希表来查找ID。 - PostureOfLearning
太好了,非常感谢@ PostureOfLearning !!! - Chopo87
不幸的是,只有在没有重复的情况下才有效 CategoryName drodpdown中的值(具有不同的ID)。在大多数情况下应该没问题,但不是全部。 - Steven de Salas
@StevendeSalas,你是对的,但为什么你会在场景背后有一个具有不同ID的多个相同显示值的下拉列表?用户不知道他们选择了哪一个。 - PostureOfLearning


jExcel是handontable的另一个插件,完全支持k => v下拉列表。您可以在以下位置找到使用条形码选项的更高级演示: 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>


1
2018-03-21 16:48