EditForm within a table does not render - asp.net-core

Blazor vRC1
There appears to be subtleties of the EditForm component, where it will not render its contents in certain markup situations. For example, when an EditForm is placed within the <table> tags, nothing happens.
<table>
<thead>...</thead>
<EditForm Model="MyModel">
#foreach(var item in MyModel.Items)
{
<tr><td>....</td></tr>
}
</EditForm>
</table>
However wrapping the <table> with the EditForm everything renders as expected.
<EditForm Model="MyModel">
<table>
<thead>...</thead>
#foreach(var item in MyModel.Items)
{
<tr><td>....</td></tr>
}
</table>
</EditForm>
I'm fine with the latter, however if the rendering engine is unable to handle the first example, it would be nice if it'd throw some sort of error to warn the developer the situation is not supported.

Avoiding making form as a child element of a table . As a workaround , you can try add a <div> and move EditForm inside it(although it's not correct to put div nested in form ) , or you can put form inside table cell(inside <td> tag) .
<table>
<thead>...</thead>
<div>
<EditForm Model="MyModel">
#foreach(var item in MyModel.Items)
{
}
</EditForm>
</div>
</table>
Or :
<table>
<thead>...</thead>
<tr>
<td>
<EditForm Model="MyModel">
#foreach(var item in MyModel.Items)
{
}
</EditForm>
</td>
</tr>
</table>
But of course , it's better to have your table inside form .

when an EditForm is placed within the tags, nothing happens.
That is because
<table>
<EditForm Model="MyModel">
</EditForm>
</table>
translates to
<table>
<form>
</form>
</table>
Blazor outputs this alright but most browsers won't render it. It is invalid HTML.
Putting a <div> around the form , like in #NanYu's answer, is a hack but it seems to work. Putting a <form> inside a <td> is completely valid.
So: not a Blazor / Razor issue, just invalid html.
it would be nice if it'd throw some sort of error to warn the developer the situation is not supported.
Building all (for different Browsers) into the razor engine would be a lot of work and seems unnecessary.

Related

Is it possible to change view content without performing reload

I need to create view that contains table with pagination, sorting and search. I'm getting my data from backend api and then I'm passing it to the view.
My action method looks like this:
public async Task<IActionResult> Home(int page = 1)
{
var list = await _service.Get<List<Model.Rezervacija>>(page);
ViewBag.Page = page;
return View(list);
}
And I have this view:
#using eBiblioteka.Model
#model List<Rezervacija>
#{
ViewBag.Title = "Home";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="view-all">
#await Html.PartialAsync("_ViewAll", Model, null)
</div>
<a asp-action="Home" asp-route-page="#(ViewBag.Page - 1)">Previous</a>
<a asp-action="Home" asp-route-page="#(ViewBag.Page + 1)">Next</a>
And what view looks like:
And that all works. Don't pay attention for displaying pages number like this and changing with previous and next, I just wanted to simplify my question. So when i click next page, data changes and table also update very fast and that isn't problem.
But i see in tab that page is reloaded:
.
So is there any solution in asp .net core to do this without seeing that page reload. I need to call my action again to change this param "page" and then fetch new data from api without see that ugly page reload.
Thank you for all solutions.
So you want to create view that contains table with pagination, sorting and search without reloading.so you should use jquery for this.update your code like below:-
#using eBiblioteka.Model
#model IEnumerable<Rezervacija>
<div>
<table class="table table-striped border" id="myTable">
<thead>
<tr class="table-info">
<th>
#Html.DisplayNameFor(c => c.Name)
</th>
<th>
#Html.DisplayNameFor(c => c.SpecialTagId)
</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td> #item.Name </td>
<td> #item.SpecialTag.Name </td>
<td>
<partial name="_ButtonPartia3" model="#item.Id" /> //you can use partial view for delete or add data.
</td>
</tr>
}
</tbody>
</table>
</div>
<br /> <br />
#section scripts{
<script src="https://cdn.datatables.net/1.11.2/js/jquery.dataTables.min.js"></script>
<script type="text/javascript">
$(document).ready( function () {
$('#myTable').DataTable();
});
</script>
}
And Add this below link in your _Layout.cshtml:-
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.2/css/jquery.dataTables.min.css">
And your output will be like this:-
So when you will go from one page to another page, it will not reload because you used jquery. and it's already sorted and you can also search as needed.
You can use some excellent front-end frameworks. I now recommend you use layui, this is a Chinese community, of course you can also choose other ones. When this layui is paging, the URL is like the following format.
https://www.layui.com/demo/table/user/?page=2&limit=10
In this way, the .net core api can be called to perform partial refresh without reloading the entire page.

vue.js 2 nested components with inline templating results in error (component must have one child element only)

I'm trying to make components that would handle some table data for me. I figured the best approach is to create a component for each part of the table.
So, I have
Vue.component('my-table', { ... });
Vue.component('my-table-header', { ... });
Vue.component('my-table-header-column', { ... });
As I was writing the code, my HTML looked like this first:
<my-table inline-template>
<table>
<thead>
....
</thead>
<tbody>
....
</tbody>
</table>
</my-table>
This worked just fine.
Now I wrote the second component (my-table-header) and changed the HTML like so:
<my-table inline-template>
<table>
<my-table-header inline-template>
<thead>
....
</thead>
</my-table-header>
<tbody>
....
</tbody>
</table>
</my-table>
This however results in vue complaining that "Inline-template components must have exactly one child element."
I can't seem to find a good explanation on what I'm doing wrong here. It seems just by using a nested component, I create this issue.
The problem was indeed with table element being finicky ands stuff getting thrown out.
I finally managed to get this working with is="component-name" construct, like so:
<my-table inline-template>
<table>
<thead is="my-table-header" inline-template>
<thead>....</thead>
</thead>
<tbody>
....
</tbody>
</table>
</my-table>
Ask me not why I had to repeat the thead tag. It wouldn't render without it.

Razor page For loop on form to execute method in model

I have a simple Razor page and I'm trying to display a button which when clicked will execute a method in the page model code behind, similar to C#'s WPF button. I don't want to use any javascript at all.
I've gotten to a point where it kinda does what I want it to but on page load it executes the method for each element in the for each list. This is something I don't want, I just want the method to be executed on button press.
The razor page code with the for loop is as follows:
#foreach (var item in #Model.UserData)
{
<tr>
<td>#item.Owner</td>
<td>#item.InputPath</td>
<td>#item.OutputPath</td>
<td>#item.Status</td>
<td>
<form asp-action="#Model.DownloadCsv(#item.OutputPath)" method="post">
<button>Download</button>
</form>
</td>
</tr>
<tr>
<td colspan="5"> <hr /> </td>
</tr>
}
In the code behind I just have this right now:
public IActionResult DownloadCsv(string inputPath)
{
int i = 0;
return Page();
}
You could use asp-page-handler to select handler and asp-route-{attribute} to pass the parameter.And use return File() to download the file without page refreshing.
Page:
#page
...
<td>
<form method="post">
<button type="submit" asp-page-handler="DownloadCsv" asp-route-inputPath="#item.OutputPath"
class="btn btn-success">
Download
</button>
</form>
</td>
PageModel:
public ActionResult OnPostDownloadCsvAsync(string inputPath)
{
//other logic
return File("path\to\file", "application/octet-stream",
"DownloadFileName.csv");
}
Refer to
Download file to browser using .NET Core Razor Pages
Return PDF to the Browser using Asp.net core

MVC4 Html.BeginForm submit button in internet Explorer >9 not working

I have a form written in ASP.NET MVC4/Razor. The form post works perfectly well in Firefox and Chrome, but for some reason in Internet Explorer 10 and 11, the "Submit" button is unresponsive. (Internet Explorer 9 works also good).
This is how my form in the view looks like:
<div class="bla">
<table style="width:100%;">
#using (Html.BeginForm("MyAction","MyController", FormMethod.Post, new {id="myID"}))
{
<thead>
<tr>
<th class="heading highlight">Enter Registration</th>
<th>
<span style="display: block;">
#Html.EditorFor(model => model.Sign)
<input style="margin-left:4px;" type="submit" value="Save" />
</span>
<span style="display: block; font-weight: normal;">#(Model.SignDescription)</span>
</th>
</tr>
</thead>
}
</table>
</div>
And this is my Controller:
[HttpPost]
public ActionResult MyAction(InfoModel infoModel)
{
if(!string.IsNullOrEmpty(infoModel.Sign))
{
//do something
}
infoModel = LoadModel ();
return (indoModel);
}
I really have no idea why this is happening...
THanks in Advance!
EDIT:
My form is inside a table, I forgot to add it..
Your markup is invalid - form element cannot be child of table element. Rearrange your markup so #using (Html.BeginForm( will be inside <th> .
you don't need to Write 'Mycontroller' complete try writing with prefix only in form.
Also ensure that your users haven't disabled JavaScript.
I spent the last 2 days trying to work out why this didn't work on IE8, but was fine on other browsers. I even had to build a windows XP hyper-v installation, just to try and reproduce the issue!

Form validation with Struts 2 + Dojo framework

I'm new on Dojo, and I'm trying to validate a form (like the last one of this example : http://dojotoolkit.org/documentation/tutorials/1.6/validation/), using Struts2 tags, but I can't.
With a "classic" HTML form (tags , ....) everything is fine, but with Struts 2 tags (), the "required" validation don't work ...
Here is my code :
<script type="text/javascript">
dojo.require('dojox.validate');
dojo.require('dojox.validate.us');
dojo.require('dojox.validate.web');
/* basic dijit classes */
dojo.require('dijit.form.CheckBox');
dojo.require('dijit.form.Textarea');
dojo.require('dijit.form.FilteringSelect');
dojo.require('dijit.form.TextBox');
dojo.require('dijit.form.ValidationTextBox');
dojo.require('dijit.form.DateTextBox');
dojo.require('dijit.form.TimeTextBox');
dojo.require('dijit.form.Button');
dojo.require('dijit.form.RadioButton');
dojo.require('dijit.form.Form');
dojo.require('dijit.form.DateTextBox');
/* basic dojox classes */
dojo.require('dojox.form.BusyButton');
dojo.require('dojox.form.CheckedMultiSelect');
</script>
<s:form dojoType="dijit.form.Form" method="post" id="toto"
theme="simple">
<script type="dojo/method" event="onSubmit">
if(this.validate()) {
return confirm('Form is valid, press OK to submit');
} else {
alert('Formulaire invalide');
return false;
}
return true;
</script>
<table cellpadding="0" cellspacing="2">
<tr>
<td valign="top"><strong>First Name*: </strong></td>
<td>
<s:textfield
name="email"
id="email"
placeholder="Your email"
dojoType="dijit.form.ValidationTextBox"
required="true"
missingMessage="Obligatoire !" />
</td>
</tr>
</table>
<s:submit
value="Submit Form"
label="Submit Form"
id="submitButton"
dojoType="dijit.form.Button"/>
</s:form>
How can I check that my fields are not empty with struts tags please ?
Thank you all
You need to check to make sure that what you're rendering is what Dojo expects. I don't know how the current Dojo validation works, but:
The "required" attribute is an attribute of <s:textfield>, it's likely not being rendered, thus not available to Dojo--if that's what Dojo uses to determine if a field is required.