asp.net mvc razor multiply two item and convert to string - asp.net-mvc

When I write #(line.Quantity * line.Product.Price).ToString("c") the result is
39,00.ToString("c")
and #line.Quantity * line.Product.Price.ToString("c") result is
2 * line.Product.Price.ToString("c")
How can i multiply two values and convert it to string in a razor view?

try
#((line.Quantity * line.Product.Price).ToString("c"))
The problem is that razor do not know when the output string ends since # is used to display code in HTML. Spaces switches razor back to HTML mode.
Wrapping everything into parenthesis makes razor evaluate the entire code block.
Although the most proper way would be to introduce a new property in your model:
public class MyModel
{
public double Total { get { return Quantity * Product.Price; }}
//all other code here
}
and simply use:
#line.Total.ToString("c")

this is an old question but I have just had the same issue and here is the resolution for it.
If you need to perform a calculation on a razor view, you can do it the following way:
if you are outside of c# block (such as #foreach or #if ):
you can wrap your calculation into #{ } and they won't be rendered.
<p>Some text</p>
#{ var x = Model.Y * Model.Z; }
<p>X equals #x.ToString()</p>
if you are inside of a c# block:
you can simply put your calculations in { }.
<p>Some text</p>
#foreach (var x in Model.Y)
{
{ var z = x * 2; }
<p>Z equals #z.ToString()</p>
}

Related

Svelte: How to bind a formatted input field to a property

First of all: Svelte is still new to me. I hope the question is not too trivial.
Within a simple component I want to use the content of a formatted input field for a calculation.
For example:
In the input field a Euro amount should be displayed formatted (1.000).
Next to it a text with the amount plus VAT should be displayed (1.190).
How I do this without formatting is clear to me. The example looks like this:
export let net;
export let vat;
$: gross = net + (net * vat / 100);
$: grossPretty = gross.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
with a simple markup like this:
<form>
<label>Net amount</label>
<input type="text" step="any" bind:value={net} placeholder="Net amount">
</form>
<div>
Gros = {grossPretty} €
</div>
In vue i used a computed property. Its getter delivers the formatted string and its setter takes the formatted string and saves the raw value.
(In data() I define net, in the computed properties i define netInput. The input field uses netInput as v-model).
It looks like this:
netInput: {
get(){
return this.net.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
},
set(s){
s = s.replace(/[\D\s._-]+/g, "");
this.net = Number(s);
}
}
How can I handle it in svelte?
You can do something somewhat similar, you create another computed variable that stores the deformatted string from the input field and is used in the calculation instead of the direct input
export let net;
export let vat;
$: net_plain = Number(net.replace(/[\D\s._-]+/g, ""));
$: gross = net_plain + (net_plain * vat / 100);
$: grossPretty = gross.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
But maybe find a better name for the variable :)
Thanks to Stephane Vanraes I found a solution.
It has not the charm of the vue approach but it's ok. First I inserted 'net_plain'. To have the input field formatted during input, I added an event listener for the keyup event.
<input type="text" step="any" bind:value={net} on:keyup={handleKeyUp} placeholder="Net amount">
The event is handled from the function handleKeyUp as follows:
function handleKeyUp(event){
if ( window.getSelection().toString() !== '' ) {
return;
}
// ignore arrow keys
let arrows = [38,40,37,39];
if ( arrows.includes( event.keyCode)) {
return;
}
let input = event.target.value.replace(/[\D\s._-]+/g, "");
input = input ? parseInt( input, 10 ) : 0;
event.target.value = ( input === 0 ) ? "" : input.toLocaleString( "de-DE" );
}
BUT: If anyone has a solution using getter and setter I would appreciate the anwer!

#: in a foreach loop doesn't work when it's between tags?

I know that #: is for output a single line of content containing plain text or unmatched HTML tags;
If so , why do I get an error for :
( ":" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{" are valid.)
#foreach (int line in new int[] { 0, 1 })
{
<span>
#: aaaaa
</span>
}
While this run as expected :
#foreach (int line in new int[] { 0, 1 })
{
#: aaaaa
}
#: is used to mix text within a code block.
When you use the span tag or any other html elements, inside a C# code block, you are already mixing HTML tag and razor can properly parse and execute it. When you use #: inside an HTML element (non-code block), it is not even valid.
In short, you can use HTML elements inside a code block as wrapper to mix plaintext/html.
#foreach (int line in new int[] { 0, 1 })
{
<div>Hello</div>
}
In razor, the #: tag produce the same result as the text tag when it comes to mixing plain text within a code block. The below will also produce same result as your second code block.
#foreach (int line in new int[] { 0, 1 })
{
<text>aaa533</text>
}

Insert img tag in nested for loop in razor view

I am trying to add variable quantity images within nested for loop in asp.net mvc razor view page. My code-
foreach (var row in ViewBag.BrandPromoters.Rows)
{
string stars = "";
for (int i = 0; i < counter; i++)
{
stars += "<img src='#(ViewBag.BaseUrl)/star.png' />";
}
<div>#stars</div>
}
But it shows as text in the div tag, not the image.
Any help?
try to use <div>#Html.Raw(stars)</div> instead of <div>#stars</div>
For your information on HTML Raw()
Hope this helps

ASP.NET MVC Razor extra whitespace rendered

In Asp.net MVC, Razor inserts extra space between text blocks. I want to render a list this way: "1, 2, 3" but get "1 , 2 , 3".
#for (int i = 1; i < 3; i++)
{
<text>#i</text>
if (i != 2)
{
<text>, </text>
}
}
Is there any ways to remove extra whitespace ?
I want to render a list this way: "1, 2, 3"
Quick and dirty:
#string.Join(", ", Enumerable.Range(1, 3))
Obviously a custom helper seems more appropriate to the job of formatting something in the view:
public static class HtmlExtensions
{
public static IHtmlString FormatList(this HtmlHelper html, IEnumerable<int> list)
{
return MvcHtmlString.Create(string.Join(", ", list));
}
}
and then simply:
#Html.FormatList(Model.MyList)
You are seeing the extra whitespace between the number and the comma because your razor template includes a line break (which displays as whitespace in the browser) between the number and the comma:
#for (int i = 1; i < 3; i++)
{
<text>#i</text> >LINE BREAK HERE<
if (i != 2)
{
<text>, </text>
}
}
I like Darin's answer, and I would suggest removing your loop and replacing it with a more declarative statement, but if you don't want to go that far, try at least removing the line break:
#for (int i = 1; i < 3; i++)
{
<text>#i</text>if (i != 2){<text>, </text>}
}
Instead of writing out bits of text in different places each time round the loop, you could accumulate all the text in a StringBuilder, then outside the loop do #stringBuilderObject.ToString().
The problem is with the source that is generated. When you look at the actual source you get:
1
,
2
,
3
As you can see there is a lot of white space in there which browsers collapse down to a single space (look at the definition for normal).
Using a StringBuilder or string.Join is the way to fix this if all you're doing is outputting these three numbers. But if you're trying to do something else and this is a simplified example then see this blog post for a way of doing it using ol/ul and lis.
I might assume that it is not issue of Razor, but rather element is rendered with some margings.
Open FireBug (or Chrome or whatever) and see that it is really markup issue.
In you css file try to add
text { margin: 0 }

Set value of var in foreach - Razor View Engine

I hope/suspect this is easy, so I will ask here and make a fool out of my self if it is.
I have a foreach loop in my view, mind you this is a Razor view. I dont know if the ASP.NET View engine does the same... but it might. I want to flip a bool on each loop, but it does not see to let me. The view engine chokes to death. Why? How can I fix it? I did a for loop and I did mod 2 for now, but I really need to understand this.
This is what I tried:
#{
var IsOdd = false;
}
#foreach(var foo in bar)
{
#{ IsOdd = !IsOdd; }
<div class="#(IsOdd ? "odd" : "even")">#foo</div>
}
Try this:
#{
var IsOdd = false;
}
#foreach(var foo in bar)
{
IsOdd = !IsOdd;
<div class="#(IsOdd ? "odd" : "even")">#foo</div>
}
(Worked for me with MVC 3 RC.)

Resources