Here is what I want to do:
#if (condition)
{
<div class="test">
}
<span class="test2">...</span>
#if (condition)
{
</div>
}
This does not work because the Blazor compiler thinks the div is never closed.
So I need to do this:
#if (condition)
{
<div class="test">
<span class="test2">...</span>
</div>
}
else
{
<span class="test2">...</span>
}
It works fine, but I have a big code redundancy with the span.
How can I do this properly?
Please note div and span are examples. In reality, my code is bigger.
Thanks
What you're seeing is really a Razor syntax issue rather than specifically a Blazor issue. This question and answer cover it well.
So, you can do what you're trying to do in the first example, but there are also other ways of solving that issue, at least one of which is Blazor specific (there are more no doubt):
Make the class conditional
Rather than trying to not render the div, you could make the class itself conditional.
So in the code section of your page you could declare a property:
#code {
string myClass = "";
protected override void OnInitialized()
{
if (condition)
{
myClass = "whatever";
}
}
}
And then use that in your razor:
<div class='#myClass'>
<span class="test2">...</span>
</div>
That way the span is only on the page once.
Split the common code into a separate component
Another approach is to make the common part (the span in this case) into a separate component and then render that component conditionally:
#if (condition)
{
<div class="test">
<YourComponent />
</div>
}
else
{
<YourComponent />
}
That's probably overkill for the span in your example, but makes more sense where the new component would be replacing multiple lines of code.
Related
I have a question about how to use ngIF in HTML code to choose different selector.
I show my code as follow:
in HTML Code:
<a class="style" (click)=clickFunction() (keyup.Enter)=ke()>
<div>
content
</div>
</a>
this is html is in a shared component,
I want to use this shared component into the other component with input parameter noClickAndKeyEnter=true |false
so in this case I should change html code as follow:
<a class="stype" (click)="noClickAndKeyEnter ? clickFunction(): ''" (keyup.Enter)="noClickAndKeyEnter ? ke() :''">
<div>
content
</div>
</a>
My question is, is there also the easy way to resolve my question, that I do not write all place with noClickAndKeyEnter ? :
any solutions?
There are multiple ways you can do this. The simplest could be:
clickFunction(){
if(this.noClickAndKeyEnter){
// execute code here
} else {
// just return or whatever you want here
}
}
You can use the callback pattern!
ts
conditionallyExecute(callback: Function, ...params) {
if(this.noClickAndKeyEnter) {
callback(params)
}
}
html
<a class="stype" (click)="conditionallyExecute(clickFunction, 1, 2)" (keyup.Enter)="conditionallyExecute(ke)">
<div>
content
</div>
</a>
Just a simple guard in your functions
clickFunction() {
if (!this.noClickAndKeyEnter) return;
...
}
ke() {
if (!this.noClickAndKeyEnter) return;
...
}
But by the name of noClickAndKeyEnter I think you might have the true / false values backwards.
Im trying to remove unused classes and id's in my site. Is there a function that I can use in the browser's JavaScript console (or other methods) to filter out the used/unused classes and elements.
Thanks in advance.
Something like this could work:
let classList = ["class1","class2","class3","class4","class5"];
classList.forEach(cl=>checkClasses(cl));
function checkClasses(classToCheck) {
if(document.querySelector('.'+classToCheck)){
console.log(classToCheck+' is being used');
}else {
console.log(classToCheck+' is not being used');
}
}
<div class="class1"></div>
<div class="class2"></div>
<div class="class4"></div>
<div class="class5"></div>
In polymer 1.1,
Does anyone know if there is a equalivant to
<div layout vertical?="{{mediaQuery}}"
horizontal?="{{!mediaQuery}}">
in polymer 1.0? class$={{foo}} doesn't do it as far as I can see. For instance, something like class$="vertical$={{mediaQuery}}"
Actually class$="{{foo}}" should work. But <div layout wouldn't 'cause the layout is now a class selector in Polymer ^1.0. So you will need to write something like <div class="vertical layout"> to make it work.
Since now string concatenation is not supported, in order to make the selectors dynamic, you need to use a computed binding -
<div class$="{{_computeLayoutClass(mediaQuery)}}">
_computeLayoutClass: function(mediaQuery) {
if (mediaQuery) {
return 'vertical layout';
}
else {
return 'horizontal layout';
}
}
I have a list of items I want to output as the contents of a main (the main in not included below). Each Item has 3 attributes: a Section Name, a Label and a Value. Each item is enclosed in a and everytime the Section Name changes I have to open a (and close the previous one, if any). I'm using a Razor view with this code:
#foreach (LocalStorageItem lsi in Model) {
string fld_name = "f_" + lsi.ItemName;
if (lsi.SectionName != sn) {
if (sn != "") {
Html.Raw("</fieldset>");
}
sn = lsi.SectionName;
<h2>#sn</h2>
Html.Raw("<fieldset>");
}
<div class="row">
<div class="ls_label">#lsi.ItemName</div>
<div class="ls_content" name="#fld_name" id="#fld_name">.</div>
</div>
}
#if (Model.Count != 0) {
Html.Raw("</fieldset>");
}
The problem is: each time the Section Name changes no fieldset tag (open and/or close) is generated. Where am I wrong? If I don't use Html.Raw (or #: as an alternative) the VS2010 parser signals an error.
Calling Html.Raw returns an IHtmlString; it doesn't write anything to the page.
Instead, you should write
#:</fieldset>
Using #: forces Razor to treat it as plain text, so it doesn't need to be well-formed.
However, your code can be made much cleaner by calling GroupBy and making a nested foreach loop.
I really think that the use of #: to work around such code is an abuse of that escape sequence. The problem should be addressed instead by correctly refactoring the code so that balanced tags can be easily written:
#foreach(var section in Model.GroupBy(i => i.SectionName)) {
<h2>#section.Key</h2>
<fieldset>
#foreach(LocalStorageItem lsi in section) {
string fld_name = "f_" + lsi.ItemName;
<div class="row">
<div class="ls_label">#lsi.ItemName</div>
<div class="ls_content" name="#fld_name" id="#fld_name">.</div>
</div>
}
</fieldset>
}
12 lines of code instead of 18
In Wicket 1.4, I'm trying to allow child pages to alter a CSS class on a tag in the parent page, which I do all the time. What is odd about this case is that the tag I want to target wraps the child page markup. Here's a simplified snip of what I tried:
ParentPage.html
<div id="main" wicket:id="main">
<wicket:child />
</div>
ParentPage.java
public abstract class ParentPage {
private WebMarkupContainer main;
protected ParentPage() {
main = new WebMarkupContainer("main");
add(main);
}
public void setClassAttr(String cssClass){
main.add(SimpleAttributeModifier("class", cssClass);
}
}
ChildPage.html
<wicket:extend>
...
</wicket:extend>
ChildPage.java
public class ChildPage extends Page {
...
public ChildPage() {
super();
...
setClassAttr("specific-class-for-this-page");
}
}
...Which blows up because it appears the HTML from the child loads, but not the java. (If I remove the wicket:id and java code on div#main, all is well.)
Note that the tag on the parent that I want to manipulate from the child is actually wrapping the wicket:child tag. In other cases I have done something similar, the tags I want to monkey with tend to be siblings or otherwise distant to the wicket:child tag.
All I really want to do is allow the child to change the class attribute on the parent - is there another way to do this? Why can't a child page be nested under another Wicket page component?
I would just like to point out that this has been removed as of Wicket 1.5. So, if you are using Wicket 1.5 or higher, you would use a TransparentWebMarkupContainer component instead of WebMarkupContainer.isTansparentResolver(). I also had the same problem as the poster. I have an outer, containing div which wraps a wicket:child tag, and I adjust its width (Twitter Bootstrap fluid grid) based on the content that it needs to display. My mainContentContainer is a TransparentWebMarkupContainer:
<div class="row-fluid">
<div class="span3" wicket:id="sidebarPanel"></div>
<div class="span6" wicket:id="mainContentContainer">
<wicket:child/>
</div>
<div class="span3" wicket:id="rightPanel"></div>
</div>
Sometimes the rightPanel is completely hidden, and the mainContentContainer changes to class="span9" to take up the unused viewport.
See here.
Thanks for posting. I had the exact same problem until I read this post.
First of all, it has nothing to do with actually setting the attribute, but with putting <wicket:child> inside a container.
Now imagine if ChildPage was a Panel, what would the code of your ParentPage look like? It would contain a line somewhere saying main.add( new ChildPanel() ). That's how the main component knows that when it renders, it should call the rendering method of your child panel too.
But with inheritance it's different. Your main component has no way of knowing what <wicket:child> should resolve to. Marking your main container transparent tells Wicket to ask the parent component (that is, your page component) to resolve and render it.
it's working great. on the component where is wicket:id="main" do what is above.
ain = new WebMarkupContainer("main") {
private static final long serialVersionUID = 1L;
#Override
public boolean isTransparentResolver() {
return true;
}
};
and exception do not occur.
I suppose your childpage extends the parentpage. Why not pass the class name into the parent's constructor like
public class ChildPage extends ParentPage {
public ChildPage() {
super("my-class");
}
}
A co-worker found the fix - make the component about the wicket:child tag a "transparentResolver". +1 to anyone who can clearly articulate how this works precisely?
main = new WebMarkupContainer("main") {
private static final long serialVersionUID = 1L;
#Override
public boolean isTransparentResolver() {
return true;
}
};
add(main);
I think, that your wicket usage (or at least code you posted) is strange (I tried with 1.4.22)...
public abstract class ParentPage {
Probably you forgot extends WebPage.
public class ChildPage extends Page {
here you want to extends ParentPage I guess.
Everything works as expected and final HTML generated is
<div id="main" wicket:id="main" class="specific-class-for-this-page">
<wicket:child>
<wicket:extend>
text
</wicket:extend>
</wicket:child>
</div>
My recommendation is "do not use HTML id for wicket elements when you do not need to".