RadzenTemplateForm using BlazorComponent Inside

I have a component which has a hand full of inputs and selects that is used in two different ways. One is on a page and is inline. The other is contained within a modal. The Save button is on the parent/calling page, not the component itself. They both work great as the single component.

I now want to add validation controls, these would have to go on the component (like RadzenRequiredValidator and such) but the RadzenTemplateForm would have to be outside of that (it would seem) which does not work. I tried to put RadzenTemplateForm within the component but it was never triggered when there should be an issue.

Can this be done?

It seems like the .Net 6 DynamicComponent may do the trick. I just have to wait for a few other ducks to get in a row before I can test that.

Unless there is an easier or similar way?

I am afraid I don't understand what the problem is. Please provide some minimal reproduction which we can examine.

I have what I am calling the child component:

<div class="row">
  <div class="col-lg-4">
    <div class="col-auto mb-3">
      <RadzenLabel Text="Project Name" class="d-block" />
      <RadzenTextBox Name="project-name" @bind-Value="Project.Name" MaxLength="200" Placeholder="Project Alpha" class="form-control" />
      <RadzenRequiredValidator Component="project-name" />
    </div>
  </div>
</div>
...

It has more inputs, but you get the point. Also, there is NO SAVE button in this component.

I then am using that child component in 2 different ways.

The first is on a Modal. This is the entire component.

<Modal @ref="modal" ModalTitle="New Project" Size="modal-lg">
  <ModalBody>
    <ChildComponent Project="model" />
  </ModalBody>
  <ModalFooter>
    <button type="button" class="btn btn-primary" @onclick="@(() => @Save(false))">Save</button>
    <button type="button" class="btn btn-primary" @onclick="@(() => @Save(true))">Save &amp; Add Formula</button>
    <button type="button" class="btn btn-secondary" @onclick="Close">Cancel</button>
  </ModalFooter>
</Modal>

There is a Save method on a parent page that includes this Modal and it works as expected.

The second usage of the ChildComponent is on a normal page that contains tabs as follows.

<RadzenTabs TabPosition="TabPosition.Top" SelectedIndex="SelectedTabIndex" RenderMode="TabRenderMode.Client">
  <Tabs>
    <RadzenTabsItem Text="Formulas">
      Another Tab
    </RadzenTabsItem>
    <RadzenTabsItem Text="Project Info">
      <ChildComponent Project="model" />
      <button type="button" class="btn btn-primary" @onclick="@(() => @Save(false))">Save</button>
      <button type="button" class="btn btn-primary" @onclick="@(() => @Save(true))">Save &amp; Add Formula</button>
    </RadzenTabsItem>
  </Tabs>
</RadzenTabs>

Again, this containing page has a Save method that does what it needs to do.

In both cases, the Save buttons are on the container. Because the modal needs them in the footer and the tabbed page, well does not have a footer.

What I am wanting is something like the Render Partial functionality that MVC and cshtml files. Where it just loads the cshtml inline as if it were part of the file all along.

My main goal here is to add validation. Which requires the RadzenTemplateForm. That has to be where the buttons are which in both cases are NOT on the ChildComponent, but on the containing page or component.

So the final goal would be something that looks like this, but it does not work.

<RadzenTabs TabPosition="TabPosition.Top" SelectedIndex="SelectedTabIndex" RenderMode="TabRenderMode.Client">
  <Tabs>
    <RadzenTabsItem Text="Formulas">
      Another Tab
    </RadzenTabsItem>
    <RadzenTabsItem Text="Project Info">
      <RadzenTemplateForm TModel="Thing" Data="Stuff">
        <ChildComponent Project="model" />
        <button type="button" class="btn btn-primary" @onclick="@(() => @Save(false))">Save</button>
        <button type="button" class="btn btn-primary" @onclick="@(() => @Save(true))">Save &amp; Add Formula</button>
      </RadzenTemplateForm>
    </RadzenTabsItem>
  </Tabs>
</RadzenTabs>

It seems that the TemplateForm cannot see into child components, just what is directly contained.

In .Net 6 there is a DynamicComponent that may do the trick. But I cannot test that just yet.

In order for validators to work two things should happen:

  1. They should be put inside RadzenTemplateForm
  2. The form should submit. This needs a <button> with type submit to be put inside the form itself.

Try this:

 <RadzenTemplateForm TModel="Thing" Data="Stuff">
        <ChildComponent Project="model" />
        <button type="submit" class="btn btn-primary" @onclick="@(() => @Save(false))">Save</button>
        <button type="submit" class="btn btn-primary" @onclick="@(() => @Save(true))">Save &amp; Add Formula</button>
</RadzenTemplateForm>

And handle the Submit event of the form instead of handling the click event of the buttons - they will fire unconditionally regardless of validation status. If you want to have multiple submit buttons check this thread: Multiple Submit Buttons - #4 by korchev

Thank you @korchev, this did the trick. I was not able to do it outside of a Modal, but I was able to just add the buttons within the Body of the Modal and remove the Footer.