<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>SlickGrid example: CompositeEditor</title> <link rel="stylesheet" href="../slick.grid.css" type="text/css"/> <link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.16.custom.css" type="text/css"/> <link rel="stylesheet" href="examples.css" type="text/css"/> <style> .cell-title { font-weight: bold; } .cell-effort-driven { text-align: center; } .item-details-form { z-index: 10000; display: inline-block; border: 1px solid black; margin: 8px; padding: 10px; background: #efefef; -moz-box-shadow: 0px 0px 15px black; -webkit-box-shadow: 0px 0px 15px black; box-shadow: 0px 0px 15px black; position: absolute; top: 10px; left: 150px; } .item-details-form-buttons { float: right; } .item-details-label { margin-left: 10px; margin-top: 20px; display: block; font-weight: bold; } .item-details-editor-container { width: 200px; height: 20px; border: 1px solid silver; background: white; display: block; margin: 10px; margin-top: 4px; padding: 0; padding-left: 4px; padding-right: 4px; } </style> </head> <body> <div style="position:relative"> <div style="width:600px;"> <div id="myGrid" style="width:100%;height:500px;"></div> </div> <div class="options-panel"> <h2>Demonstrates:</h2> <ul> <li>using a CompositeEditor to implement detached item edit form</li> </ul> <h2>Options:</h2> <button onclick="openDetails()">Open Item Edit for active row</button> <h2>View Source:</h2> <ul> <li><A href="https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example-composite-editor-item-details.html" target="_sourcewindow"> View the source for this example on Github</a></li> </ul> </div> </div> <script id="itemDetailsTemplate" type="text/x-jquery-tmpl"> <div class='item-details-form'> {{each columns}} <div class='item-details-label'> ${name} </div> <div class='item-details-editor-container' data-editorid='${id}'></div> {{/each}} <hr/> <div class='item-details-form-buttons'> <button data-action='save'>Save</button> <button data-action='cancel'>Cancel</button> </div> </div> </script> <script src="../lib/firebugx.js"></script> <script src="../lib/jquery-1.7.min.js"></script> <script src="../lib/jquery-ui-1.8.16.custom.min.js"></script> <script src="../lib/jquery.event.drag-2.2.js"></script> <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script> <script src="../slick.core.js"></script> <script src="../plugins/slick.cellrangeselector.js"></script> <script src="../plugins/slick.cellselectionmodel.js"></script> <script src="../slick.formatters.js"></script> <script src="../slick.editors.js"></script> <script src="../slick.grid.js"></script> <script src="slick.compositeeditor.js"></script> <script> function requiredFieldValidator(value) { if (value == null || value == undefined || !value.length) { return {valid: false, msg: "This is a required field"}; } else { return {valid: true, msg: null}; } } var grid; var data = []; var columns = [ {id: "title", name: "Title", field: "title", width: 120, cssClass: "cell-title", editor: Slick.Editors.Text, validator: requiredFieldValidator}, {id: "desc", name: "Description", field: "description", width: 100, editor: Slick.Editors.Text}, {id: "duration", name: "Duration", field: "duration", editor: Slick.Editors.Text}, {id: "percent", name: "% Complete", field: "percentComplete", width: 80, resizable: false, formatter: Slick.Formatters.PercentCompleteBar, editor: Slick.Editors.PercentComplete}, {id: "start", name: "Start", field: "start", minWidth: 60, editor: Slick.Editors.Date}, {id: "finish", name: "Finish", field: "finish", minWidth: 60, editor: Slick.Editors.Date}, {id: "effort-driven", name: "Effort Driven", width: 80, minWidth: 20, maxWidth: 80, cssClass: "cell-effort-driven", field: "effortDriven", formatter: Slick.Formatters.Checkmark, editor: Slick.Editors.Checkbox} ]; var options = { editable: true, enableAddRow: true, enableCellNavigation: true, asyncEditorLoading: false, autoEdit: false }; function openDetails() { if (grid.getEditorLock().isActive() && !grid.getEditorLock().commitCurrentEdit()) { return; } var $modal = $("<div class='item-details-form'></div>"); $modal = $("#itemDetailsTemplate") .tmpl({ context: grid.getDataItem(grid.getActiveCell().row), columns: columns }) .appendTo("body"); $modal.keydown(function (e) { if (e.which == $.ui.keyCode.ENTER) { grid.getEditController().commitCurrentEdit(); e.stopPropagation(); e.preventDefault(); } else if (e.which == $.ui.keyCode.ESCAPE) { grid.getEditController().cancelCurrentEdit(); e.stopPropagation(); e.preventDefault(); } }); $modal.find("[data-action=save]").click(function () { grid.getEditController().commitCurrentEdit(); }); $modal.find("[data-action=cancel]").click(function () { grid.getEditController().cancelCurrentEdit(); }); var containers = $.map(columns, function (c) { return $modal.find("[data-editorid=" + c.id + "]"); }); var compositeEditor = new Slick.CompositeEditor( columns, containers, { destroy: function () { $modal.remove(); } } ); grid.editActiveCell(compositeEditor); } $(function () { for (var i = 0; i < 500; i++) { var d = (data[i] = {}); d["title"] = "Task " + i; d["description"] = "This is a sample task description.\n It can be multiline"; d["duration"] = "5 days"; d["percentComplete"] = Math.round(Math.random() * 100); d["start"] = "01/01/2009"; d["finish"] = "01/05/2009"; d["effortDriven"] = (i % 5 == 0); } grid = new Slick.Grid("#myGrid", data, columns, options); grid.onAddNewRow.subscribe(function (e, args) { var item = args.item; var column = args.column; grid.invalidateRow(data.length); data.push(item); grid.updateRowCount(); grid.render(); }); grid.onValidationError.subscribe(function (e, args) { // handle validation errors originating from the CompositeEditor if (args.editor && (args.editor instanceof Slick.CompositeEditor)) { var err; var idx = args.validationResults.errors.length; while (idx--) { err = args.validationResults.errors[idx]; $(err.container).stop(true, true).effect("highlight", {color: "red"}); } } }); grid.setActiveCell(0, 0); }) </script> </body> </html>