I'm using UiBinder to create a custom widget. The UI template is something like:
<g:HTMLPanel styleName="setting">
<div ui:field="dynamicDiv">
</div>
{other stuff here}
</g:HTMLPanel>
Then, to add widget in the dynamicDiv I wrap it with HTMLPanel:
HTMLPanel.wrap(dynamicDiv);
and just use it as a normal widget.
When I run the application normally everything is fine, but if I run in debug mode, the following
assert Document.get().getBody().isOrHasChild(element);
in HTMLPanel.wrap() it fails, hence I am unable to debug the code.
Apart from the annoyance of debugging, I guess there was a good reason to put that assert there, so I would like to understand what is the correct way to wrap that div.
You don't need to wrap the div, just use the appropriate method from the containing HTMLPanel; e.g.:
theHtmlPanel.add(theWidget, dynamicDiv);
Related
I've recently added a simple ZK ThemeProvider that adds some CSS files, which works fine but seems to have a strange side effect... My index page looks like this...
<?page id="iframe" title="${labels.title}"?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver" ?>
<zk>
<include src="/zk/content/outerContainer.zul" id="outerContainer" sclass="outerContainerLayout" apply="com.example.RootComposer"/>
</zk>
But somehow, ZK ends up putting this style into the include-div...
style="width:100%;height:100%;"
The width and height of 100% is not correct, but I have no idea where they come from. Interesting enough, it only happens to that include - not includes following. Except, when I try to wrap the thing into another include - both get 100%, but still not the includes below that in the hierarchy.
Anyone an idea where zk adds this strange style?
The solution is in the documentation:
If this component is the only child of its parent, the default width
and height will become 100%.
Somehow this only seems to happen when ThemeProvider is used (or there was some other side effect before that prevented it). Anyway, adding a (hidden) empty div to my index page solved the problem:
<?page id="iframe" title="${labels.title}"?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver" ?>
<zk>
<include src="/zk/content/outerContainer.zul" id="outerContainer" sclass="outerContainerLayout" apply="com.example.RootComposer"/>
<div sclass="hidden"/> <-- Cannot have a poor, sad, alone include -->
</zk>
Now the style of the include-div is empty, as it should be.
Ok, to set a Css for a widget in Gwt or Gwtp, we can do following:
-1. directly from gwt code. Ex: label1.getElement().getStyle().setBackground("blue");
-2. include "ui:style" in UiBinder xml file, but this css only visible to that UiBinder
-3. include "ui:width" in UiBinder xml file, it will visible to all UiBinder
- and there r many way to set the Css directly to the widget in UiBinder.
The one that made me confused is that if i used , ex
<ui:with field='res' type="com.myproj.client.MyResource" />
& if myResource.css has .gwt-TabLayoutPanel then i don't need to use "addStyleNames", ex <g:TabLayputPanel />, it can recognized CSS perfectly.
However, if i add .gwt-ScrollPanel into myResource.css & use <g: ScrollPanel /> then nothing happened.
So I have to create public interface MyCssResource extends CssResource, then add String gwt-ScrollPanel(); to MyCssResource. But Java eclipse do not allow hyphen - in the method name, so I have to change to String gwtScrollPanel();.
Finally, i have to add addStyleNames into <g: ScrollPanel />, ex <g: ScrollPanel addStyleNames="{res.css.gwtScrollPanel}" /> then it will work.
That also means if i want to use .gwt-TabLayoutPanel in MyCssResource, then i need to remove the hyphen - & this will cause inconsistency in my code.
So, can someone explain to me what is going on here? I am confused?
The only think you should be aware about, is that GWT obfuscates class names when you use then in ui-binders. For instance:
<ui:style>
.gwtTabLayoutPanel {}
</ui:style>
<g:TabLayoutPanel addStyleNames="{style.gwtTabLayoutPanel}" />
.gwtTabLayoutPanel will be renamed to something like .AB in the final injected style-sheet.
But most GWT widgets, are styled with un-obfuscated class names, so for using them in ui-binders files, you have to define as external in order to prevent GWT compier to obfuscate the class name:
<ui:style>
#external .gwt-TabLayoutPanel;
.gwt-TabLayoutPanel {}
</ui:style>
<g:TabLayoutPanel />
That's because when you create a TabLayoutPanel, it has a default class called .gwt-TabLayoutPanel. So you don't need to add that class manually in to your TabLayoutPanel.Just create a TabLayoutPanel and you will see the class ".gwt-TabLayoutPanel" is already there.
But ScrollPanel doesn't comes with a default class called .gwt-ScrollPanel. It is just a div. Try creating a ScrollPanel and see. It doesn't have any classes added initially.see the screenshot
If you want to add a class called .gwt-ScrollPanel you will have to do it manually.
I have a form in a module that I want to appear in a modal window. Depending on the id the window may be blank, or if it does show any content all classes and ids are removed, so I can't validate or style the form.
Truncated Code:
...
<div id="feedback">
<div class="feedbackinner">
<!-- form module -->
<div id="contact-wrapper">
<!--form elements with ids and classes-->
</div>
<!-- end module -->
</div><!-- end .feedbackinner -->
</div><!-- end #feedback -->
This triggers the modal window without any ids or classes (using Firefox Web Developer outline current elements):
Click for ugly unstyled form that won't validate
This triggers a blank modal window:
Click if you like staring at a blank white box
So most importantly how do I keep all the ids and classes inside the modal window, and why won't calling the parent div work?
( As a work around I moved the form to a component view then called it using handler: 'iframe' instead of clone. I still want to know what's going on with the modal window. )
Thanks!
not seen the code but implications of using Element.clone on an element are apparent. By nature of HTML, id is meant to be unique. This means you are not really supposed to have more than one element with the same id injected into the DOM at the same time.
MooTools mirrors the sentiment correctly by implicitly removing the id from any element it creates a clone of:
https://github.com/mootools/mootools-core/blob/master/Source/Element/Element.js#L860
the .clone method accepts optional arguments which allow you to override stuff:
clone: function(contents, keepid){ - see http://mootools.net/docs/core/Element/Element#Element:clone as well.
cloned elements also lose all the events you may have assigned to them (but cloneEvents can help with that).
I would recommend looking at the squeezebox implementation and double check that the clone is implemented in the intended way. A better practice may be to adopt and re-attach the elements instead - or to copy the whole innerHTML (though this will once again cause non-delegated events to fail).
I have issue with auto generated code for web components.
Here is piece of HTML:
<div id="hidden-ui">
<div id="auth-form" class="...">
...
<to-button></to-button>
</div>
...
</div>
As you can see, there is custom web component called to-button:
<element name="to-button" constructor="TOSimpleButton" extends="div">
...
</element>
On startup I want to move #auth-form outside from parent node to document root:
Element af = document.query('#auth-form');
Element db = document.query('BODY');
db.children.add(af);
It's OK if there is no custom web-components inside movable node, but while to-button is inside I get run-time RangeError.
Here is piece of auto generated code:
__e1 = __root.nodes[9].nodes[1].nodes[7];
__t.component(new TOSimpleButton()..host = __e1);
As you can see, there is strict old path to component, thus RangeError exception raise.
How can I handle with this?
Sounds like you want to display popup forms every now and then. Here's what I do.
I specify this constructor for the dialog/popup:
var lifecycleCaller;
DialogFooComponent() {
host = new Element.html('<x-dialog-foo></x-dialog-foo>');
lifecycleCaller = new ComponentItem(this)
..create();
document.body.children.add(host);
lifecycleCaller.insert();
}
And as you can see, I add it to the document body. However, this only happens when creating a new instance.
Whenever I need to show that popup, I have code like this:
import '../dialog/foo/foo.dart';
...
// Later at some point I do:
new DialogFooComponent();
And what happens is that you have popup forms appearing in the body whenever you wish them to.
When you want to close the dialog, you can just call this inside the dialog component:
lifecycleCaller.remove();
As mentioned here, this will not be fixed in WebUI package, but will in Polymer.
this won't be fixed in web_ui pkg. It should work in polymer pkg.
I'm working on a site in EPiServer, and whenever I create a page property with the type set to "XHTML string" (which uses the WYSIWYG content editor in Edit mode), it wraps all content in <p> tags.
Is there any way to prevent this from happening? I can't remove the paragraph margins universally through my CSS (e.g. p {margin: 0 !important;}) since I do need the margins for actual paragraphs of text. I've even tried going to the HTML source view in the editor and manually deleting the <p> tags that it generates, but it immediately adds them back in when I save!
It doesn't happen when the property type is either a long or short string, but that's not always an option since the content might contain images, dynamic controls, etc.
This is becoming a real nuisance since it's very hard to achieve the layout I need when basically every element on the page has extra margins applied to it.
As Johan is saying, they are there for a reason - see more info here. That being said, it's not impossible to remove them. It can be done in one of two ways (taken from world.episerver.com:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
myEditor.InitOptions["force_p_newlines"] = "false";
}
or
<script type="text/javascript">
tinyMCE.init({
force_p_newlines: false
});
</script>
You can add your own custom TinyMCE-config that removes P-elements or strip them out using regular expressions either when saving the page or when rendering the property/page.
I think it's a bad idea though. P-elements are what the editors generate the most and in most cases their content is also semantically correct. Better to wrap your property in a div with a class and adjust margins using CSS like you mention.
If you're using a version of EPiServer with TinyMCE editors, you can insert <br /> elements instead of <p> elements if you type shift-enter instead of enter. This should eliminate your margin problems.
More info at the link below:
http://www.tinymce.com/wiki.php/TinyMCE_FAQ#TinyMCE_produce_P_elements_on_enter.2Freturn_instead_of_BR_elements.3F
EDIT: My comment below answers his question better.
I discovered that while I can't remove the <p> tags from the source view (because it adds them back in automatically), if I replace them with <div> tags, it'll leave things alone. It does mean that I've got an extra <div> wrapping some elements that I don't really need, but at least a <div> doesn't add margins like a <p> does, so...good enough!