255 lines
9.7 KiB
Plaintext
255 lines
9.7 KiB
Plaintext
@model Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models.TestGridModel
|
|
@using DevExtreme.AspNet.Mvc
|
|
@Html.AntiForgeryToken()
|
|
|
|
<div>
|
|
@(
|
|
Html.DevExtreme().DataGrid()
|
|
.ID("orderDataGridContainer")
|
|
.ShowBorders(true)
|
|
.DataSource(ds => ds.Mvc()
|
|
.Controller("ManagementPage")
|
|
.LoadAction("GetShippingDocuments"))
|
|
.KeyExpr("Id")
|
|
.SearchPanel(sp => sp.Visible(true))
|
|
.HeaderFilter(hf => hf.Visible(true))
|
|
.Paging(p => p.PageSize(15))
|
|
.Pager(p => p.Visible(true))
|
|
.OnRowExpanded("onRowExpanded")
|
|
.Editing(editing => {
|
|
editing.Mode(GridEditMode.Cell);
|
|
editing.AllowUpdating(true);
|
|
editing.AllowAdding(true);
|
|
editing.AllowDeleting(true);
|
|
})
|
|
.Columns(c => {
|
|
c.Add().DataField("Id").AllowEditing(false);
|
|
c.Add().DataField("PartnerId")
|
|
.AllowEditing(true)
|
|
.Lookup(lookup => lookup
|
|
.DataSource(d => d.Mvc().Controller("ManagementPage").LoadAction("GetAllPartners").Key("Id"))
|
|
.ValueExpr("Id")
|
|
.DisplayExpr("Name")
|
|
)
|
|
.EditCellTemplate(new TemplateName("DropDownBoxTemplate"))
|
|
.Width(150);
|
|
c.Add()
|
|
.Caption("Items in order")
|
|
.DataType(GridColumnDataType.Number)
|
|
.CalculateCellValue("calculateItemsCount").AllowEditing(false);
|
|
@* c.Add().DataField("PartnerId"); *@
|
|
c.Add().DataField("DocumentIdNumber");
|
|
c.Add().DataField("IsAllMeasured").AllowEditing(false);
|
|
c.Add()
|
|
.Caption("Completed")
|
|
.DataType(GridColumnDataType.Boolean)
|
|
.CalculateCellValue("calculateCellValue").AllowEditing(false);
|
|
})
|
|
.Toolbar(toolbar => {
|
|
toolbar.Items(items => {
|
|
items.Add()
|
|
.Name("addRowButton")
|
|
.ShowText(ToolbarItemShowTextMode.Always);
|
|
|
|
items.Add()
|
|
.Location(ToolbarItemLocation.After)
|
|
.Widget(w =>
|
|
w.Button()
|
|
.Text("Delete Selected Records")
|
|
.Icon("trash")
|
|
.Disabled(true)
|
|
.OnClick("onDeleteBtnClick")
|
|
);
|
|
});
|
|
})
|
|
.MasterDetail(md => md.Enabled(true).Template(new TemplateName("masterDetailTemplate"))
|
|
)
|
|
)
|
|
|
|
</div>
|
|
|
|
@using (Html.DevExtreme().NamedTemplate("masterDetailTemplate"))
|
|
{
|
|
<div class="master-detail-caption">
|
|
<%- data.ShippingDate %> <%- data.LicencePlate %>'s shipping documents:
|
|
</div>
|
|
|
|
@if (Model.ChildGrids != null && Model.ChildGrids.Any())
|
|
{
|
|
<div class="@Model.Configuration.ChildGridContainerCssClass mt-3" data-parent-id="<%- data.Id %>">
|
|
@if (Model.Configuration.ShowChildGridsAsTabs)
|
|
{
|
|
<ul class="nav nav-tabs" role="tablist">
|
|
@for (int i = 0; i < Model.ChildGrids.Count; i++)
|
|
{
|
|
var child = Model.ChildGrids[i];
|
|
var isActive = i == 0 ? "active" : "";
|
|
<li class="nav-item">
|
|
<a class="nav-link @isActive"
|
|
data-toggle="tab"
|
|
data-child-index="@i"
|
|
href="#content-@child.Id-<%- data.Id %>"
|
|
onclick="reloadChildGrid(this, '<%- data.Id %>', @i)">
|
|
@child.GridName
|
|
</a>
|
|
</li>
|
|
}
|
|
</ul>
|
|
|
|
<div class="tab-content mt-2">
|
|
@for (int i = 0; i < Model.ChildGrids.Count; i++)
|
|
{
|
|
var child = Model.ChildGrids[i];
|
|
var isActive = i == 0 ? "show active" : "";
|
|
|
|
<div class="tab-pane fade @isActive"
|
|
id="content-@child.Id-<%- data.Id %>"
|
|
data-child-index="@i">
|
|
@* Initial load - will be replaced by AJAX on first tab click *@
|
|
<div class="text-center p-3">
|
|
<span class="spinner-border spinner-border-sm" role="status"></span>
|
|
Loading...
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
}
|
|
|
|
@using(Html.DevExtreme().NamedTemplate("DropDownBoxTemplate")) {
|
|
@(Html.DevExtreme().DropDownBox()
|
|
.DataSource(d => d.Mvc().Controller("ManagementPage").LoadAction("GetAllPartners").Key("Id"))
|
|
.Value(new JS("value"))
|
|
.ValueExpr("Id")
|
|
.InputAttr("aria-label", "Partner")
|
|
.DisplayExpr("Name")
|
|
.DropDownOptions(options => options.Width(500))
|
|
.Option("setValue", new JS("setValue"))
|
|
.ContentTemplate(new TemplateName("ContentTemplate"))
|
|
)
|
|
}
|
|
|
|
@using(Html.DevExtreme().NamedTemplate("ContentTemplate")) {
|
|
@(Html.DevExtreme().DataGrid()
|
|
.DataSource(d => d.Mvc().Controller("ManagementPage").LoadAction("GetAllPartners").Key("Id"))
|
|
.RemoteOperations(true)
|
|
.Height(250)
|
|
.Columns(c => {
|
|
c.Add().DataField("Name");
|
|
c.Add().DataField("Country");
|
|
c.Add().DataField("TaxId");
|
|
})
|
|
.Scrolling(s => s.Mode(GridScrollingMode.Virtual))
|
|
.HoverStateEnabled(true)
|
|
.Selection(s => s.Mode(SelectionMode.Single))
|
|
.SelectedRowKeys(new JS("component.option('value') !== undefined && component.option('value') !== null ? [component.option('value')] : []"))
|
|
.FocusedRowEnabled(true)
|
|
.FocusedRowKey(new JS("component.option('value')"))
|
|
.OnContextMenuPreparing("function(e) { e.items = [] }")
|
|
.OnSelectionChanged("function(e) { onPartnerSelectionChanged(e, component) }")
|
|
)
|
|
}
|
|
|
|
<script>
|
|
// Store the parent grid model as JSON
|
|
var parentGridModel = @Html.Raw(Json.Serialize(Model));
|
|
|
|
// Global function to reload child grids
|
|
function reloadChildGrid(tabElement, contextId, childIndex) {
|
|
const $tab = $(tabElement);
|
|
const $contentPane = $($tab.attr('href'));
|
|
|
|
// Check if already loaded
|
|
if ($contentPane.data('loaded')) {
|
|
return;
|
|
}
|
|
|
|
// Show loading state
|
|
$contentPane.html('<div class="text-center p-3"><span class="spinner-border spinner-border-sm"></span> Loading...</div>');
|
|
|
|
// Get the child model from the parent model
|
|
var childModel = parentGridModel.ChildGrids[childIndex];
|
|
|
|
$.ajax({
|
|
url: '@Url.Action("LoadChildGrid", "ManagementPage")',
|
|
type: 'POST',
|
|
contentType: 'application/json',
|
|
headers: {
|
|
'RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val()
|
|
},
|
|
data: JSON.stringify({
|
|
contextId: contextId,
|
|
childModel: childModel
|
|
}),
|
|
success: function (data) {
|
|
$contentPane.html(data);
|
|
$contentPane.data('loaded', true);
|
|
},
|
|
error: function (xhr, status, error) {
|
|
$contentPane.html('<div class="alert alert-danger">Error loading grid: ' + error + '</div>');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Load first tab automatically when master detail opens
|
|
$(document).ready(function() {
|
|
$('#orderDataGridContainer').on('contentReady', function() {
|
|
// This will trigger when master detail rows are expanded
|
|
$('.nav-tabs .nav-link.active').each(function() {
|
|
const contextId = $(this).closest('[data-parent-id]').attr('data-parent-id');
|
|
const childIndex = $(this).data('child-index');
|
|
if (contextId && childIndex !== undefined) {
|
|
reloadChildGrid(this, contextId, childIndex);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
function calculateCellValue(rowData) {
|
|
return rowData.Status === "Completed";
|
|
}
|
|
|
|
function calculateItemsCount(rowData) {
|
|
return rowData.ShippingItems ? rowData.ShippingItems.length : 0;
|
|
}
|
|
|
|
function onDeleteBtnClick() {
|
|
let dataGrid = $("#orderDataGridContainer").dxDataGrid("instance");
|
|
$.when.apply($, dataGrid.getSelectedRowsData().map(function(data) {
|
|
return dataGrid.getDataSource().store().remove(data.Id);
|
|
})).done(function() {
|
|
dataGrid.refresh();
|
|
});
|
|
}
|
|
|
|
|
|
function onRowExpanded(e) {
|
|
// Trigger loading of first tab when row expands
|
|
const $firstTab = $(e.element).find('.master-detail-caption').next().find('.nav-link.active').first();
|
|
if ($firstTab.length) {
|
|
const contextId = e.key; // This is the actual row's Id (data.Id)
|
|
const childIndex = $firstTab.data('child-index');
|
|
if (contextId && childIndex !== undefined) {
|
|
setTimeout(() => reloadChildGrid($firstTab[0], contextId, childIndex), 100);
|
|
}
|
|
}
|
|
}
|
|
function onInitNewRow(e) {
|
|
// Replace this with actual default values and db insert
|
|
|
|
}
|
|
|
|
function onPartnerSelectionChanged(e, dropDownBoxComponent) {
|
|
var selectedRowKey = e.selectedRowKeys[0];
|
|
|
|
if (e.selectedRowKeys.length > 0) {
|
|
dropDownBoxComponent.option('value', selectedRowKey);
|
|
dropDownBoxComponent.close();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
</script> |