Use HtmlHelper in Kendo Template - c#

What I'm trying to do seems pretty simple but I'm not sure if it's possible or not.
I have a Kendo Template and I am wanting to use an HtmlHelper that I created inside of it but I'm having an issue with passing the value into it.
This is what my template looks like:
<script type="text/x-kendo-tmpl" id="reviewTemplate">
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">
#:ProducerProfileDisplay#
</div>
</div>
<div class="panel-body">
#Html.Raw(Html.DisplayRating(#:Rating#))
<p>#:ReviewText#</p>
</div>
</div>
</script>
The problem with this is it just doesn't like the syntax at all and I can't compile my project. And if I decide to put it inside of quotes then it will literally just pass in the string #:Rating#.
By the way, the method I created is expecting a double.
Any ideas?

Related

Blazor WASM repeatable RenderFragment for similar EditForm properties

I am creating a large html form (using the EditForm tag) in my Blazor WASM app, containing many properties. Mostly all of which follow an identical pattern of a label, an input, and a validation section. I would like to create a render fragment that would let me cut down on my mark up. I am struggling with how to reference the "bind-Value" for the correct property.
Here is the start of the edit form, which has a model called registerModel with many properties, including string "Company" representing "Company Name"
<EditForm autocomplete="off" Model="#registerModel" OnValidSubmit="#HandleValidRegisterSubmit">
This is an example of a single section for the company name part, of which there are many in the form for all the individual properties:
<div class="row mb-3 align-items-center">
<div class="col-sm-2">
<label>
Company Name
</label>
</div>
<div class="col-sm-6 p-0">
<InputText #bind-Value="registerModel.Company" type="text" placeholder="Enter Company Name"
class="rounded-input form-control"
id="Last"
autocomplete="off"/>
</div>
<div class="col-sm-4">
<ValidationMessage For="() => registerModel.Company"/>
</div>
</div>
I want a render fragment function to automate creating each form section so I don't have to repeat so much html, and I can make my component more reusable. This is what I have tried so far
RenderFragment<(
EventCallback<string> eventCallback,
Expression<Func<string>> func,
string id,
string label,
string placeholder)> RenderFieldSection = (item) => __builder =>
{
<div class="row mb-3 align-items-center">
<div class="col-sm-2">
<label>#item.label</label>
</div>
<div class="col-sm-6 p-0">
<InputText #bind-Value="#item.eventCallback" type="text" placeholder="#item.placeholder"
class="rounded-input form-control"
id="#item.id"
autocomplete="off"/>
</div>
<div class="col-sm-4">
<ValidationMessage For="#item.func"/>
</div>
</div>
};
Which I am trying to call in the markup with:
#RenderFieldSection((
eventCallback: EventCallback.Factory.Create<string>(this, s => { registerModel.Company = s;}),
func:()=> registerModel.Company,
id: "Company",
label:Translate("CompanyNameLabel"),
placeholder:Translate("CompanyNamePlaceholder")
)
)
Everything works except the input #bind-Value="#item.eventCallback" part, which is supposed to take an EventCallback<string>. This gives the following error.
Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
I guess I am constructing the event callback wrongly, but I don't know how to do it. Any ideas? I expect I could do it by finding the property via reflection, but I (naively?) wonder if I can avoid the overhead of that.

Cannot get my bootstrap rows on the same line

I read the other questions that were similar but my issue is more basic. I'm rather new to bootstrap but I'm testing it out to see if this will work for a simple form that I need to be opened by phones, tablets, and any other device.
I'm trying to get my textbox on the same line as the text that describes it. Instead, the textbox is under the text.
Here is what is happening:
Here is the cshtml page of the above:
#model MvcBootstrap.Models.HomeModels.VisitingCustomer
#{
ViewBag.Title = "Home Page";
}
<div class="">
<p class="lead">Please enter your branch number, account number, and at least the first three characters of your last name or at least the first three characters of your company name below so we can locate your account.</p>
</div>
<div class="container">
#using (Html.BeginForm("TypeOfPayment", "Home", FormMethod.Post))
{
<div class="row">
<h2>Account Lookup</h2>
<div class=".col-md-4">
Branch Number
</div>
<div class=".col-md-8">
#Html.TextBoxFor(m => m.Branch, new {#class = "", #maxlength = "2"})
</div>
</div>
<div class="row">
<input id="submitpayment" class="typicalbutton" type="submit" value="Continue" />
</div>
}
</div>
I have no additional css code nor have I modified any of the existing css.
This should be pretty straight forward but I'm just not grasping the concept I guess. What am I doing wrong?
You could group the Branch Number and the text box in one column like so
<div class="col-md-4">
<label for="branch-number">Branch Number</label>
# add text box here and give it an id="branch-number"
</div>
Also, you don't need to have a . before the class name in your classes.
You can try this format. form-inline class makes the form inline. you don't need to use the responsive column classes. also you should use class="col-md-*" not class=".col-md-*"
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<form class="form-inline">
<div class="form-group">
<label for="branch"> Branch Number</label>
<input type="text" class="form-control" id="branch no">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
You can specify the class for different screen
i.e
col-lg-1 to col-lg-12 for large screen
col-md-1 to col-md-12 for desktop / laptop screen
col-sm-1 to col-sm-12 for tablet screen
col-xs-1 to col-xs-12 for mobile screen
Example
<input type="text" class="col-lg-6 col-md-6 col-sm-6 col-xs-12" >
What you are looking for is an inline form.
#using (Html.BeginForm("TypeOfPayment", "Home", FormMethod.Post, new { #class="form-inline" }))
{
<div class="row">
<div class="col-md-12">
<h2>Account Lookup</h2>
<div class="form-group">
#Html.LabelFor(m => m.Branch)
#Html.TextBoxFor(m => m.Branch, new {#class = "form-control", #maxlength = "2"})
</div>
<input id="submitpayment" class="typicalbutton" type="submit" value="Continue" />
</div>
</div>
}
In your model for this form you will want to add a [DisplayName] attribute for your Branch property so that you can use the Html.LabelFor() helper I included above:
[DisplayName("Branch Number")]
public string Branch { get; set; }
You will also want to read more about the grid system. Your original code did not use the proper classes for the columns.
Like #Asif Raza said, you should specify what size of screen are targeting. Keep in mind that the sizing will work for the size you specify and UP. So if you specify a medium size screen, it will affect medium size screens and larger, not smaller.
I dont think thats your issue though, I think whats happening with you is there are extra margins you are not seeing that is causing the textbox to be placed below. The max width of the container is going to be 12 columns, which you are using, but if there are any other margins in between it's going to cause the textbox to fall below. I recommend inspecting the element with F12 to zone in and see if there is anything extra being added.

How to check in razor view if field is valid?

I use bootstrap with ASP.NET Core and to indicate form field validation errors i want to add has-errors class to form-group div when given field has an error. The view looks like that:
<div class="form-group">
<label asp-for="Fragment.Content" class="col-lg-2 control-label "></label>
<div class="col-lg-10">
<textarea asp-for="Fragment.Content" class="form-control content-editor"></textarea>
<span class="help-block">A longer block of help text that breaks onto a new line and may extend beyond one line.</span>
<span asp-validation-for="Fragment.Content"></span>
</div>
</div>
I would like to do something like:
<div class="form-group" asp-add-class-if-error="has-errors" for-field="Fragment.Content"/>
I know i can write my own tag helper, however i am curious if there is a built-in solution.
I found that you can use:
#using Microsoft.AspNetCore.Mvc.ModelBinding
#if(ViewData.ModelState.GetFieldValidationState("Fragment.Content") == Microsoft.AspNetCore.Mvc.ModelBinding.ModelValidationState.Invalid)
{
// something here
}

MVC - Nested Partial Views

I am getting an error ("Server Error in '/' Application") when I nest partial views in my MVC app. The views work fine individually, but not when nested. It's my understanding that it's okay to do this, so what am I doing wrong?
Essentially, I am trying to use partials as sub-layouts within my _Layout.cshtml.
Here's my main layout - _Layout.cshtml
<!DOCTYPE html>
<html>
<head>...</head>
<body style="padding-top: 80px;">
<div class="container-fluid">
<div class="row">
<div id="myTab" class="col-lg-12 col-md-12 col-sm-12">
...
<div class="tab-content">
<div class="tab-pane fade" id="search">
#Html.Partial("~/Areas/Search/Views/Shared/_SearchLayout.cshtml")
</div>
</div>
</div>
</div>
</div>
#RenderBody()
#RenderSection("scripts", required: false)
</body>
</html>
This is the first partial view (_SearchLayout). If I remove the partials AND #RenderBody, no error.
<div class="container-fluid">
#Html.Partial("_PolicySearch")
#Html.Partial("_ClaimSearch")
</div>
#RenderBody()
This partial view is nested in the first partial view (_SearchLayout):
<div class="row top-buffer search-outline form-horizontal">
<div class="col-md-1 search-icon-size text-primary">
<i class="glyphicon glyphicon-heart"></i>
</div>
<div class="col-md-1 search-icon-size text-primary">
<h4>Claim Search</h4>
</div>
</div>
In your first partial view:
Remove RenderBody
Replace Html.Partial to Html.RenderPartial
I also would recommend to rename your partial view to something not containing the word "Layout" to avoid the mismatch between the view types.
Use Html.RenderPartial instead
The problem is #RenderBody(). This can only be called in a layout, which when used in this way _SearchLayout.cshtml is not, despite its name.
The important thing to remember about layouts, partials and views in ASP.NET MVC is that they're all views. The only thing that differentiates them is how they're used. In this instance, you're using the _SearchLayout.cshtml view as a partial, and partials can't use #RenderBody().

Nested layouts for MVC5

I've seen a few posts on this topic:
Razor Nested Layouts with Cascading Sections
MVC 3 - Nested layouts - sections don't render in Areas
And it always seems to be problematic. However they are both pretty old so wondering if things have changed.
Basically I have a master layout, and 3 different body templates based on what kind of page it is. For examples sake:
_Layout.cshtml
<html lang="en">
<head>
</head>
<body style="padding: 50px 0;">
<header class="navbar navbar-default navbar-fixed-top" role="banner">
#Html.Partial("_MenuPartial")
</header>
<ol class="breadcrumbs">
#RenderSection("breadcrumbs", true);
</ol>
<section>
#RenderBody();
</section>
<footer class="navbar navbar-default navbar-fixed-bottom">
#Html.Partial("_FooterPartial")
</footer>
#Html.Partial("_ScriptInitPartial")
</body>
</html>
_LayoutForEdit.cshtml
<div class="panel panel-primary">
<div class="panel-body">
<div class="col-lg-2">
<ul class="nav nav-pills nav-stacked">
#RenderSection("tabs", true)
</ul>
</div>
<div class="col-lg-10">
<div class="tab-content">
#RenderBody()
</div>
</div>
</div>
<div class="panel-footer">
<button class="btn btn-primary" data-bind="enable: Entity.isValid, click: save">Save</button>
</div>
</div>
Now this renders fine when called. Almost.
The rendering of sections must be in the child layout it seems. If I try to put the breadcrumbs in the _Layout.cshtml, it will fail because _LayoutForEdit.cshtml never rendered it. How can I fix this?
The following sections have been defined but have not been rendered for the layout page "~/Views/Shared/_LayoutForEdit.cshtml": "breadcrumbs".
I know it's an old question. I thought I'd share this anyway in case anyone else runs into this (like I did).
At the bottom of your child layout, you define a section with the same name as the section in the parent layout. Inside of this section you simply put a #RenderSection, again specifying the same name as before. Once this is in place, you essentially have the child layout "bypass" content from pages, up to its parent layout:
#section breadcrumbs {
#RenderSection("breadcrumbs", true)
}
Not sure if you still need help, but I'll answer anyways.
There RenderSection method takes the following parameters according to the
MSDN Documentation:
public HelperResult RenderSection(
string name,
bool required
)
Parameters
name
Type: System.String
The section to render.
required
Type: System.Boolean
true to specify that the section is required; otherwise, false.
Change the call to:
#RenderSection("breadcrumbs", false);
If the section "required" parameter is false, it will not give an error if that section is not included by a view.

Categories

Resources