【问题标题】:Kendo UI grid - programmatic update to auto-generated textboxKendo UI 网格 - 对自动生成的文本框的编程更新
【发布时间】:2014-07-17 03:22:23
【问题描述】:

我认为我的一个问题与另一个Stack Overflow question 类似,但不完全是,而且这解释起来相当复杂,所以我有很多细节,但我认为可能会直截了当回答。因为除了我的方法之外,可能还有其他方法可以做到这一点,我当然愿意接受建议。假设我在 Kendo 网格中有这个,在它呈现后看到的 HTML 标记中:

<table>
    <tr id=activeRow_1>
         <td>
            <input type=textbox data-bind=value:Status jQuery123456789="136" data-val="true" kendoBindingObject="[object Object]" />
        </td>
        <td>
        ....... // other columns in my grid, here
        </td>
        <td>
            <a class="k-button k-button-icontext k-grid-update" id=btnUpdate_1 href=#><span class="k-icon k-update"/></a>
        </td>
    </tr>
</table>

我需要找出真正的“jQuery123456789”是什么。它可以是任何数字,因为此文本框是由具有内联编辑功能的 Kendo UI 网格控件自动生成的。我会稍微解释一下为什么我认为我可能需要这个属性名称。

这就是我进入文本框的方式 - 一个从锚标记(本质上是链接按钮)上的 onclick 事件运行的函数,该标记在 Kendo 控件动态重写列以插入之前位于第一列中它的文本框。我传入该行的 ID 并获取文本框,然后为更新按钮分配一个 ID 以供以后使用:

function btnClick(id) {
    $('id="btnEdit_'+id+'"]').click(); // programmatic click to Edit button I'll hide, later, that exposes the textbox
    var activeRow = $('[id="activeRow_"'+id']'); // gridrow "TR" element
    var activeElem = activeRow.children(0).children(0); // <-- textbox node

    activeRow.childNodes[4].childNodes[0].setAttribute("id", "btnUpdate_" + id); // sets ID on Update button for later jQuery clicking
    ....
}

在上面的... 区域中,我还动态地将下拉列表添加到第一列,作为 TD 的第三个节点(第二个节点是我未显示的文本框的字段验证器)。我在下面以这种格式显示它只是为了显示目的,但在代码中它都在一行中,在 activeRow.children(0).append() 内:

'<select id=ddlStatus_'+id+' onchange=setVal(this.value)>
    <option value=1>Active</option>
    <option value=0>Inactive</option>
    <option value=2>Cancelled</option>
</select>'

然后我让它使用文本框的值并使用.val() 在下拉列表中设置选定的值。 onchange setVal() 将使用下拉列表的新值以编程方式更新文本框,然后我让它以编程方式在setVal() 函数中单击带有$('id="btnUpdate_'+id+'"]').click(); 的更新按钮。

问题是数据库没有更新。如果我注释掉程序化更新点击,点击进入文本框,点击空格键,点击关闭,然后点击更新按钮,然后它会正常工作。我尝试在setVal() 的文本框中添加.blur(),但没有骰子,并且添加诸如SendKeys 之类的东西可能不是一个选项,因为它们会仔细检查附加组件,除非直接手动输入。代码驻留在非 Internet 连接的网络上。

所以我在想,在... 区域中,我需要使用文本框的属性更新下拉列表 - 也许如果我复制文本框的属性并将它们应用于下拉列表,那么它可能会更新数据库,因为用户与它想要的控件交互。我不能将其保留为文本框,因为用户不知道要为这 3 个可能的值输入的值,如果他们输入一个字符串,它将失败,因为它需要一个数字。我真的不想对已经对用户不友好的东西进行验证。

所以,要像我认为需要的那样使用下拉菜单,我需要自动生成的文本框的属性。但是要获得那个“jQuery”属性名称,我需要对 NAME 进行部分匹配,而不是它的值,所以我可以在下拉列表中设置两者。

我试过了:

var jQAttrName = activeElem.filter(function() {
    for (var property in $(this).data()) {
        alert(property);
        if (property.indexOf('jQuery') != -1) {
            return property;
    }
});

它找到的唯一属性是“bind”,而不是“data-bind”,而且绝对没有“jQuery”。有没有人以前做过这样的程序化更新,或者匹配属性的部分名称,并获得全名,然后成功地获得程序化更新以在 Kendo 网格上工作?

用于获取文本框属性的 JSFiddle:http://jsfiddle.net/vAk52/1

更新:这可能是一个更简单的问题,我怎样才能得到这样的东西来更新数据源,然后使用远程数据/AJAX 和 MVC? 新 JSFiddle:http://jsfiddle.net/4VMJE/

【问题讨论】:

    标签: jquery kendo-ui attributes kendo-grid


    【解决方案1】:

    事实证明,我不必在文本框上获取“jQuery####”属性,甚至根本不需要使用文本框,并且可以使用具有我需要的下拉列表的 EditorTemplate 替换它.因此,在“视图”下的“共享”文件夹中,我有一个“EditorTemplates”文件夹,并在其中创建了一个名为“StatusComboBox.cs”的视图,其中包含一个 Kendo DropDown:

    @(Html.Kendo().ComboBox()
        .Name("Status")
        .DataValueField("Value")
        .DataTextField("Text")
        .BindTo((System.Collections.Ienumerable)ViewData["status"]))
    

    接下来,我们有一个名为 SimpleListItem 的模型:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace OurProject.Models
    {
        [Serializable]
        public class SimpleListItem<T>
        {
            public T Value { get; set; }
            public string Text { get; set; }
        }
    }
    

    然后,在控制器中,我们输入这些:

    private void populateData()
    {
        using (var db = new OurDatabase(false))
        {
            var statusList = new List<SimpleListItem<int>>();
            statusList.Add(new SimpleListItem<int> { Value = 0, Text = "0 - Inactive" });
            statusList.Add(new SimpleListItem<int> { Value = 1, Text = "1 - Active" });
            statusList.Add(new SimpleListItem<int> { Value = 2, Text = "2 - Cancelled" });
    
            ViewData["status"] = statusList;
            ViewBag.jsonStatus = JsonSerializer.Serialize(statusList);
        }
    }
    public class JsonSerializer
    {
        public static T Deserialize<T>(string s);
        public static string Serialize<T>(T o);
    }
    

    ...并将populateData() 放在这里,在控制器中...

    public ActionResult Index()
    {
        populateData();
        return View();
    }
    

    在视图中,我有这个专栏:

    columns.Bound(p => p.Status).Title("Active").Width(65).ClientTemplate("# if (Status == 1) {# <a href=javascript:void(0) id=btnActive_${Id} onclick=changeImg(this, '1', ${Id}) class='k-button k-button-icontext k-grid-update'><img id=imgActive src=../../Images/active_1.png /></a> #} else if (Status == 0) {# <a href=javascript:void(0) id=btnActive_${Id} onclick=changeImg(this, '0', ${Id}) class='k-button k-button-icontext k-grid-update'><img id=imgActive src=../../Images/active_0.png /></a> #} else if (Status == 2) {# <a href=javascript:void(0) id=btnActive_${Id} onclick=changeImg(this, '1', ${Id}) class='k-button k-button-icontext k-grid-update'><img id=imgActive src=../../Images/active_1.png /></a> #}#").EditorTemplateName("StatusComboBox");
    

    您会注意到此列实际上有一个链接按钮,其中包含&lt;a&gt;&lt;/a&gt;&lt;img&gt;,它是根据从数据库返回的值设置的——“1”的复选标记图像,或“ x”代表“0”或“2”。单击“按钮”通过以编程方式单击“编辑”按钮来显示下拉列表。我通过在隐藏的编辑按钮上设置一个 ID 来做到这一点:

    columns.Command(command => {command.Edit().HtmlAttributes(new { id = "btnEdit_" + "${Id}" }); }).Width(100).Hidden(true);
    

    然后在勾号/X的onclick函数中调用.click()changeImg()

    要求是 1)设置下拉列表更改时的值,以及 2) 确保没有其他字段可编辑

    这是第一列中链接按钮的onclick函数:

    function changeImg(obj, status, id) {
        var parentTr = obj.parentNode.parentNode;
        $('[id="btnEdit_'+id+'"]').click(); // Edit button clicked to expose dropdown 
        parentTr.childNodes[4].childNodes[0].setAttribute("id", "btnUpdate_"+id); // this represents 5th column, first node in the cell - and sets an ID on the button for jQuery
    
        // Get values and make them read-only - remember, columns start at 0 where linkbutton is
        parentTr.childNodes[1].childNodes[0].setAttribute('id', 'titleCtrl'+id);
        parentTr.childNodes[2].childNodes[0].setAttribute('id', 'startDateCtrl'+id);
        parentTr.childNodes[3].childNodes[0].setAttribute('id', 'endDateCtrl'+id);
        var titleCtrl = $('[id="titleCtrl"+id]');
        var titleVal = titleCtrl.val();
        titleCtrl.css('display', 'none').parent().html(titleVal);
        var startDateCtrl = $('[id="startDateCtrl"+id]');
        var startDateVal = startDateCtrl.val();
        startDateCtrl.css('display', 'none').parent().html(startDateVal);
        var endDateCtrl = $('[id="endDateCtrl"+id]');
        var endDateVal = endDateCtrl.val();
        endDateCtrl.css('display', 'none').parent().html(endDateVal);
    
        // Click the button after update
        var statusField = $('input[name="Status_input"]');
        statusField.blur(function() {
            $('[id="btnUpdate_'+id+'"]').click();  // performs update here
        }
    }
    

    请注意,“changeImg()”有点用词不当——代码不会直接将图像从复选标记翻转为 X——更新数据库并刷新网格即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-08
      • 2013-06-02
      • 2013-02-20
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多