I am able to pass data to view file, but need to display them in different format with .
I try to use if statement to check the form name.
It returns error said "Operator '==' cannot be applied to operands of type 'System.Web.HtmlString' and 'string'".
Can I add blocks within IF condition? how to validate data within if condition in view file? Thank you! Here is the code:
#{ foreach (var form in #ViewBag.FormContent)
{
if (Html.Raw(form.Name) == "xyz") //pull up the title and text for the form
{
#Html.Raw(form.FormTitle)
<div class="panel-body">
<div style="height: 300px; overflow: auto; padding:15px;">
#Html.Raw(form.FormText)
</div>
</div>
}
}}
HTML.Raw returns an object that implements IHtmlString. It does not return a string. It doesn't even support ToString. Its only member is ToHtmlString(), which returns a string.
If you want to compare the output of Html.Raw with "xyz", you need to convert it to a string first. So instead of
if (Html.Raw(form.Name) == "xyz")
use something like
if (Html.Raw(form.Name).ToHtmlString() == "xyz")
Or... don't even bother with Html.Raw to begin with. Don't think you need it. Just write this:
if (form.Name == "xyz")
Related
In Angular, how to use *ngIf to check whether a JSON value includes a certain string, and then show them a certain URL ? In my case I have a object name called campaigns.description which has a value that includes a description. I want to see whether a given string, for example "one beam" is included in that description and show an URL based on that.
So not the way that the value equals a certain string, but the text that is held within the value includes a certain string.
You can use indexof() function to check the existence of some substring inside a string. This function returns '-1' if the substring is not present in the string.
<label *ngIf="campaigns.description.indexOf('One Beam') != -1 ? true : false">{{urlToShow}}</label>
You could generally use indexOf to check whether a string contains a sub-string.
console.log("Sample string".indexOf('string'));
console.log("Sample string".indexOf('not'));
The Angular part:
Trivial (not recommended)
Trivial solution is to check directly in the *ngIf condition
<div *ngIf="campaigns.description.indexOf('one beam') !== -1; else other">
<!-- contains the sub-string -->
</div>
<ng-template #other>
<!-- does not contain the sub-string -->
</ng-template>
However binding a function to *ngIf directive with default change detection strategy would trigger the function for each change detection cycle. It might lead to performance issues.
Additional property (recommended)
You could introduce additional property to hold the result of the condition in the controller and use it in the template.
Controller (*.ts)
// I assume `campaigns` is initialized in a subscription
ngOnInit() {
someObservable.subscription(
(res: any) => {
this.campaigns = {
...res,
subString: res.description.indexOf('one beam') !== -1
}
},
(error: any) => { }
);
}
Template (*.html)
<div *ngIf="campaigns?.subString; else other">
<!-- contains the sub-string -->
</div>
<ng-template #other>
<!-- does not contain the sub-string -->
</ng-template>
I want to allow a user to provide a list of one-word attributes without parameter values. For example,
<container row crosscenter wrap spacearound ...>
which results in something like this in container.html
<div [ngClass]="{ 'flexDisplay': true, 'directionRow': isRow, 'directionCol': isCol, 'contentSpaceAround': isSpaceAround}" ...>
What I'm missing is how to set
#Input('row') isRow = false;
to true if 'row' was present in the container line.
Any ideas?
Thanks in advance.
Yogi
This can be handled in ngOnChanges. The value can be assigned either back to input property or to some object that will be passed to ngClass
ngOnChanges(changes: SimpleChanges) {
if ('foo' in changes) {
this.options.foo = true;
}
}
Since there's no way how inputs can become unassigned, there's no reason to provide bindings for them. #Attribute can be used instead:
constructor(#Attribute('foo') public foo: boolean|null) {
this.foo = (foo != null);
}
Using attributes for regular options isn't a good decision, design-wise. This prevents from setting them dynamically. Instead, it is always preferable to accept options input. If all options are supposed to be flags, it can be a string input that will be split and processed in ngOnChanges, like:
<container options="row crosscenter wrap spacearound">
or
<container [options]="'row crosscenter wrap spacearound'">
I think the answer to my question is to create directives for each of the "one-word" tags (attributes) I want to use.
:-)
I have a template as below:
<span *ngIf="item.status !=='E1' && item.status !=='B' && item.status !=='R'">{{item.status_desc}}</span>
As above, i have a ngIf condition there, making no sense but somehow it working. What am trying to do there is check "status in [E1, B, R]" something like that. How can i do that in the html without going to the ts file. Any idea guys?
In your HTML, you could use includes(), which returns true if the element is found:
<span *ngIf="!['E1', 'B', 'R'].includes(item.status)">{{item.status_desc}}</span>
as JB Nizet suggested.
Or you could use a function, like this:
statusList = [E1, B, R];
checkStatus(item)
{
return (statusList.indexOf(item) != -1);
}
where your HTML now should llol like this:
<span *ngif="checkStatus(item.status)">{{item.status_desc}}</span>
If you really don't want to go to your TypeScript source, you can do something like this for increased readability.
<span *ngIf="!['E1', 'B', 'R'].includes(item.status)">{{item.status_desc}}</span>
But perhaps it's wiser to make a variable on your class with the 'undesired' statuses like:
public ignoreStatus: string[] = ['E1', 'B', 'R'];
and then
<span *ngIf="!ignoreStatus.includes(item.status)">{{item.status_desc}}</span>
but then it would be even better to make a reusable method out of this in your class:
public isIgnoreStatus(item: any): boolean {
return this.ignoreStatus.includes(item.status);
}
with
<span *ngIf="!isIgnoreStatus(item.status)">{{item.status_desc}}</span>
No you cannot do that with template, what you can do is create a function that does the job for you
statuses = [E1, B, R];
checkValid(item){
return (statuses.indexOf(item) != -1);
}
then in HTML
<span *ngIf="checkValid(item.status)">{{item.status_desc}}</span>
You can create a pipe to do all this filters.
In that pipe you can write any logic to remove all unwanted elements.
It will make your code look better and understandable.
I want to create a string variable in thymeleaf by iterating through a loop and concatenating values into this string variable. Then i want to display this string in a <span> element. What i want to achieve can be written in java as follows:
String forDisplay = "";
foreach (MyObject o : myObjectCollection) {
if (o.type == 1) { forDisplay += o.stringValue; }
}
Then in i want to put this in an html element like span. I know how to use:
<span th:each="o : ${objectCollection}" th:if="${o.type == 1}" th:text="${o.stringValue}"></span>
But this creates <span> for each of the elements that satisfy the condition. I just want to build-up my string in a th tag free section and then i just want to display my string in a single <span> element.
Ahmet, take a look at Expression Utility Objects for Strings, from Thymeleaf docs.
You have three methods for joining items:
${#strings.arrayJoin(namesArray,',')} // For Arrays
${#strings.listJoin(namesList,',')} // For Lists
${#strings.setJoin(namesSet,',')} // For Sets
These Utility Objects offers lots of cool methods for Aggregation, Calendars and etc.
Att
Here is how I join numbers into string using ", " as delimiter
<span th:each="instrumentDescriptor, iterStat : ${instrument.instrumentDescriptors}" th:text="!${iterStat.last} ? ${instrumentDescriptor.instrumentVersion} + ', ': ${instrumentDescriptor.instrumentVersion}"></span>
how are we going to use conditional operators on the {{#index}} variable such that we can print only the even records form the json.
{{#each options}}
if( {{#index}} % 2 == 0 ) //
{
print record
}
else
{ this is a odd record
}
{{/each}}
Logic like you're trying to do has to be in a helper function. You can't put relational operators like that directly into a handlebars template. It is designed that way on purpose. Helpers are very easy to create and use. See http://handlebarsjs.com/#helpers more more info.
FYI, a very common helper I use is an even/odd helper:
hbs.registerHelper("stripes", function(index) {
return (index % 2 === 0 ? "even" : "odd");
});
Which I use like this to get an "even" or "odd" class name put in a row:
<div class="row {{{stripes #index}}}">
... other content
</div>
I don't quite understand what you're trying to do in your example, but you could hide all the odd records with a simple CSS rule or you could put more logic into the helper.