Skip to content

Commit

Permalink
AppendableDataPager added
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasherceg committed Nov 19, 2023
1 parent e26b66b commit 06afecf
Show file tree
Hide file tree
Showing 17 changed files with 448 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -811,11 +811,15 @@ JsExpression wrapInRound(JsExpression a) =>

private void AddDataSetOptionsTranslations()
{
var dataSetHelper = new JsSymbolicParameter(JavascriptTranslator.KnockoutContextParameter).Member("$gridViewDataSetHelper");
// GridViewDataSetBindingProvider
AddMethodTranslator(() => GridViewDataSetBindingProvider.DataSetClientSideLoad(null!), new GenericMethodCompiler(args =>
new JsIdentifierExpression("dotvvm").Member("dataSet").Member("loadDataSet").Invoke(args[1].WithAnnotation(ShouldBeObservableAnnotation.Instance), dataSetHelper.Clone().Member("loadDataSet")).WithAnnotation(new ResultIsPromiseAnnotation(e => e))));

var dataSetHelper = new JsSymbolicParameter(JavascriptTranslator.KnockoutContextParameter).Member("$gridViewDataSetHelper");
AddMethodTranslator(typeof(GridViewDataSetBindingProvider), nameof(GridViewDataSetBindingProvider.DataSetClientSideLoad), new GenericMethodCompiler(args =>
new JsIdentifierExpression("dotvvm").Member("dataSet").Member("loadDataSet").Invoke(
args[1].WithAnnotation(ShouldBeObservableAnnotation.Instance),
args[2],
dataSetHelper.Clone().Member("loadDataSet"),
dataSetHelper.Clone().Member("postProcessor")
).WithAnnotation(new ResultIsPromiseAnnotation(e => e))));
AddMethodTranslator(() => GridViewDataSetBindingProvider.GetCurrentGridDataSet<Generic.DataSet>(), new GenericMethodCompiler(args =>
dataSetHelper.Clone().Member("dataSet")
));
Expand Down
110 changes: 110 additions & 0 deletions src/Framework/Framework/Controls/AppendableDataPager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Text;
using DotVVM.Framework.Binding;
using DotVVM.Framework.Binding.Expressions;
using DotVVM.Framework.Binding.HelperNamespace;
using DotVVM.Framework.Compilation.Javascript;
using DotVVM.Framework.Hosting;

namespace DotVVM.Framework.Controls
{
/// <summary>
/// Renders a pager for <see cref="GridViewDataSet{T}"/> that allows the user to append more items to the end of the list.
/// </summary>
[ControlMarkupOptions(AllowContent = false, DefaultContentProperty = nameof(LoadTemplate))]
public class AppendableDataPager : HtmlGenericControl
{
private readonly GridViewDataSetBindingProvider gridViewDataSetBindingProvider;

[MarkupOptions(AllowBinding = false, MappingMode = MappingMode.InnerElement)]
[DataPagerApi.AddParameterDataContextChange("_dataPager")]
public ITemplate? LoadTemplate
{
get { return (ITemplate?)GetValue(LoadTemplateProperty); }
set { SetValue(LoadTemplateProperty, value); }
}
public static readonly DotvvmProperty LoadTemplateProperty
= DotvvmProperty.Register<ITemplate, AppendableDataPager>(c => c.LoadTemplate, null);

[MarkupOptions(AllowBinding = false, MappingMode = MappingMode.InnerElement)]
public ITemplate? EndTemplate
{
get { return (ITemplate?)GetValue(EndTemplateProperty); }
set { SetValue(EndTemplateProperty, value); }
}
public static readonly DotvvmProperty EndTemplateProperty
= DotvvmProperty.Register<ITemplate, AppendableDataPager>(c => c.EndTemplate, null);

[MarkupOptions(Required = true, AllowHardCodedValue = false)]
public IPageableGridViewDataSet DataSet
{
get { return (IPageableGridViewDataSet)GetValue(DataSetProperty)!; }
set { SetValue(DataSetProperty, value); }
}
public static readonly DotvvmProperty DataSetProperty
= DotvvmProperty.Register<IPageableGridViewDataSet, AppendableDataPager>(c => c.DataSet, null);

public ICommandBinding? LoadData
{
get => (ICommandBinding?)GetValue(LoadDataProperty);
set => SetValue(LoadDataProperty, value);
}
public static readonly DotvvmProperty LoadDataProperty =
DotvvmProperty.Register<ICommandBinding?, AppendableDataPager>(nameof(LoadData));


private DataPagerBindings? dataPagerCommands = null;


public AppendableDataPager(GridViewDataSetBindingProvider gridViewDataSetBindingProvider) : base("div")
{
this.gridViewDataSetBindingProvider = gridViewDataSetBindingProvider;
}

protected internal override void OnLoad(IDotvvmRequestContext context)
{
var dataSetBinding = GetValueBinding(DataSetProperty)!;
var commandType = LoadData is { } ? GridViewDataSetCommandType.LoadDataDelegate : GridViewDataSetCommandType.Default;
dataPagerCommands = gridViewDataSetBindingProvider.GetDataPagerCommands(this.GetDataContextType()!, dataSetBinding, commandType);

if (LoadTemplate != null)
{
LoadTemplate.BuildContent(context, this);
}

if (EndTemplate != null)
{
var container = new HtmlGenericControl("div")
.SetProperty(p => p.Visible, dataPagerCommands.IsLastPage);
Children.Add(container);

EndTemplate.BuildContent(context, container);
}
}

protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
{
var dataSetBinding = GetDataSetBinding().GetKnockoutBindingExpression(this, unwrapped: true);

var helperBinding = new KnockoutBindingGroup();
helperBinding.Add("dataSet", dataSetBinding);
if (this.LoadData is { } loadData)
{
helperBinding.Add("loadDataSet", KnockoutHelper.GenerateClientPostbackLambda("LoadDataCore", loadData, this, new PostbackScriptOptions(elementAccessor: "$element", koContext: CodeParameterAssignment.FromIdentifier("$context"))));
helperBinding.Add("loadNextPage", KnockoutHelper.GenerateClientPostbackLambda("LoadData", dataPagerCommands!.GoToNextPage!, this));
helperBinding.Add("postProcessor", "dotvvm.dataSet.postProcessors.append");
}
writer.AddKnockoutDataBind("dotvvm-gridviewdataset", helperBinding.ToString());

var binding = new KnockoutBindingGroup();
binding.Add("autoLoadWhenInViewport", LoadTemplate == null ? "true" : "false");
writer.AddKnockoutDataBind("dotvvm-appendable-data-pager", binding);

base.AddAttributesToRender(writer, context);
}

private IValueBinding GetDataSetBinding()
=> GetValueBinding(DataSetProperty) ?? throw new DotvvmControlException(this, "The DataSet property of the dot:DataPager control must be set!");
}
}
3 changes: 2 additions & 1 deletion src/Framework/Framework/Controls/DataPager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ protected virtual void DataBind(Hosting.IDotvvmRequestContext context)
var dataSetBinding = GetValueBinding(DataSetProperty)!;
var dataSetType = dataSetBinding.ResultType;

var commandType = LoadData is {} ? GridViewDataSetCommandType.StaticCommand : GridViewDataSetCommandType.Command;
var commandType = LoadData is {} ? GridViewDataSetCommandType.LoadDataDelegate : GridViewDataSetCommandType.Default;

pagerBindings = gridViewDataSetBindingProvider.GetDataPagerCommands(this.GetDataContextType().NotNull(), dataSetBinding, commandType);

var enabled = GetValueOrBinding<bool>(EnabledProperty)!;
Expand Down
2 changes: 1 addition & 1 deletion src/Framework/Framework/Controls/GridView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ protected virtual ICommandBinding BuildDefaultSortCommandBinding()
protected virtual ICommandBinding? BuildLoadDataSortCommandBinding()
{
var dataContextStack = this.GetDataContextType()!;
var commandType = LoadData is { } ? GridViewDataSetCommandType.StaticCommand : GridViewDataSetCommandType.Command;
var commandType = LoadData is { } ? GridViewDataSetCommandType.LoadDataDelegate : GridViewDataSetCommandType.Default;
return gridViewDataSetBindingProvider.GetGridViewCommands(dataContextStack, GetDataSourceBinding(), commandType).SetSortExpression;
}

Expand Down
Loading

0 comments on commit 06afecf

Please sign in to comment.