Is there any better way as compared to #if #else Just to changes few attributes (like disabled, value, class etc) of html element in cshtml page built with Razor view?
you can use inline conditional statements as well:
<input type="text" value="#(true == true ? "one value" : "another value")" />
MVC 4/Razor V2 will have some improvements:
Conditional attribute rendering
If you have an attribute that might be null, in the past you've needed to do a null check to avoid writing out an empty attribute, like this:
<div #{if (myClass != null) { <text>class="#myClass"</text> } }>Content</div>
Now Razor is able to handle that automatically, so you can just write out the attribute. If it's null, the attribute isn't written:
<div class="#myClass">Content</div>
So if #myClass is null, the output is just this:
<div>Content</div>
From Jon Galloway's blog.
You can pass them in the ViewModel as true/false values or string values.
For example -
anything that needs to be dynamically set to be enabled or disabled - you can create a bool
any html class that is a string set on runtime, can be passed as a string variable in your view model.
etc.
That would clean up your razor views of all the #if else statements
I don't know why you think there is any performance flaw with razor #if but you can use Your ViewModel or ViewBag for this:
<input type="text" value="#(ViewBag.TheValue)" />
But for best practice, Don't mix server side logic with the presentation. "Separate of concerns"
Update(What did I mean by "separate of concerns"):
It mean the View should contains as much as it can, HTML markups and HTML helpers(which just help you write markup) only. Don't put logic inside the View. don't reuse the same view if it makes you put code inside of it.
Related
I'm migrating my site from ASP.net Framework (4.7.2) to Asp.net Core (5). One issue that I can't seem to figure out is that in my original site I had c# in a few of my HTML tags to set the css class(es). For instance:
<div class="carousel-item propertyCarousel #if (firstImage) { <text>active</text> } #if (slideNumber > 2) { <text>bonus-image</text> } " data-slide-number="#slideNumber.ToString("D2")">
Because of tag helpers, asp complains about the code. So I disabled tag helpers in the _ViewImports.cshtml and it no longer complains, but then sometimes the code just doesn't work. For instance in the above example I never get a div with the 'active' class despite verifying the conditions are correct (i.e. that 'firstImage' is true for the first image).
Since the previous commenter did not really answered the question, I'm going to go ahead and say that you need to use brackets for it to work.
This works because it's in a variable:
<div class="#htmlClass"></div>
But when you need the result of an expression from within your HTML attribute like:
<div class="#myvar == true ? "active" : string.Empty"></div>, does not work. What you should do is wrap it in brackets like this :
<div class="#(myvar == true ? "active" : string.Empty)"
This will output: <div class="active"> if the result of the expression was true.
I would like to use Bootstrap's has-success and has-failure classes with Thymeleaf.
So far I have
<div th:class="${#fields.hasErrors('field')}? 'form-group has-error' : 'form-group'"></div>
This displays the failure style correctly, when the form is posted and the field is invalid.
However if I change the second part of the ternary to 'form-group has-success', then on the initial form GET request, then, of course, it styles it as a success, even though the form hasn't been posted yet.
My question: is there a way in Thymeleaf to handle the following
Displays a form without any styling on GET.
On POST apply has-error or has-success classes.
I think you'll need to add attributes to your Model in the back-end for this.
In you GET request, change nothing. In your POST request, add an attribute: ["hasErrors", true] if the form data you send via the post is incorrect, false otherwise.
Now in your html you can add the following:
<th:block th:if="${hasErrors != null}">
<div th:class="${hasErrors ? 'form-group has-error' : 'form-group has success'"></div>
</th:block>
<th:block th:unless="${hasErrors != null}">
<div class="form-group"></div>
</th:block>
You check if the hasErrors model attribute isn't null, if it is, it means you're in the GET method and you should display a simple form-group. If the hasErrors is not null, you can create the ternary expression based on the boolean value hasErrors. The th:block is non-html. You can replace it with a div, but then you neen an extra div just to check a boolean.
I'm not going into GET/POST problem but I think that this can help you:
New th:errorclass for adding CSS class to form fields in error
Until now, whenever we wanted to apply a specific CSS class to an input field in a form when there were errors for that field, we needed to use the th:class or th:classappend attributes.
In Thymeleaf 2.1, in order to simplify this structure, a new th:errorclass attribute processor has been introduced. This processor will read the name of the field from the name or th:field attribute in the same tag, and apply the specified class if such field has errors.
Note the 'error' literal is in fact a token, so no single quotes are really needed.
The result is much more concise. Note also that th:errorclass works like th:classappend, not th:class. So the specified class will in fact be appended to any existing ones.
http://www.thymeleaf.org/whatsnew21.html#errcl
I found that Thymeleaf as a hasAnyErrors function.
<div class="form-group row"
th:attrappend="class=${#fields.hasAnyErrors()
? #fields.hasErrors('field') ? ' has-error' : ' has-success'
: '' }">
This now works.
When the user GETs the form, hasAnyErrors is false, so the empty string is appended and the input and label receive the default style.
When the user POSTs the form, if there are any errors then the first part of the ternary is evaluated. This adds the has-error or has-success styles.
This was inspired by Roel Strolenberg's answer below.
Hello everyone I'm trying to do change text color in my controller. Yes I did it but I have to send two parameter to my view. So is there any alternative way to change color in controller method ?
Here is my controller:
public action Test ()
{
ViewBag.stackoverflow = "It's gonna be red";
ViewBag.color = "red";
}
And my view:
#{
ViewBag.Title = "Test me";
}
<font color="#ViewBag.color">#ViewBag.stackoverflow</font>
I was just trying to figure out this same thing. All I did was wrap my ViewBag in view with a bootstrap class:
<div class="text-danger">
#ViewBag.Message //Message comes out red
</div>
In ASP.NET MVC, Controller and View communicate via Model that you send to view. So there is no way.
But it is good thing. MVC introduces separation of various concerns. One of many advantages is testability.
One more thing. your "color"property on ViewBag is not good idea neither. Try to describe the purpose of highlighted value like "priority" or something else and later in view you can decide the color to use for different levels of priority.
I found using the tag with the class from bootstrap helped. Very easy:
<span class="alert-success">
#Html.Raw(TempData["Message"])
</span>
I want to create in ASP.NET MVC 3 a link (in Ajax) with an image as background and no text. I'm using this method that creates an ajax link manually:
<div class="icon icon_like"></div>
The div tag calls the class "icon icon_like" of CSS that will import an image.
My question, is the following:
There is no other way (maybe a helper) to being able to do this easily?
UPDATE:
gdoron redirected me to a good link but it was not quite what I wanted (no Ajax support). For me, the first torm's answer is better, I only made some few changes to make it universal:
First in the helper it supports now a routeValues and changing the section that is to be updated
#helper AjaxImageLink(string action, Object routeValues, string icon_name, string sectionToUpdate = "#result"){
<div class="icon #icon_name"></div>
}
About the use of that helper I'm using for the example in question:
#AjaxImageLink("Like", new { controller = "Article", like = 1, id = Model.Item1.ID }, "icon_like")
And it works as it should.
To be compliant with DRY principle you can easily wrap your link structure in an inline helper like :
#helper AjaxLink(string action, string controller, string icon_name){
<div class="icon #icon_name"></div>
}
other way would be to take ajax portion to unobtrusive reusable jquery binding :
</div>
$('.ajaxLink').click(function (e) {
e.preventDefault();
$("#result").load($(this).attr("href");
});
You can see this question.
There are many others examples for it in the internet just google "asp.net mvc image action link"
use ajax.actionlink inside html.Raw and replace ajax.actionlink text with image tag.
simple one line code.
#Html.Raw(#Ajax.ActionLink("[replacetext]", "Action", "Controller", new AjaxOptions { HttpMethod="Post"}).ToHtmlString().Replace("[replacetext]", ""))
I'm looking for the equivalent of an
#if DEBUG
//view elements to show just for debug builds
#if
for views in MVC3/Razor. What's the idiomatic method for implementing this type of a setup?
That's too messy IMO. Views should be dumb, and focused on rendering HTML, not making build-based decisions.
Set properties in your view model if debug is configured, and render them out in the View.
If the properties are null (e.g non-debug), nothing will get rendered.
You can use HttpContext.Current.IsDebuggingEnabled, it checks debug value in the web.config file.
For instance:
#if(HttpContext.Current.IsDebuggingEnabled) {
//view elements to show just for debug builds
}
The other option is use write your own HttpHelper extension
public static class HtmlHelperExtensions
{
public static bool IsDebug(this HtmlHelper helper)
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
Then in your Razor code you can use it as:
#if (Html.IsDebug())
{
//view elements to show just for debug builds
}
Don't think you can do that in Razor as it doesn't compile the same way as C# code does.
So I'd say the best way to do it would be to do it in your controller and add it to a value in your model.
Edit: Here's some more info. The person here is suggesting an extension method that loads the appropriate code whether it's in debug or not: asp.mvc view enteres #IF DEBUG in release configuration
Since you haven't told us what you'd like to do, i can't give you any 'code' answers.
Preprocessor directives (#if) are a language feature C#, which you can enter by using a razor code block (#{}) and then use a explicit delimited transition (<text></text>) or an explicit line transition (#:) to conditionally add html like this:
#{
#if DEBUG
{
#:<div>Debug Mode</div>
}
#else
{
<text>
<div>
Release Mode
</div>
</text>
}
#endif
}
See Also: Preprocessor directives in Razor