using C1.Web.Mvc;
using MultiRowExplorer.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using C1.Web.Mvc.Serialization;
namespace MultiRowExplorer.Controllers
{
public partial class MultiRowController : Controller
{
private static List<Sale> Source = Sale.GetData(10).ToList<Sale>();
public ActionResult CustomEditors()
{
ViewBag.Countries = Sale.GetCountries();
ViewBag.Products = Sale.GetProducts();
return View(Source);
}
public ActionResult MultiRowEditorsUpdate([C1JsonRequest]CollectionViewEditRequest<Sale> requestData)
{
return this.C1Json(CollectionViewHelper.Edit<Sale>(requestData, sale =>
{
string error = string.Empty;
bool success = true;
var fSale = Source.Find(item => item.ID == sale.ID);
fSale.Country = sale.Country;
fSale.Amount = sale.Amount;
fSale.Start = sale.Start;
fSale.End = sale.End;
fSale.Product = sale.Product;
fSale.Active = sale.Active;
fSale.Amount2 = sale.Amount2;
fSale.Color = sale.Color;
return new CollectionViewItemResult<Sale>
{
Error = error,
Success = success && ModelState.IsValid,
Data = fSale
};
}, () => Source));
}
public ActionResult MultiRowEditorsCreate([C1JsonRequest]CollectionViewEditRequest<Sale> requestData)
{
return this.C1Json(CollectionViewHelper.Edit(requestData, item =>
{
string error = string.Empty;
bool success = true;
try
{
Source.Add(item);
item.ID = Source.Max(u => u.ID) + 1;
}
catch (Exception e)
{
error = e.Message;
success = false;
}
return new CollectionViewItemResult<Sale>
{
Error = error,
Success = success,
Data = item
};
}, () => Source));
}
public ActionResult MultiRowEditorsDelete([C1JsonRequest]CollectionViewEditRequest<Sale> requestData)
{
return this.C1Json(CollectionViewHelper.Edit(requestData, item =>
{
string error = string.Empty;
bool success = true;
try
{
var resultItem = Source.Find(u => u.ID == item.ID);
Source.Remove(resultItem);
}
catch (Exception e)
{
error = e.Message;
success = false;
}
return new CollectionViewItemResult<Sale>
{
Error = error,
Success = success,
Data = item
};
}, () => Source));
}
}
}
@model IEnumerable<Sale>
@{
List<string> countries = ViewBag.Countries;
List<string> products = ViewBag.Products;
}
@section Scripts{
<script type="text/javascript">
c1.documentReady(function () {
var grid = wijmo.Control.getControl('#customEditorsMultiRow');
grid.hostElement.addEventListener('keydown', function (e) {
if (e.keyCode == 32) {
e.preventDefault();
}
});
});
// The following scripts are added to customize updating for the Product column.
// apply the customized updating for the Product column
function cellEditEnding(grid, cellRangeEventArgs) {
var row = cellRangeEventArgs.row, col = cellRangeEventArgs.col;
var bcol = grid.getBindingColumn(grid.cells, row, col);
// when it is the editor of the "Product" column,
// apply the updating manually.
if (!cellRangeEventArgs.cancel
&& cellRangeEventArgs.panel.cellType == wijmo.grid.CellType.Cell
&& bcol.binding == 'Product') {
updateCellValue(grid, cellRangeEventArgs);
cellRangeEventArgs.cancel = true;
}
}
function productEditorFocus(event) {
var input = event.currentTarget;
if (input) {
wijmo.setSelectionRange(input, 0, input.value.length);
}
}
function productEditorBlur(event) {
var input = event.currentTarget;
setTimeout(function () {
if (wijmo.contains(document.activeElement, input)
// ensure the input element is not removed from the page.
|| !document.body.contains(input)) {
return;
}
var wrapper = input.parentNode,
cellRange = getActiveEditorCellRange(input),
grid = wijmo.Control.getControl('#customEditorsMultiRow');
updateCellValue(grid, cellRange);
wrapper.parentNode.removeChild(wrapper);
});
}
// the id of the element would be [MultiRow's id] + "_Cell_r" + row + "_c" + col + "_"
function getActiveEditorCellRange(ele) {
var id = ele.id, strId,
row, col, index;
if (id) {
strId = id.substr('customEditorsMultiRow_Cell_r'.length);
index = strId.indexOf('_c');
row = parseInt(strId.substring(0, index));
col = parseInt(strId.substr(index + 2));
return { row: row, col: col };
}
}
// update the Product cell's value with its editor.
function updateCellValue(grid, cellRangeEventArgs) {
var row, col,
sel = grid.selection,
cv = grid.collectionView;
row = cellRangeEventArgs.row;
col = cellRangeEventArgs.col;
cv.editItem(cv.items[row]);
var input = getEditorControl(row, col);
grid.setCellData(row, col, input.value);
cv.commitEdit();
cv.commitNew();
grid.select(sel);
}
function getEditorControl(row, col) {
var elementId = 'customEditorsMultiRow_Cell_r' + row + '_c' + col;
return document.getElementById(elementId);
}
</script>
}
<script id="edtDate" type="text/template">
@(Html.C1().InputDate()
.Id("dateEditor")
.Format("d")
.IsRequired(false) // add this for new row
.CssStyle("width", "100%") // full with the cell
.TemplateBind("Value", "Start")
.ToTemplate()
)
</script>
<script id="edtTime" type="text/template">
@(Html.C1().InputTime()
.Id("timeEditor")
.Step(30)
.Format("t")
.IsRequired(false) // add this for new row
.CssStyle("width", "100%") // full with the cell
.TemplateBind("Value", "End").ToTemplate()
)
</script>
<script id="edtAmount" type="text/template">
@(Html.C1().InputNumber()
.Id("amountEditor")
.Format("c2")
.IsRequired(false) // add this for new row
.CssStyle("width", "100%") // full with the cell
.Step(10)
.TemplateBind("Value", "Amount").ToTemplate()
)
</script>
<script id="edtCountry" type="text/template">
@(Html.C1().ComboBox()
.Id("countryEditor")
.IsEditable(false)
.Bind(countries)
.CssStyle("width", "100%") // full with the cell
.TemplateBind("Text", "Country").ToTemplate()
)
</script>
<script id="edtProduct" type="text/template">
<input type="text" id="{{uid}}" onfocus="productEditorFocus(event)" onblur="productEditorBlur(event)" style="width:100%;height:100%" value="{{Product}}" />
</script>
<script id="edtColor" type="text/template">
@(Html.C1().InputColor()
.Id("colorEditor")
.CssStyle("width", "100%") // full with the cell
.TemplateBind("Text", "Color").ToTemplate()
)
</script>
<!-- MultiRow hosting the custom editors -->
@(Html.C1().MultiRow<Sale>()
.Id("customEditorsMultiRow")
.KeyActionTab(KeyAction.Cycle)
.AllowAddNew(true)
.AllowDelete(true)
.LayoutDefinition(ld =>
{
ld.Add().Cells(cells =>
{
cells.Add(cell => cell.Binding("ID").Header("ID").IsReadOnly(true));
cells.Add(cell => cell.Binding("Active").Header("Active"));
});
ld.Add().Cells(cells =>
{
cells.Add(cell => cell.Binding("Start").Header("Date").Width("150").Format("d").CellTemplate(ctb => ctb.EditTemplateId("edtDate")));
cells.Add(cell => cell.Binding("End").Header("Time").Format("t").CellTemplate(ctb => ctb.EditTemplateId("edtTime")));
});
ld.Add().Colspan(2).Cells(cells =>
{
cells.Add(cell => cell.Binding("Country").Header("Country").Colspan(2).CellTemplate(ctb => ctb.EditTemplateId("edtCountry")));
cells.Add(cell => cell.Binding("Product").Header("Product").CellTemplate(ctb => ctb.EditTemplateId("edtProduct")));
cells.Add(cell => cell.Binding("Color").Header("Color").CellTemplate(ctb => ctb.EditTemplateId("edtColor")));
});
ld.Add().Cells(cells =>
{
cells.Add(cell => cell.Binding("Amount").Header("Amount").Format("n2").CellTemplate(ctb => ctb.EditTemplateId("edtAmount")));
cells.Add(cell => cell.Binding("Amount2").Header("Amount2"));
});
})
.Bind(bl => bl.Update(Url.Action("MultiRowEditorsUpdate"))
.Create(Url.Action("MultiRowEditorsCreate"))
.Delete(Url.Action("MultiRowEditorsDelete"))
.Bind(Model))
.OnClientCellEditEnding("cellEditEnding")
.CssClass("multirow")
)
@section Description{
<p>
This sample shows how you can use custom editors to change the values in the cells of <b>MultiRow</b> control.
</p>
<p>
The sample uses the <b>EditTemplateId</b> property to specify the id of the template for cell editor.
When the user starts editing a cell, the editor will show and get the focus.
</p>
<p>
There are three kinds of editors.
</p>
<ul class="normal">
<li>
<b>Using C1 Input controls which have "Value" or "Text" property</b>
<p>
You need to set the <b>EditTemplate</b> property of a cell.
</p>
<p>
If the grid allows adding a new row, you need to set the editor's <b>IsRequired</b> to false.
If you want the editor with the whole cell, you can set the style width to "100%".
</p>
<p>
In this sample, "Date", "Time", "Country", "Amount" and "Color" use C1 Input controls as the editors.
</p>
</li>
<li>
<b>Using other control or a C1 control which has NO "Value" or "Text" property</b>
<p>
You need to use grid's <b>OnClientCellEditEnding</b> event and set
<pre>
cellEditEndingEventArgs.cancel = true;
</pre>
to apply your updates.
</p>
<p>
Then you need to consider when to update the cell value and remove the editor from a grid in your application.
For example, when the editor blurs, we need to update the cell value and remove the editor.
</p>
<p>
In this sample, the "Product" column uses <input /> as the editor.
</p>
<p>
To get the binding column in the event handler, please use the MultiRow's <b>getBindingColumn</b> function.
</p>
</li>
<li>
<b>Using grid's internal editor</b>
<p>
In this sample, "Amount2" and "Active" use grid's internal editor. Here, you do not need to do anything.
</p>
</li>
</ul>
}