KendoUI网格大师和细节按钮错误

时间:2015-05-27 14:28:54

标签: kendo-ui kendo-grid master-detail kendo-ui-grid

如果对主按钮和详细信息行按钮使用相同的名称,则会收到这些按钮的双击事件。我认为kendo ui使用“k-grid- {Your Button Name}”类属性来限制事件。不要在主行和明细行中使用相同的按钮名称。

name: btnName,
template: '<a class="k-button k-button-icontext k-grid-' + btnName +'" ><span class="k-icon k-i-refresh"></span></a>',
click: function (e) {

3 个答案:

答案 0 :(得分:1)

Grid将按钮与k-grid-xxx类解释为内置命令,这些命令确实应该具有唯一的名称。如果不希望这样,你可以设置不以k-grid模式开头的CSS类,并通过jQuery手动附加click处理程序。

答案 1 :(得分:0)

I create two button functions for delete operation. 

第一个函数名是“deleteButton()”,它总是返回相同名称的“删除”按钮。

第二个函数名是“deleteButton2()”,由于“prmName”参数,它可以返回不同的名称按钮。

请在确认消息中查看详细网格中两个按钮的产品名称。我们会看到不同的消息。

因为相同的名称按钮会对主要和详细信息进行两次单击事件。 你可以在调试中看到它。

因此,我们不会对细节和主网格按钮使用相同的名称。

var sampleData = [{
  ProductID: 1,
  ProductName: "Apple iPhone 5s",
  Introduced: new Date(2013, 8, 10),
  UnitPrice: 525,
  Discontinued: false,
  UnitsInStock: 10
}, {
  ProductID: 2,
  ProductName: "HTC One M8",
  Introduced: new Date(2014, 2, 25),
  UnitPrice: 425,
  Discontinued: false,
  UnitsInStock: 3
}, {
  ProductID: 3,
  ProductName: "Nokia 5880",
  Introduced: new Date(2008, 10, 2),
  UnitPrice: 275,
  Discontinued: true,
  UnitsInStock: 0
}];

function dataSource() {

  return new kendo.data.DataSource({
    transport: {
      read: function(e) {
        e.success(sampleData);
      },
      create: function(e) {
        e.data.ProductID = nextId(sampleData);
        sampleData.push(e.data);
        e.success(e.data);
      },
      update: function(e) {
        sampleData[getIndexById(sampleData, e.data.ProductID)] = e.data;
        e.success();
      },
      destroy: function(e) {
        sampleData.splice(getIndexById(sampleData, e.data.ProductID), 1);
        e.success();
      }
    },
    error: function(e) {
      alert("Status: " + e.status + "; Error message: " + e.errorThrown);
    },
    pageSize: 10,
    batch: false,
    schema: {
      model: {
        id: "ProductID",
        fields: {
          ProductID: {
            editable: false,
            nullable: true
          },
          ProductName: {
            validation: {
              required: true
            }
          },
          Introduced: {
            type: "date"
          },
          UnitPrice: {
            type: "number",
            validation: {
              required: true,
              min: 1
            }
          },
          Discontinued: {
            type: "boolean"
          },
          UnitsInStock: {
            type: "number",
            validation: {
              min: 0,
              required: true
            }
          }
        }
      }
    }
  });

};

var sampleDetailData = [{
  ProductID: 11,
  ProductName: "Detail Product 1"
}, {
  ProductID: 12,
  ProductName: "Detail Product 2"
}, {
  ProductID: 13,
  ProductName: "Detail Product 3"
}];

function detailDataSource() {

  return new kendo.data.DataSource({
    transport: {
      read: function(e) {
        e.success(sampleDetailData);
      },
      create: function(e) {
        e.data.ProductID = nextId(sampleDetailData);
        sampleDetailData.push(e.data);
        e.success(e.data);
      },
      update: function(e) {
        sampleDetailData[getIndexById(sampleDetailData, e.data.ProductID)] = e.data;
        e.success();
      },
      destroy: function(e) {
        sampleDetailData.splice(getIndexById(sampleDetailData, e.data.ProductID), 1);
        e.success();
      }
    },
    error: function(e) {
      alert("Status: " + e.status + "; Error message: " + e.errorThrown);
    },
    pageSize: 10,
    batch: false,
    schema: {
      model: {
        id: "ProductID",
        fields: {
          ProductID: {
            editable: false,
            nullable: true
          },
          ProductName: {
            validation: {
              required: true
            }
          }
        }
      }
    }
  });

};

function detailInit(e) {
  var detailRow = e.detailRow;
  detailRow.find("#detailGrid").kendoGrid({
    dataSource: detailDataSource(),
    pageable: true,
    toolbar: ["create"],
    columns: [{
      field: "ProductName",
      title: "Mobile Phone"
    }, {
      command: ["edit", deleteButton(),deleteButton2("DetailDelete")],
      title: "&nbsp;",
      width: "200px"
    }],
    editable: {
      mode: "popup",
      confirmation: false
    }
  });
};

function nextId(prmData) {
  return prmData.length + 1;
};

function getIndexById(prmData, id) {
  var idx,
    l = prmData.length;

  for (var j; j < l; j++) {
    if (prmData[j].ProductID == id) {
      return j;
    }
  }
  return null;
}

var windowTemplate = kendo.template($("#windowTemplate").html());

var dWindow = $("#window").kendoWindow({
  title: "Are you sure you want to delete this record?",
  visible: false,
  width: "400px",
  height: "200px",
}).data("kendoWindow");

var deleteButton = function() {
  return {
    name: "Delete",
    click: function(e) {
      var grid = this;
      var row = $(e.currentTarget).closest("tr");
      var data = this.dataItem(row);
      dWindow.content(windowTemplate(data));
      dWindow.open().center();

      $("#yesButton").click(function() {
        grid.removeRow(row);
        dWindow.close();
      })
      $("#noButton").click(function() {
        dWindow.close();
      })
    }
  }
};

var deleteButton2 = function(prmName) {
  return {
    name: prmName,
    click: function(e) {
      var grid = this;
      var row = $(e.currentTarget).closest("tr");
      var data = this.dataItem(row);
      dWindow.content(windowTemplate(data));
      dWindow.open().center();

      $("#yesButton").click(function() {
        grid.removeRow(row);
        dWindow.close();
      })
      $("#noButton").click(function() {
        dWindow.close();
      })
    }
  }
};

$("#grid").kendoGrid({
  dataSource: dataSource(),
  pageable: true,
  toolbar: ["create"],
  columns: [{
    field: "ProductName",
    title: "Mobile Phone"
  }, {
    field: "Introduced",
    title: "Introduced",
    format: "{0:yyyy/MM/dd}",
    width: "200px"
  }, {
    field: "UnitPrice",
    title: "Price",
    format: "{0:c}",
    width: "120px"
  }, {
    field: "UnitsInStock",
    title: "Units In Stock",
    width: "120px"
  }, {
    field: "Discontinued",
    width: "120px"
  }, {
    command: ["edit", deleteButton(),deleteButton2("MasterDelete")],
    title: "&nbsp;",
    width: "200px"
  }],
  detailTemplate: kendo.template($("#detailGridTemplate").html()),
  detailInit: detailInit,
  editable: {
    mode: "popup",
    confirmation: false
  }
});
<link href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.default.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.common.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2015.1.429/js/kendo.all.min.js"></script>
<div id="grid"></div>
<div id="window"></div>
<script type="text/x-kendo-template" id="windowTemplate">
  Delete <strong>#= ProductName #</strong> ?</p>
  <button class="k-button" id="yesButton">Yes</button>
  <button class="k-button" id="noButton">No</button>
</script>

<script type="text/x-kendo-template" id="detailGridTemplate">
  <div id="detailGrid"></div>
</script>

答案 2 :(得分:0)

我不会把这个问题称为错误。您遇到的是事件传播。您的详细删除按钮和主删除按钮共享相同的名称,并且Kendo UI使用此名称作为元素类名称(即'k-grid-Delete')的布线事件的一部分,如您所知。

当您触发子项上的单击事件(详细信息按钮)时,它会向上传播DOM树。瞧,随着事件的冒泡,它会找到一个具有相同类名的主删除按钮,因此,它的click事件也会触发。

要停止此类行为,请在删除按钮的点击事件中停止传播。

var deleteButton = function() {
  return {
    name: "Delete",
    click: function(e) {
      // insert this line - it stops the event from bubbling up the DOM tree
      e.stopPropagation();

      var grid = this;
      var row = $(e.currentTarget).closest("tr");
      var data = this.dataItem(row);
      dWindow.content(windowTemplate(data));
      dWindow.open().center();

      $("#yesButton").click(function() {
        grid.removeRow(row);
        dWindow.close();
      });
      $("#noButton").click(function() {
        dWindow.close();
      });

      console.log('deleteButton hit!');
    }
  };
};