I am not able to figure out how :host(:hover) works on child custom elements of a parent custom element. Can someone explain how to make this work?
todoitem.html
<!-- import polymer-element's definition -->
<link rel="import" href="packages/polymer/polymer.html">
<polymer-element name="my-li" extends="li">
<style>
:host(:hover){
color: red;
}
</style>
<template>
<content></content>
</template>
<script type="application/dart" src="todoitem.dart"></script>
</polymer-element>
todoitem.dart
import 'package:polymer/polymer.dart';
import "dart:html" as html;
import 'package:logging/logging.dart';
final Logger _widgetlogger = new Logger("todo.item");
#CustomTag('my-li')
class MyListElement extends html.LIElement with Polymer, Observable {
factory MyListElement() => new html.Element.tag('li', 'my-li');
MyListElement.created() : super.created() {
polymerCreated();
}
#override
void attached() {
super.attached();
_widgetlogger.info("todoitem attached");
}
#override
void detached() {
super.detached();
_widgetlogger.info("todoitem detached");
}
}
todowidget.html
<!-- import polymer-element's definition -->
<link rel="import" href="packages/polymer/polymer.html">
<link rel="import" href="todoitem.html">
<polymer-element name="todo-widget" attributes="title">
<template>
<style>
:host(.colored){
color: blue;
}
</style>
<div>
<h1>{{title}}</h1>
<div>
<input id="inputBox" placeholder="Enter Todo item" on-change="{{addToList}}">
<button id="deleteButton" on-click="{{deleteAll}}">Delete All</button>
</div>
<ul id="todolist">
</ul>
</div>
</template>
<script type="application/dart" src="todowidget.dart"></script>
</polymer-element>
Corresponding Dart Script
import 'package:polymer/polymer.dart';
import "dart:html" as html;
import "todoitem.dart";
import 'package:logging/logging.dart';
final Logger _widgetlogger = new Logger("todo.widget");
#CustomTag('todo-widget')
class TodoWidget extends PolymerElement {
#published String title;
html.InputElement todoInput;
// html.ButtonElement deleteButton;
html.UListElement todolist;
#override
void attached() {
super.attached();
todolist = $["todolist"];
todoInput = $["inputBox"];
}
TodoWidget.created() : super.created() {
//This can go into template!!!
if (title == null) {
title = "My Todo App";
}
;
}
void deleteAll(html.Event e, var detail, html.Node target) {
_widgetlogger.info("All items deleted");
todolist.children.clear();
// print("Clicked");
}
void addToList(html.Event e, var detail, html.Node target) {
_widgetlogger.info("Item added");
MyListElement li = new MyListElement();
li
..text = todoInput.value
..classes.add("todoitem")
..onClick.listen((e) => e.target.remove());
todolist.children.add(li);
todoInput.value = "";
}
}
Upon running I see no hovering effect. How can I fix this?
I guess the problem is that the style tag is outside the <template> tag. It should be inside. I played around with your code (same as in your previous question) and moved the style inside the <template> tag without knowing that I was deviating from the code you posted in your question (I built the element from scratch instead copying the code from your question).
Related
I have created a directive and using HostListner , want to add a CSS style on Click event on the tag.Also remove on the click again.I have the following CSS .
CSS
.strikethrough { text-decoration: line-through;}
HTML
<p optionalIngredient>ABCD</p>
Directive
constructor(private elRef: ElementRef ,private renderer: Renderer2)
{ }
#HostListener('mouseenter') onMouseEnter() {
this.renderer.addClass(this.elRef.nativeElement, 'strikethrough');
}
#HostListener('mouseleave') onMouseLeave() {
this.renderer.removeClass(this.elRef.nativeElement,strikethrough');
}
You can use a boolean to keep track of whether the style is applied.
styled = false;
#HostListener('click')
onClick(){
if (!styled) this.renderer.addClass(this.elRef.nativeElement, 'strikethrough');
else this.renderer.removeClass(this.elRef.nativeElement, 'strikethrough');
this.styled = !this.styled;
}
I tried to build compound components with Lit 2.0 but passing data to slots as attributes seems impossible.
<my-accordion>
<my-accordion-title>Title</my-accordion-title>
<my-accordion-content>Content</my-accordion-content>
</my-accordion
How I can pass "extended" propery to custom elements slots?
Here is my custom elements:
#customElement("my-accordion")
export class MyAccordion extends LitElement {
#property()
extended: boolean = false;
toggleExtend(){
this.extended = !this.extended
}
render() {
return html`
<div #click=${this.toggleExtend}>
<slot .extended=${this.extended}></slot>
</div>
`;
}
}
#customElement("my-accordion-title")
export class MyAccordionTitle extends LitElement {
// want to access parent node extended property here
render() {
return html`
<div>
<slot></slot>
</div>
`;
}
}
To assign the extended property to slotted children, get the slot element's assignedElements() array.
#customElement("my-accordion")
export class MyAccordion extends LitElement {
#property()
extended: boolean = false;
toggleExtend(){
this.extended = !this.extended
}
updated(changed: PropertyValues<this>) {
if (changed.has('extended'))
this.extendedChanged()
}
extendedChanged() {
for (const child of this.slot.assignedElements()) {
if (child instanceof MyAccordionTitle)
child.extended = this.extended;
}
}
#query('slot') slot: HTMLSlotElement | null;
render() {
return html`
<div #click=${this.toggleExtend}>
<slot></slot>
</div>
`;
}
}
#customElement("my-accordion-title")
export class MyAccordionTitle extends LitElement {
// want to access parent node extended property here
render() {
return html`
<div>
<slot></slot>
</div>
`;
}
}
NB: When assigning click listeners to <div> and other non-interactive elements, there are many accessibility issues involved. It's usually recommended therefore to use a <button> element, or in your case maybe a <details> and <summary>
i have a HTML document rendered from Server Side in Xamarin WebView.
I want to apply CSS Stylesheet to the HTML document in webview.
using (HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse())
{
using (Stream stream = httpResponse.GetResponseStream())
{
string response = (new StreamReader(stream)).ReadToEnd();
ArticleData article = JsonConvert.DeserializeObject<ArticleData>(JsonConvert.DeserializeObject<ArticleDetails>(response).d);
var htmlSource = new HtmlWebViewSource();
htmlSource.Html = "<html><head><link rel='stylesheet' type='text/css' href='Assets/Main.css' /></head><body>" + article.Html + "</body></html>";
webView.Source = htmlSource;
}
}
According to your code, the css is inside the Assets. Due to i did not have the article.Html, i created a local.html in Assets folder for reference.
local.html:
<html>
<head>
<title>webViewSample</title>
<link rel="stylesheet" type="text/css" href="Main.css" />
</head>
<body>
<h1>Xamarin.Forms</h1>
<p>This is a local Android Html page</p>
<img src="XamarinLogo.png" />
</body>
</html>
Main.css:
html,body{margin:0;padding:10px}
body, p, h1 {
font-family: 'Roboto';
}
Use the dependency service to load the CSS and html file from the Assets folder.
[assembly: Xamarin.Forms.Dependency(typeof(BaseUrl_Android))]
namespace App27.Droid
{
public class BaseUrl_Android : IBaseUrl
{
public string Get()
{
return "file:///android_asset/";
}
}
}
Xaml:
<StackLayout>
<Button Clicked="Button_Clicked"></Button>
<WebView x:Name="webView" HeightRequest="500"/>
</StackLayout>
Code behind:
public interface IBaseUrl { string Get(); }
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
var htmlSource = new HtmlWebViewSource();
htmlSource.Html = "<html><head><link rel='stylesheet' type='text/css' href='Main.css' /></head><body>" + " <p><a href='local.html'>next page</a></p>" + "</body></html>";
htmlSource.BaseUrl = DependencyService.Get<IBaseUrl>().Get();
webView.Source = htmlSource;
}
}
Screenshot: https://imgur.com/My83Qvv
I want to get the atomic clock from here http://watches.uhrzeit.org/atomic-clock.php and I wrote this program
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.*;
import java.util.*;
public class da {
/**
* #param args
*/
public static void main(String[] args) {
try{
Document doc=Jsoup.connect("http://watches.uhrzeit.org/atomic-clock.php").get();
Elements spans = doc.select("span[id=anzeige_std]");
System.out.println(spans.text());
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
The problem is why it doesn't print anything(I am noob in this thing and I want to learn).
First, to select an element by its id, use the format element#id. The way you have it is for other attributes.
Second, the clock is on this html:
<div id="timer">
<div id="timeText">
<h2>current time CET</h2>
<div id="anzeige_zeit">22:03:10</div>
<div id="anzeige_datum">Tuesday, 2. August 2016</div>
<div id="anzeige_kw">calendar week 31</div>
</div>
</div>
Which we can target with CSS Selectors like this:
Document doc = Jsoup.connect("http://watches.uhrzeit.org/atomic-clock.php").get();
Element atomicTime = doc.select("div#anzeige_zeit").first();
System.out.println(atomicTime.ownText());
Output
22:08:05
I have my GWT application with TabLayoutPanel and when I load it in Chrome, everything is fine. But when I first load it in ie9 I don't get the full page: several labels and images on the first tab didn't load. But when I create the second tab and then open the first one, everything is fine. I found some questions about this on this site that the code is correct. The problem must be in first time uploading css. I compared the code in Chrome and IE(first load and after creating the second tab in TabLayoutPanel) and here are the results
Chrome
<head>
<link rel="stylesheet" href="http://127.0.0.1:8888/myproject/Upload.css">
<style>
#loader{position:fixed;......A LOT OF STYLES...
</style>
</head>
<body style="margin: 0px;">
IE (first load)
<head>
<link rel="stylesheet" href="http://127.0.0.1:8888/myproject/Upload.css">
<style></style>
<style></style>
</head>
<body style="margin: 0px;">
<iframe>
...
<div style="height: 0px;">
...
<div style="top: 0px; bottom: 0px;">
</iframe>
IE (after creating the second tab in TabLayoutPanel)
<head>
<link rel="stylesheet" href="http://127.0.0.1:8888/myproject/Upload.css">
<style></style>
<style></style>
</head>
<body style="margin: 0px;">
<iframe>
...
<div style="height: 68px;">
...
<div style="top: 68px; bottom: 221px;">
</iframe>
Help me please. What should I do? I need that the page loaded correctly in the first loading.
Java Code
public void onModuleLoad() {
startAuthApplication();
}
private void startAuthApplication() {
AppController appController = new AppController();
appController.go(RootLayoutPanel.get());
}
/********************************************************************/
public class AppController{
public void go(final HasWidgets container) {
SystemPresenter systemPresenter = new SystemPresenter(AppFactory.getSystemView());
systemPresenter.go(container);
}
}
/********************************************************************/
public class SystemPresenter{
private final SystemView systemView;
public SystemPresenter(SystemView systemView) {
this.systemView = systemView;
}
public void go(HasWidgets container) {
container.clear();
container.add(systemView.asWidget());
}
}
/********************************************************************/
public class AppFactory {
private static SystemView systemView;
private static TabPanelViewImpl tabPanelView;
public static SystemView getSystemView() {
if (systemView == null) {
systemView = new SystemViewImpl();
}
return systemView;
}
public static TabPanelViewImpl getTabPanelView() {
if (tabPanelView == null) {
tabPanelView = new TabPanelViewImpl();
}
return tabPanelView;
}
}
/********************************************************************/
public class SystemViewImpl extends Composite implements SystemView {
interface Binder extends UiBinder<DockLayoutPanel, SystemViewImpl> {
}
private static Binder binder = GWT.create(Binder.class);
#UiField(provided = true)
TabPanelViewImpl tabPanelView;
public SystemViewImpl() {
tabPanelView = AppFactory.getTabPanelView();
initWidget(binder.createAndBindUi(this));
}
}
/********************************************************************/
public class TabPanelViewImpl extends Composite implements TabPanelView,
DocListEditDraftEventHandlers {
interface TabPanelViewImplBinder extends
UiBinder<TabLayoutPanel, TabPanelViewImpl> {
}
private static TabPanelViewImplBinder binder = GWT
.create(TabPanelViewImplBinder.class);
private TabPanelPresenter presenter;
#UiField(provided = true)
TabLayoutPanel tabPanel;
private DocListTableView docListTableView;
public TabPanelViewImpl() {
super();
tabPanel = new TabLayoutPanel(30, Unit.PX);
docListTableView = AppFactory.getDocListTableView();
tabPanel.add(docListTableView, "List of Docs");
initWidget(binder.createAndBindUi(this));
}
/********************************************************************/
public class DocListTableView extends Composite {
interface DocListTableViewUiBinder extends
UiBinder<Widget, DocListTableView> {
}
private static DocListTableViewUiBinder uiBinder = GWT
.create(DocListTableViewUiBinder.class);
private final DocListTableConstants constants = GWT
.create(DocListTableConstants.class);
private final Resources resources = GWT.create(Resources.class);
private final DocListTableResources resource = GWT
.create(DocListTableResources.class);
#UiField(provided = true)
CellTable<DocList> cellTable;
#UiField
Label emptyLabel;
#UiField(provided = true)
Label userLabel;
public DocListTableView() {
userLabel = new Label("User: "
+ AppFactory.getUserInfo().getUserName());
initWidget(uiBinder.createAndBindUi(this));
}
/********************************************************************/
DocListTableView.ui.xml
<ui:with field="res"
type="com.myproject.client.resources.DocListTableConstants" />
<g:DockLayoutPanel unit='EM'>
<g:north size='5'>
<g:HTMLPanel addStyleNames="{docListStyle.center}">
<g:HorizontalPanel width="100%">
<g:cell horizontalAlignment="ALIGN_LEFT">
<g:Label addStyleNames="{docListStyle.label}" ui:field="userLabel" />
</g:cell>
</g:HorizontalPanel>
<g:HorizontalPanel width="100%">
<g:cell horizontalAlignment="ALIGN_CENTER">
<g:Label addStyleNames="{docListStyle.label} {docListStyle.centerLabel}"
text="{res.label}" />
</g:cell>
</g:HorizontalPanel>
</g:HTMLPanel>
</g:north>
<g:center>
<g:HTMLPanel addStyleNames="{docListStyle.center1}">
<g:HorizontalPanel width="100%">
<g:cell horizontalAlignment="ALIGN_CENTER">
<g:Label ui:field="emptyLabel" visible="false">Your document list is empty</g:Label>
</g:cell>
</g:HorizontalPanel>
<table cellspacing='0' cellpadding='0'>
<tr>
<td valign='top'>
<ct:CellTable addStyleNames='{docListStyle.panel1}'
ui:field='cellTable' />
</td>
</tr>
<tr>
<td align='center'>
<my:DocListSimplePager ui:field='pager'
visible="false" />
</td>
</tr>
</table>
</g:HTMLPanel>
</g:center>
<g:south size='10'>
<g:HTMLPanel addStyleNames="{docListStyle.center}">
<g:Label addStyleNames="{docListStyle.label} {docListStyle.centerLabel}"
text="{res.status}" />
<table>
<tr>
<td>
<g:Image url="images/status/draft.png"></g:Image>
</td>
<td>
<div class="{docListStyle.label}">
<ui:text from='{res.draft}' />
</div>
</td>
<td>
<g:Image url="images/status/accept.png"></g:Image>
</td>
<td>
<div class="{docListStyle.label}">
<ui:text from='{res.accept}' />
</div>
</td>
</tr>
<tr>
<td>
<g:Image url="images/status/send.png"></g:Image>
</td>
<td>
<div class="{docListStyle.label}">
<ui:text from='{res.send}' />
</div>
</td>
<td>
<g:Image url="images/status/get.png"></g:Image>
</td>
<td>
<div class="{docListStyle.label}">
<ui:text from='{res.get}' />
</div>
</td>
</tr>
</table>
</g:HTMLPanel>
</g:south>
</g:DockLayoutPanel>
I know I posted a lot of code, but I hope it quite understanding. I add DocListTableView on the first tab of TabLayoutPanel and in DocListTableView.ui.xml file only celltable+pager display in first load. The other Labels and <table> element doesn't show up.
Edit
Interface Resources and DocListTableResources I use in cellTable and they render correctly.
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
public interface Resources extends ClientBundle {
#Source("draft.png")
ImageResource draft();
#Source("edit.png")
ImageResource edit();
...
}
import com.google.gwt.user.cellview.client.CellTable;
public interface DocListTableResources extends CellTable.Resources {
public interface DocListTableStyle extends CellTable.Style {
};
#Override
#Source({ "DocListTableStyle.css" })
DocListTableStyle cellTableStyle();
}
Edit2
import com.google.gwt.i18n.client.ConstantsWithLookup;
public interface DocListTableConstants extends ConstantsWithLookup {
public String label();
public String status();
public String draft();
...
If the tabs loads properly the second time you trigger it, there might some kind of race condition going on when the view is initially created and populated. In such cases, Scheduler.scheduleDeferred usually helps:
A deferred command is executed after the browser event loop returns.
Meaning, the code in the callback will be executed when the view is created and added to the DOM.
As to where this call is needed - I can only guess, you know your code best :) I'd start with:
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
tabPanel.add(docListTableView, "List of Docs");
}
});
Thanks for all your help, but I found the error by myself.
In DocListTableView.ui.xml I use DockLayoutPanel and set it size in EM.
<g:DockLayoutPanel unit='EM'>
There is a problem with IE with using EM. So I tried to use PX and it worked!