Kendo UI网格 - 自动生成文本框的程序化更新

时间:2014-07-17 03:22:23

标签: jquery kendo-ui attributes kendo-grid

我认为我的一个问题与另一个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()将以编程方式使用下拉列表的新值更新文本框,然后以编程方式单击$('id="btnUpdate_'+id+'"]').click();函数中setVal()的更新按钮。

问题是没有发生对数据库的更新。如果我注释掉程序更新,请单击文本框,点击空格键,单击它,然后单击更新按钮,然后它将正常工作。我尝试在.blur()的文本框中添加setVal(),但没有骰子,添加像SendKeys这样的东西可能不是一个选项,因为他们仔细检查附加组件,除非直接手动输入。代码驻留在非互联网连接的网络上。

所以我认为在...区域中我需要使用文本框的属性更新下拉列表 - 也许如果我复制文本框的属性并将其应用于下拉列表,那么它可能会更新数据库,因为用户与它想要的控件交互。我不能将它作为文本框保留,因为用户不知道输入这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/

1 个答案:

答案 0 :(得分:0)

事实证明,我没有必要在文本框上获取“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");

您会注意到此列实际上有一个内部带有<a></a><img>的链接按钮,它是根据从数据库返回的值设置的 - “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)确保没有其他字段可编辑

这是第一列中linkbutton的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--更新数据库并刷新网格。