I am using DevExtreme dxGrid
to display and edit data for users, and I have a lookup column to chose the user department.
The data display in grid correctly but after I press the edit button and the popup form show up the lookup field display the id value of the department, not the value specified in DisplayExpr
, but when I click the dropdown the values displayed correctly.
I have searched a lot on the DevExpress site and tried everything they said about type mismatch between the data source and JS and nothing works.
The cshtml code:
@(Html.DevExtreme().DataGrid().ID("gridContainer")
.DataSource(d => d.WebApi().Controller("UsersApi").Key("Id").LoadAction("GetUsers").UpdateAction("Put"))
.AllowColumnReordering(true)
.AllowColumnResizing(true)
.ColumnAutoWidth(true)
.ColumnChooser(c => c.Enabled(true))
.GroupPanel(groupPanel => groupPanel.Visible(true))
.OnToolbarPreparing("OnToolbarPreparing")
.OnEditorPreparing("OnEditorPreparing")
.Editing(e =>
{
e.AllowUpdating(true);
e.Mode(GridEditMode.Popup);
})
.Columns(c =>
{
c.Add().DataField("IsActive").Caption("Active").Width("100");
c.Add().DataField("UserName").Caption("Username").Width("120").AllowEditing(false);
c.Add().DataField("FullName").Caption("Full Name").Width("200");
c.Add().DataField("Email").Width("250");
c.Add().DataField("CreatedUtc")
.Caption("Created")
.DataType(GridColumnDataType.Date)
.CellTemplate(new JS("created_CellTemplate"))
.Visible(false)
.ShowInColumnChooser(true)
.AllowEditing(false)
.Width("80");
c.Add().DataField("CreatedBy").Caption("Created By").Visible(false).ShowInColumnChooser(true).AllowEditing(false).Width("120");
c.Add().DataField("LastAccessStr")
.Caption("Latest Access")
.CellTemplate(new JS("latestAccess_CellTemplate"))
.CalculateSortValue("LastAccessUtc")
.SortOrder(SortOrder.Desc)
.AllowEditing(false)
.Width("120");
c.Add().DataField("LastLoginStr")
.Caption("Latest Login")
.CellTemplate(new JS("latestLogin_CellTemplate"))
.CalculateSortValue("LastLoginUtc")
.AllowEditing(false).Visible(false).ShowInColumnChooser(true)
.Width("120");
c.Add().DataField("LastLoginIP").Caption("Latest Login IP").AllowEditing(false).Width("150");
c.Add().DataField("PhoneNumber").Caption("Phone").Width("150").Visible(false).ShowInColumnChooser(true);
c.Add().DataField("Role").Width("200");
c.Add().DataField("DepartmentId").Caption("Department").Width(200).Lookup(
lookup => lookup
.DataSource(d => d.WebApi()
.Controller("DepartmentsApi")
.LoadAction("GetDepartment")
.Key("Id"))
.DisplayExpr("Name")
.ValueExpr("Id")
);
})
.Summary(c =>
{
c.TotalItems(cc => cc.Add().Column("UserName").SummaryType(SummaryType.Count));
})
.Paging(paging => paging.PageSize(25))
.Pager(pager =>
{
pager.ShowPageSizeSelector(true);
pager.AllowedPageSizes(new List<int> { 10, 25, 50 });
pager.ShowInfo(true);
})
.FilterRow(filterRow => filterRow
.Visible(false)
.ApplyFilter(GridApplyFilterMode.Auto)
)
.SearchPanel(searchPanel => searchPanel
.Visible(true)
.Width(240)
.Placeholder("Search...")
)
.RowAlternationEnabled(true)
.OnCellPrepared("cell_prepared")
)
<script>
function created_CellTemplate(cellElement, cellInfo) {
var tipid = cellInfo.data.Id;
var sitetextid = cellInfo.data.Id + "s";
$("<div id=" + tipid + "></div><div id=" + sitetextid + "><div>").text(cellInfo.data.ElapsedTime).appendTo(cellElement);
$("#" + tipid).dxTooltip({
target: "#" + sitetextid,
showEvent: "dxhoverstart",
hideEvent: "dxhoverend",
position: "top",
contentTemplate: function (contentElement) {
var utcDate = new Date(cellInfo.data.CreatedUtc);
contentElement.html("<b>" + convertUtcToLocal(utcDate) + "</b>");
}
});
}
function last_CellTemplate(cellElement, cellValue, cellDisplayValue, tipId, cellTextId) {
if (cellDisplayValue === 'N/A') {
$("<div id=" + tipId + "></div>").text(cellDisplayValue).appendTo(cellElement);
} else {
$("<div id=" + tipId + "></div><div id=" + cellTextId + "><div>").text(cellDisplayValue).appendTo(cellElement);
$("#" + tipId).dxTooltip({
target: "#" + cellTextId,
showEvent: "dxhoverstart",
hideEvent: "dxhoverend",
position: "top",
contentTemplate: function (contentElement) {
var utcDate = new Date(cellValue);
contentElement.html("<b>" + convertUtcToLocal(utcDate) + "</b>");
}
});
}
}
function latestAccess_CellTemplate(cellElement, cellInfo) {
var tipid = 'la_' + cellInfo.data.Id;
var sitetextid = 'la_' + cellInfo.data.Id + "s";
last_CellTemplate(cellElement, cellInfo.data.LastAccessUtc, cellInfo.data.LastAccessStr, tipid, sitetextid);
}
function latestLogin_CellTemplate(cellElement, cellInfo) {
var tipid = 'll_' + cellInfo.data.Id;
var sitetextid = 'll_' + cellInfo.data.Id + "s";
last_CellTemplate(cellElement, cellInfo.data.LastLoginUtc, cellInfo.data.LastLoginStr, tipid, sitetextid);
}
function OnToolbarPreparing(e) {
var dataGrid = e.component;
var toolbarItems = e.toolbarOptions.items;
toolbarItems.push({
widget: 'dxButton',
options: { icon: 'refresh', onClick: function () { dataGrid.refresh(); } },
location: 'after'
});
toolbarItems.push({
widget: 'dxButton',
options: {
icon: 'filter',
hint: 'Show Filters',
onClick: function (data) {
dataGrid.option('filterRow.visible', !dataGrid.option('filterRow.visible'));
}
},
location: 'after'
});
toolbarItems.push({
widget: 'dxButton',
options: {
icon: 'add',
hint: 'New User',
onClick: function (data) {
window.location.href = '/Admin/AddUser';
}
},
location: 'after'
});
}
function OnEditorPreparing(e) {
if (e.dataField === 'Role') {
e.cancel = true;
var selectBox = $('<div id="role-editor"></div>').dxSelectBox({
dataSource: "/Admin/GetAllRoles",
value: e.value,
onValueChanged: function (ev) {
e.setValue(ev.value);
}
});
e.editorElement.html(selectBox);
}
}
function cell_prepared(e) {
if (e.rowType === "data" && e.column.command === "edit") {
var isEditing = e.row.isEditing,
$links = e.cellElement.find(".dx-link");
$links.text("");
if (isEditing) {
$links.filter(".dx-link-save").addClass("dx-icon-save");
$links.filter(".dx-link-cancel").addClass("dx-icon-revert");
} else {
$links.filter(".dx-link-edit").addClass("dx-icon-edit");
$links.filter(".dx-link-delete").addClass("dx-icon-trash");
}
}
}
</script>
The problem in the departmentId
column.
The UsersApiController.cs code:
public class UsersApiController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly IUnitOfWork _unitOfWork;
public UsersApiController(UserManager<ApplicationUser> userManager, IUnitOfWork unitOfWork)
{
_userManager = userManager;
_unitOfWork = unitOfWork;
}
[HttpGet]
public async Task<IActionResult> GetUsers()
{
var users = new List<UserViewModel>();
foreach (var user in _unitOfWork.ApplicationUsers.GetAll())
{
if (user.UserName.ToLower() == "admin")
continue;
var userRoles = await _userManager.GetRolesAsync(user);
var userToAdd = new UserViewModel
{
Id = user.Id,
UserName = user.UserName,
FullName = user.FullName,
Email = user.Email,
IsActive = user.IsActive,
PhoneNumber = user.PhoneNumber,
CreatedUtc = user.CreatedUtc,
ElapsedTime = DateHelper.GetElapsedTime(user.CreatedUtc),
Role = user.Role,
LastAccessUtc = user.LastAccess,
LastAccessStr = DateHelper.GetElapsedTime(user.LastAccess),
LastLoginIP = user.LastLoginIP,
LastLoginUtc = user.LastLogin,
LastLoginStr = DateHelper.GetElapsedTime(user.LastLogin),
CreatedBy = user.CreatedByUsername,
DepartmentId=user.DepartmentId
};
users.Add(userToAdd);
}
return Ok(users);
}
The DepartmentsApiController.cs code:
public class DepartmentsApiController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly IUnitOfWork _unitOfWork;
public DepartmentsApiController(UserManager<ApplicationUser> userManager, IUnitOfWork unitOfWork)
{
_userManager = userManager;
_unitOfWork = unitOfWork;
}
[HttpGet]
public IActionResult GetDepartment()
{
var dep = _unitOfWork.DepartmentsRep.GetAll();
return Ok(dep);
}
Please note that the departmentId
is of type Guid
.
I also tried replacing the Guid
type with string
type and the problem still the same. I also tried using int
instead of Guid
in the UsersApi
and DepatementsApi
and the problem still the same. I am trying this because in DevExpress site they said this problem because of type mismatch.
I have included an image showing the problem.
First of all your sample code has some problems, your DepartmentsApiController inherits from Controller but returns Ok(), it should inherit from ApiController instead, second, your GetDepartment action returns a IActionResult, it should return a IHttpActionResult
Now after these considerations here is the answer to your question, the problem is on your GetDepartment Action, it looks like this
[HttpGet]
public IActionResult GetDepartment()
{
var dep = _unitOfWork.DepartmentsRep.GetAll();
return Ok(dep);
}
But should look like this
[HttpGet]
public HttpResponseMessage GetDepartment(DataSourceLoadOptions oadOptions)
{
var dep = _unitOfWork.DepartmentsRep.GetAll();
return Request.CreateResponse(DataSourceLoader.Load(dep, loadOptions));
}
Here you can see a DevExpress official sample code
Razor
columns.Add()
.DataField("ShipVia")
.Caption("Shipping Company")
.Lookup(lookup => lookup
.DataSource(d => d.WebApi().Controller("GridData").LoadAction("ShippersLookup").Key("Value"))
.ValueExpr("Value")
.DisplayExpr("Text")
);
API
[HttpGet]
public HttpResponseMessage ShippersLookup(DataSourceLoadOptions loadOptions)
{
var lookup = from i in _nwind.Shippers
orderby i.CompanyName
select new
{
Value = i.ShipperID,
Text = i.CompanyName
};
return Request.CreateResponse(DataSourceLoader.Load(lookup, loadOptions));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With