Reflection and thymeleaf - thymeleaf

I use spring boot and thymeleaf. I have many entity and I need to create crud ui. All ui will be similar Is it possible to use reflection to reduce ui to generate?
I would like to loop on the fields and get value in the thymeleaf template

In these days I have been working on an issue very similar to yours.
I have discovered that Thymeleaf has this thing called preprocessing which allows you to have nested expression, so something like this works:
<p th:text="${__${'myObj.myField'}__}"></p>
In this situation, the expression __${'myObj.myField'}__ is evaluated first: after this preprocessing, the expression that will be evaluated by the <p> tag will become:
<p th:text="${myObj.myField}"></p>
Which is the desidered result. Note that, in the preprocessed expression, we are passing the field as a string: therefore, it should be totally possible to create a fragments with a th:each in it which accepts a list of strings in which each string is a field. This list could either be injected directly in the model through Java or could be statically declared in the Thymeleaf's markup. An example of such fragment could be:
<div th:fragment = "show-details">
<tr th:each = "field : ${fieldsToPrint}">
<td th:text = "${__${myObj + '.' + field}__}"></td>
</tr>
</div>
Which could, for example, be used like this:
<div th:replace = "myfragments :: show-details(fieldsToPrint = ${ {'name', 'surname'} }, myObj = ${objFromModel})"></div>
The list of fields could either be generate manually or through Java reflection.
This procedure still involves some work, but way less than creating by hand all the views, especially if you can show all the entities with the same show-details fragments. I have not got around to it yet, but it should be possible to use a similar pattern also for editing such entities.

Related

How to pass data- attribute to #Html.CheckBoxFor [duplicate]

Is there a nicer syntax when creating elements with hyphenated attributes instead of using:
<%= Html.TextBox ("name", value, new Dictionary<string, object> { {"data-foo", "bar"} }) %>
Looking at the HTML specs for the proposed standards HTML 5 and WIA ARIA it seems hyphens in HTML attributes are being planned to be more common as some sort of simple name spacing.
E.g. HTML 5 proposes custom attributes are prefixed with data- and WIA ARIA uses the aria- prefix for all WIA ARIA attributes.
When using HTML helpers in ASP.NET MVC such as <%= Html.TextBox("name", value, new { attribute = attributeValue }) %> the anonymous object is converted to a dictionary.
Unfortunately in C# there is no support for hyphens in names, so the only alternative is to create a dictionary. The syntax for which is very verbose, has anyone seen a nicer alternative or a simple way of altering the functionality of ASP.NET MVC's HTML extensions without having to re-write the entire extension?
Use an underscore in the data attribute name, and it'll magically handle it for you, converting it to a hyphen. It knows you want a hyphen rather than an underscore as underscores aren't valid in html attribute names.
<%= Html.TextBox("name", value, new { #data_foo = "bar"}) %>
The answer provided at ActionLink htmlAttributes suggests using underscores instead of hyphens. MVC.Net is supposed to emit hyphens instead of the underscores when sending the page to the browser.

Razor, shortest conditional block

I frequently use code like:
<p #if(Model.Sth)
{
?:style="display: none;"
}>Some text</p>
Many template engines have special markers for conditional blocks, for example in Mustache you can write:
<p {{#Model.Sth}}style="display: none;"{{/Model.Sth}}>Some text</p>
Can my Razor code can be written in shorter form?
In Razor you can embed expressions inside parenthesis to execute them inline. If your conditional can be written using the ternary operator, then you can do something like this:
#(this.Model.Sth ? "style='display:none;'" : string.Empty)
The trick is getting Razor to emit the resulting string correctly back into your HTML. You could use HtmlHelper to do it, but it gets messy enough that the long-form conditional is much cleaner.
In the specific case of an attribute, however, there's a special feature of Razor, as of MVC4, that will help. If you specify an attribute using an expression that evaluates to null, MVC won't emit the attribute at all, so you can do:
<p style="#(this.Model.Sth ? "display:none;" : null)">Some Text</p>
(Note that null and string.Empty are different in this case: Razor will emit style="" if your expression evaluates to empty string.)

How to set variables in a thymeleaf fragment?

I understand Thymeleaf is made for rendering the views however, I just wanted to know if there is any way to set a variable may be in request scope in a Thymeleaf fragment?
I have a very large conditional expression that I have to repeat a lot of times across the application so it will be really helpful if I can set a variable in main layout then reuse it in all other child fragments.
I am aware of using a Spring interceptor and setting the variable in model but I prefer not to.
Please advise.
Thanks
Prash
In the fragment template, define fragment with parameters:
<div th:fragment=”myfragment(myvariable)”>
<p th:text=”${myvariable}”></p>
</div>
and in layout template, include fragment with that variable specified:
<div th:include=”template :: myfragment(${variable})”></div>
Then variable is passed to the fragment template.
If you need the result of your expression only in the fragments you could use
th:with="var=${verylargeexpression}"
This creates a local variable which you can use everywhere within the dom element you defined it, including fragments.
<div th:include="'path/your/file/' + ${variable}"></div>
The code above can use variables that you can choose to build the file path
If you are using Spring MVC along with Thymeleaf, then you should be able to access any bean within thymeleaf template.
Just use expressions like this in global template ...
<span th:text="${beans.myBean.verylargeexpression}"></span>

Referring to current HTML-Element in Razor?

In Razor (MVC 4) can I do something like the following (pseudo)code?
<div id="One" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
<div id="Two" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
My intention is, that in DIV "One" an additional attribute will be written, but not in DIV "Two"
So, the THIS_ID_IS(string id) should determine, if the Razor-Parse is INSIDE the given DIV with id="xyz"
Is this possible?
You can use single line if statement to overcome this situation
<div id="One" #(THIS_ID_IS("One") ? "write something" : "") ></div>
Since ids are unique values. All divs will have diffrent ids.
So I dont think there is any need for Conditional Check in razor.
You can Directly add the extra attributes to your Div as follows
<div id="One" attribute-name="Value"></div>
In situations like this I tend to write a helper method to output the markup. This way you a not constrained by the 'rules' of razor. I did a similar thing to output jQuery slider html inside a div.
It also depends on your target audience, I rarely produce the actual views as our designer does most of that. I don't like handing over stuff to the 'creatives' that requires them to write/understand the logic.
It may not be the ideal solution or maybe even overkill in your situation but may be worth a look.
http://www.asp.net/mvc/tutorials/older-versions/views/creating-custom-html-helpers-cs
As much as I would like it to be possible. It looks like it's not the case.
Based on these two articles :
Simple
In depth
It would seem that the Razor engine combines a code and a markup parser.
The main parser decides to use one or the other.
So the parsers are not aware of one another.
Simply put, in your example, <div id="One"></div> and #if(THIS_ID_IS("One")) would be parsed in different scopes and then just concatenated together.

Better way to implement an Html Helper method?

I created an html helper
Html.BreadCrumb(IDictionary<string, string> crumbs)
Where the first string is the label and the second string is the URL.
The helper creates the html required (an unordered list, some classes for first element, current element, last element, dead element and separators etc)
All working nice, but I do this by creating a stringbuilder, pumping all the html in it and returning the stringbuilder's content as a string.
I figure in this example it doesn't matter all that much, but what if an Html helper is churning out a big load of html? Isn't there a way to push it to Response.Write instead of a stringbuilder?
Or any other issues/improvements you have?
BTW we have a naming pattern in ASP.NET MVC for the various rendering techniques.
Helpers that return a string of what they are should be named what they are. For example, Url.Action() and Html.TextBox() return those exact items. Thus, these helpers should be used with the <%= %> syntax.
Helpers that render directly to the output stream should start with Render. For example, Html.RenderPartial(). These are used with the <% %> syntax.
Helpers that use the IDisposable pattern should be named with Begin/End. For example, Html.BeginForm() and Html.EndForm(). These should also be used with the <% %> syntax.
Thanks,
Eilon
It certainly is possible to use Response.Write instead of returning a string; see the source for System.Web.Mvc.Ajax.Form (in AjaxExtensions.cs) in the MVC source for an example.
You then call the helper with <% instead of <%=.
Will it be any faster? I doubt it, but it's easy to test.
I don't think you will have any performance problems as long as the size of the HTML pages you produce is reasonable. And when you really start to create pages of megabytes in size, then you should ask yourself, why are you creating such huge HTML files?

Resources