In Razor, you can do something like:
#if (TempData["whatever"] != null)
{
blah blah
}
I want to check, in the if condition, the value of an input, for example:
<input id="hey" type="text" value="some text here"/>
#if ((#hey).value == "test")
{
blah blah
}
Obviously, the above doesn't work, it is just to show the intention. Is it possible?
In order to do that, you should use a Razor Helper class that create a textbox input and a model class:
Example
#Html.TextBoxFor(model => model.Name)
#if (Model.Name == "test")
{
<p>What a name.</p>
}
else
{
<p>Oh a name.</p>
}
But as devqon wrote, you should do it with JavaScript. Example :
function validateForm() {
var x = document.forms["myForm"]["fname"].value;
if (x == null || x == "") {
alert("First name must be filled out");
return false;
}
}
Link: http://www.w3schools.com/js/js_form_validation.asp
Related
For example,
sortDir field is passed to model, but if I forget it, I want to use asc as default one.
This does not work as it shows div only when sortDir==null.
<div class="wrapper"
th:if="${sortDir == null}" th:with="sortDir=${'asc'}">
// Main content
</div>
You should remove your conditional on the div and try to decide on the value with an inline expression as follows:
<div class="wrapper"
th:with="sortDir=${sortDir != null} ? sortDir : 'asc'">
// Main content
</div>
Another way to achieve this is by setting the value right in the controller before you return from the controller method. An example line might be as follows:
#GetMapping
public String getSomething(Model model) {
if (sortDir == null) { sortDir = "asc" };
model.addAttribute("sortDir", sortDir);
return "someView";
}
How do I check if a checkbox value is true when the result is either {false} for not checked and {true,false} for checked?
When I add value="yes" to the helper i get {yes,false} for checked. {Sidebar: What is so wrong with Microsoft they can't get this right?}
{Versions: netcoreapp3.1, Microsoft.EntityFrameworkCore 3.1.5, Microsoft.VisualStudio.Web.CodeGeneration.Design 3.1.3, VS Enterprise 2019 16.6.3}
View:
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="MyBoolValue" /> #Html.DisplayNameFor(model => model.MyBoolValue)
</label>
</div>
Controller: (with IFormCollection form)
if(form["MyBoolValue"].ToString() != "") // Does not work when the value is {false} not checked
{
DbTable.MyBoolValue = true;
}
else
{
DbTable.MyBoolValue = false;
}
I've tried many combinations like:
if(Convert.ToBoolean(form["MyBoolValue"]) == true)
Anyone have a simple way to get a true false condition consistently from a checkbox?
The second field is a hidden field. It will be submitted regardless whether the checkbox is checked or not. If the checkbox is checked, the posted value will be true,false. Else,the posted value will be false.It is caused by design.
If you want to check the checkbox is true or false,You can do like this:
Controller:
public IActionResult Test(IFormCollection form) {
string[] str = form["MyBoolValue"].ToArray();
//the first solution
if (str.Length > 1)
{
//MyBoolValue is true
}
else {
//MyBoolValue is false
}
//the second solution
if (str[0].Equals("true"))
{
//MyBoolValue is true
}
else
{
//MyBoolValue is false
}
return View();
}
}
I currently have a view rendering a display page for a list of Employee entities.
The values returned from the database for the Gender property are a string value of "M" or "F" for the corresponding gender. I would like to be able to show string "Male" or "Female" in the view from the corresponding property value.
I've added the following logic to the Index.cshtml which is working.
#foreach (var item in Model)
{
<tr>
//... various <td>'s
#if (item.Gender == "M")
{
<td>Male</td>
}
else if (item.Gender == "F")
{
<td>Female</td>
}
}
I'm trying to move this to a Display Template, but cant get it working.
I've added the following code to the Views\Shared\DisplayTemplates\Gender.cshtml:
#model System.String
#if (Model.Gender == "M")
{
<td>Male</td>
}
else if (Model.Gender == "F")
{
<td>Female</td>
}
What is the best way to get this working?
You can add a partial view and call it like this in main view:
#foreach (var item in Model)
{
// other tds here
#Html.Partial("_Gender",item.Gender)
}
Create Partial view with name _Gender in the View >> Shared folder:
#model String
#{
Layout = null;
}
#if (Model== "M")
{
<td>Male</td>
}
else if (Model == "F")
{
<td>Female</td>
}
// or
<td>#(Model == "M" ? "Male" : "Female") </td>
It can also handle it in main view without creating partial view.
It can handle it in main view like this:
#foreach (var item in Model)
{
<tr>
//... various <td>'s
<td>#(item.Gender == "M" ? "Male" : "Female") </td>
</tr>
}
If you want it to work with a Display Template then you need to do something like this:
#foreach (var item in Model)
{
#Html.DisplayFor(model => item.Gender)
}
and in the View Model attach the attribute:
[UIHint("Gender")]
public string Gender { get; set; }
UIHint tells MVC which Display template to use. Otherwise by convention MVC will look for one called String.chtml
Following Brad Wilson's excellent series on using and customizing editor templates, I tried adding an Object.cshtml to the Shared\EditorTemplates folder. The template renders, but the [HiddenInput(DisplayValue = false)] on a model property doesn't render a hidden <input type="hidden" ... /> as expected. Using [HiddenInput(DisplayValue = true)] renders both the hidden and visible elements as expected.
I have verified that the default template for Object works fine and renders the hidden inputs. It's only a problem when building a custom template based on Brad's series above.
Looks like something has changed. Inspecting the MVC 3 source, I found that prop.HideSurroundingHtml is used to determine when to print the surrounding HTML, not to print only the hidden element. The following template allows several levels of rendering an editor for an object graph:
#if (ViewData.TemplateInfo.TemplateDepth > 2)
{
#(ViewData.ModelMetadata.Model != null ?
ViewData.ModelMetadata.SimpleDisplayText :
ViewData.ModelMetadata.NullDisplayText)
}
else
{
foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm)))
{
if (!prop.HideSurroundingHtml)
{
if (!String.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString()))
{
<div class="editor-label">#Html.Label(prop.PropertyName)</div>
}
#Html.Raw("<div class=\"editor-field\">")
}
#Html.Editor(prop.PropertyName)
if (!prop.HideSurroundingHtml)
{
#Html.ValidationMessage(prop.PropertyName, "*")
#Html.Raw("</div>")
}
}
}
I tidied my version of that up a bit for anyone who cares:
#foreach (var modelMetadata in ViewData.ModelMetadata.Properties)
{
if (modelMetadata.HideSurroundingHtml == false)
{
if (!string.IsNullOrEmpty(Html.Label(modelMetadata.PropertyName).ToHtmlString()))
{
<div class="editor-label">
#Html.Label(modelMetadata.PropertyName)
</div>
}
<div class="editor-field">
#Html.Editor(modelMetadata.PropertyName)
</div>
}
}
I have a Page.cshtml similar to the following (that does not work):
#{
Layout = "../Shared/Layouts/_Layout.cshtml";
var mycollection = (ViewBag.TheCollection as IQueryable<MyCollectionType>);
}
<h2>#ViewBag.Title</h2>
content here
#if (mycollection != null && mycollection.Count() > 0)
{
#section ContentRight
{
<h2>
Stuff
</h2>
<ul class="stuff">
#foreach (MyCollectionType item in mycollection )
{
<li class="stuff-item">#item.Name</li>
}
</ul>
}
}
As I said, this does not work. I want to not define the section if there's nothing in the collection. Is there any way to have something like this work? If not, what are my other options? I'm very new to this Razor ViewEngine.
Edit
In my layout i have:
#if(IsSectionDefined("ContentRight"))
{
<div class="right">
RenderSection("ContentRight")
</div>
}
what i don't want is the div to output when the section is empty.
I ended up doing something a little hacky to get it working how I needed it.
on my page i have:
#{
Layout = "../Shared/Layouts/_Layout.cshtml";
var mycollection = (ViewBag.TheCollection as IQueryable<MyCollectionType>);
ViewBag.ShowContentRight = mycollection != null && mycollection.Count() > 0;
}
then in my layout i have:
#if(IsSectionDefined("ContentRight") && (ViewBag.ShowContentRight == null ||ViewBag.ShowContentRight == true))
{
<div class="right">
RenderSection("ContentRight")
</div>
}
else if(IsSectionDefined("ContentRight"))
{
RenderSection("ContentRight")
}
If the section is defined it has to be rendered, but if there's no content i dont want the <div>s
If there's a better way i'd like to know.
The renderer is expecting the method to be called sometime in the layout file. You can spoof the renderer and use "global" conditionals (think login).
#{
ViewBag.content = RenderBody();
}
#if (Request.IsAuthenticated) {
#ViewBag.content;
}
else {
#Html.Partial("_LoginPartial")
}
Extension method with private static readonly field info for perf:
private static readonly FieldInfo RenderedSectionsFieldInfo = typeof(WebPageBase).GetField("_renderedSections", BindingFlags.Instance | BindingFlags.NonPublic);
public static void EnsureSectionsAreRegisteredAsRendered(this WebPageBase webPageBase, params string[] sectionNames)
{
var renderedSections = RenderedSectionsFieldInfo.GetValue(webPageBase) as HashSet<string>;
if (renderedSections == null)
{
throw new WebCoreException("Could not get hashset from private field _renderedSections from WebPageBase");
}
foreach (var sectionName in sectionNames)
{
if (!renderedSections.Contains(sectionName))
{
renderedSections.Add(sectionName);
}
}
}
In your cshtml:
#{ this.EnsureSectionsAreRegisteredAsRendered("SectionName1", " SectionName2", "…"); }
Yes, yes, yes.... I know.... bad reflection! Use at your own risk :)
I use the following method in my view base class (from this excellent blog post http://haacked.com/archive/2011/03/05/defining-default-content-for-a-razor-layout-section.aspx/):
public HelperResult RenderSection(string name, Func<dynamic, HelperResult> defaultContents)
{
if (IsSectionDefined(name))
{
return RenderSection(name);
}
return defaultContents(null);
}
If you don't have a view base class, I recommend one because it lets you add all sorts of little extra functionality to your views. Just create a class with the following signature: public abstract class MyViewPage<T> : WebViewPage<T> and then set it in your web.config:
<system.web.webPages.razor>
<pages pageBaseType="MyViewPage">
...
</pages>
</system.web.webPages.razor>
You can wrap your whole section in an if statement with IsSectionDefined
Layout.cshtml:
#if (IsSectionDefined("ContentRight"))
{
<div>
#RenderSection(name: "ContentRight", required: false)
</div>
}
Your cshtml page:
#section ContentRight
{
#if (mycollection != null && mycollection.Count() > 0)
{
<h2>
Stuff
</h2>
<ul class="stuff">
#foreach (MyCollectionType item in mycollection )
{
<li class="stuff-item">#item.Name</li>
}
</ul>
}
}