Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TemplateHost control #1109

Merged
merged 6 commits into from
Sep 5, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/DotVVM.Framework/Controls/TemplateHost.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotVVM.Framework.Binding;
using DotVVM.Framework.Hosting;

namespace DotVVM.Framework.Controls
{
/// <summary>
/// Renders a template supplied by a resource binding or from a runtime.
/// </summary>
[ControlMarkupOptions(AllowContent = false)]
public class TemplateHost : DotvvmControl
{

/// <summary>
/// Gets or sets the template that will be rendered inside this control.
/// </summary>
[MarkupOptions(AllowBinding = false, MappingMode = MappingMode.Attribute, Required = true)]
public ITemplate Template
{
get { return (ITemplate)GetValue(TemplateProperty); }
set { SetValue(TemplateProperty, value); }
}
public static readonly DotvvmProperty TemplateProperty
= DotvvmProperty.Register<ITemplate, TemplateHost>(c => c.Template, null);



protected internal override void OnLoad(IDotvvmRequestContext context)
{
Template.BuildContent(context, this);
tomasherceg marked this conversation as resolved.
Show resolved Hide resolved
base.OnLoad(context);
}
}
}
3 changes: 3 additions & 0 deletions src/DotVVM.Samples.Common/DotVVM.Samples.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
<None Remove="Views\ControlSamples\Repeater\IndexInNestedRepeater.dothtml" />
<None Remove="Views\ControlSamples\Repeater\NamedTemplate.dothtml" />
<None Remove="Views\ControlSamples\RouteLink\RouteLinkQueryParameters.dothtml" />
<None Remove="Views\ControlSamples\TemplateHost\Basic.dothtml" />
<None Remove="Views\ControlSamples\TemplateHost\TemplatedListControl.dotcontrol" />
<None Remove="Views\ControlSamples\TemplateHost\TemplatedMarkupControl.dotcontrol" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressQueues.dothtml" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressRedirect.dotmaster" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressRedirect1.dothtml" />
Expand Down
3 changes: 2 additions & 1 deletion src/DotVVM.Samples.Common/DotvvmStartup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,9 @@ private static void AddControls(DotvvmConfiguration config)
config.Markup.AddMarkupControl("cc", "RecursiveTextRepeater2", "Views/FeatureSamples/PostBack/RecursiveTextRepeater2.dotcontrol");
config.Markup.AddMarkupControl("cc", "ModuleControl", "Views/FeatureSamples/ViewModules/ModuleControl.dotcontrol");
config.Markup.AddMarkupControl("cc", "Incrementer", "Views/FeatureSamples/ViewModules/Incrementer.dotcontrol");
config.Markup.AddMarkupControl("cc", "TemplatedListControl", "Views/ControlSamples/TemplateHost/TemplatedListControl.dotcontrol");
config.Markup.AddMarkupControl("cc", "TemplatedMarkupControl", "Views/ControlSamples/TemplateHost/TemplatedMarkupControl.dotcontrol");
config.Markup.AddCodeControls("cc", typeof(Loader));

config.Markup.AddMarkupControl("sample", "EmbeddedResourceControls_Button", "embedded://EmbeddedResourceControls/Button.dotcontrol");

config.Markup.AutoDiscoverControls(new DefaultControlRegistrationStrategy(config, "sample", "Views/"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotVVM.Framework.ViewModel;

namespace DotVVM.Samples.Common.ViewModels.ControlSamples.TemplateHost
{
public class BasicViewModel : DotvvmViewModelBase
{

public List<IntValue> ObjectList { get; set; } = new List<IntValue>()
{
new IntValue() { Value = 1 },
new IntValue() { Value = 2 },
new IntValue() { Value = 3 }
};

public IntValue CreateObject()
{
return new IntValue() { Value = 1 };
}
}

public class IntValue
{
public int Value { get; set; }
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@viewModel DotVVM.Samples.Common.ViewModels.ControlSamples.TemplateHost.BasicViewModel, DotVVM.Samples.Common

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>

<h1>TemplateHost</h1>

<cc:TemplatedMarkupControl HeaderText="Form 1">
<ContentTemplate>
<p>hello from template</p>
</ContentTemplate>
</cc:TemplatedMarkupControl>

<cc:TemplatedListControl DataSource="{value: ObjectList}" OnCreateItem="{command: _root.CreateObject}">
<ItemTemplate>
<big>{{value: Value}}</big>
<dot:Button Text="+" Click="{staticCommand: Value = Value + 1}" />
<dot:Button Text="-" Click="{staticCommand: Value = Value - 1}" />
</ItemTemplate>
</cc:TemplatedListControl>
</body>
</html>


Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotVVM.Framework.Binding;
using DotVVM.Framework.Binding.Expressions;
using DotVVM.Framework.Controls;

namespace DotVVM.Samples.Common.Views.ControlSamples.TemplateHost
{
public class TemplatedListControl : DotvvmMarkupControl
{

[MarkupOptions(AllowHardCodedValue = false, Required = true)]
public IEnumerable DataSource
{
get { return (IEnumerable)GetValue(DataSourceProperty); }
set { SetValue(DataSourceProperty, value); }
}
public static readonly DotvvmProperty DataSourceProperty
= DotvvmProperty.Register<IEnumerable, TemplatedListControl>(c => c.DataSource, null);

[ControlPropertyBindingDataContextChange(nameof(DataSource), order: 0)]
[CollectionElementDataContextChange(order: 1)]
[MarkupOptions(AllowBinding = false, Required = true, MappingMode = MappingMode.InnerElement)]
public ITemplate ItemTemplate
{
get { return (ITemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public static readonly DotvvmProperty ItemTemplateProperty
= DotvvmProperty.Register<ITemplate, TemplatedListControl>(c => c.ItemTemplate, null);

[MarkupOptions(AllowHardCodedValue = false, Required = true)]
public ICommandBinding<object> OnCreateItem
{
get { return (ICommandBinding<object>)GetValue(OnCreateItemProperty); }
set { SetValue(OnCreateItemProperty, value); }
}
public static readonly DotvvmProperty OnCreateItemProperty
= DotvvmProperty.Register<ICommandBinding<object>, TemplatedListControl>(c => c.OnCreateItem, null);


public void AddItem()
{
var item = OnCreateItem.BindingDelegate(this.GetDataContexts().ToArray(), this);
((dynamic)DataSource).Add(((dynamic)item)());
}

public void RemoveItem(object item)
{
((dynamic)DataSource).Remove((dynamic)item);
}

}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@viewModel System.Object, mscorlib
@baseType DotVVM.Samples.Common.Views.ControlSamples.TemplateHost.TemplatedListControl, DotVVM.Samples.Common

<dot:Repeater DataSource="{value: _control.DataSource}" class="templated-list">
<ItemTemplate>
<div>
<dot:TemplateHost Template="{resource: _control.ItemTemplate}" />

<p>
<dot:LinkButton Text="Remove" Click="{command: _control.RemoveItem(_this)}" />
</p>
</div>
</ItemTemplate>
<SeparatorTemplate>
<hr />
</SeparatorTemplate>
</dot:Repeater>

<p>
<dot:Button Text="Add item" Click="{command: _control.AddItem()}" />
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotVVM.Framework.Binding;
using DotVVM.Framework.Controls;

namespace DotVVM.Samples.Common.Views.ControlSamples.TemplateHost
{
public class TemplatedMarkupControl : DotvvmMarkupControl
{

public string HeaderText
{
get { return (string)GetValue(HeaderTextProperty); }
set { SetValue(HeaderTextProperty, value); }
}
public static readonly DotvvmProperty HeaderTextProperty
= DotvvmProperty.Register<string, TemplatedMarkupControl>(c => c.HeaderText, null);

[MarkupOptions(AllowBinding = false, MappingMode = MappingMode.InnerElement, Required = true)]
public ITemplate ContentTemplate
{
get { return (ITemplate)GetValue(ContentTemplateProperty); }
set { SetValue(ContentTemplateProperty, value); }
}
public static readonly DotvvmProperty ContentTemplateProperty
= DotvvmProperty.Register<ITemplate, TemplatedMarkupControl>(c => c.ContentTemplate, null);


}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@viewModel System.Object, mscorlib
@baseType DotVVM.Samples.Common.Views.ControlSamples.TemplateHost.TemplatedMarkupControl, DotVVM.Samples.Common

<fieldset>
<legend>{{value: _control.HeaderText}}</legend>
<dot:TemplateHost Template="{resource: _control.ContentTemplate}" />
</fieldset>
54 changes: 54 additions & 0 deletions src/DotVVM.Samples.Tests/Control/TemplateHostTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotVVM.Samples.Tests.Base;
using DotVVM.Testing.Abstractions;
using Riganti.Selenium.Core;
using Xunit;
using Xunit.Abstractions;

namespace DotVVM.Samples.Tests.Control
{
public class TemplateHostTests : AppSeleniumTest
{
public TemplateHostTests(ITestOutputHelper output) : base(output)
{
}

[Fact]
public void Control_TemplateHost_Basic()
{
RunInAllBrowsers(browser => {
browser.NavigateToUrl(SamplesRouteUrls.ControlSamples_TemplateHost_Basic);

AssertUI.TextEquals(browser.Single("fieldset legend"), "Form 1");
AssertUI.TextEquals(browser.Single("fieldset p"), "hello from template");

var items = browser.FindElements(".templated-list div");
items.ThrowIfDifferentCountThan(3);

// increment item
AssertUI.TextEquals(items[0].Single("big"), "1");
items[0].ElementAt("input[type=button]", 1).Click();
AssertUI.TextEquals(items[0].Single("big"), "0");

// remove item
items[0].Single("a").Click();
browser.WaitFor(() => {
items = browser.FindElements(".templated-list div");
items.ThrowIfDifferentCountThan(2);
}, 2000);
AssertUI.TextEquals(items[0].Single("big"), "2");

// add item
browser.Last("input[type=button]").Click();
browser.WaitFor(() => {
items = browser.FindElements(".templated-list div");
items.ThrowIfDifferentCountThan(3);
}, 2000);
});
}
}
}
14 changes: 7 additions & 7 deletions src/DotVVM.Samples.Tests/DotVVM.Samples.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Riganti.Selenium.Coordinator.Client" Version="3.0.0-preview07-final" />
<PackageReference Include="Riganti.Selenium.Core" Version="3.0.0-preview07-final" />
<PackageReference Include="Riganti.Selenium.Core.Abstractions" Version="3.0.0-preview07-final" />
<PackageReference Include="Riganti.Selenium.DotVVM" Version="3.0.0-preview07-final" />
<PackageReference Include="Riganti.Selenium.AssertApi" Version="3.0.0-preview07-final" />
<PackageReference Include="Riganti.Selenium.xUnitIntegration" Version="3.0.0-preview07-final" />
<PackageReference Include="Riganti.Selenium.Validators" Version="3.0.0-preview07-final" />
<PackageReference Include="Riganti.Selenium.Coordinator.Client" Version="3.0.0-preview08-final" />
<PackageReference Include="Riganti.Selenium.Core" Version="3.0.0-preview08-final" />
<PackageReference Include="Riganti.Selenium.Core.Abstractions" Version="3.0.0-preview08-final" />
<PackageReference Include="Riganti.Selenium.DotVVM" Version="3.0.0-preview08-final" />
<PackageReference Include="Riganti.Selenium.AssertApi" Version="3.0.0-preview08-final" />
<PackageReference Include="Riganti.Selenium.xUnitIntegration" Version="3.0.0-preview08-final" />
<PackageReference Include="Riganti.Selenium.Validators" Version="3.0.0-preview08-final" />
</ItemGroup>

<ItemGroup>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.