DOM selecting elements that are visible in a dom-if - polymer-1.0

I'd like for a way to select only visible elements in the DOM that are within a template that evaluates to true.
<template is="dom-if" if="[[true]]">
<span>I should be selectable</span>
</template>
<template is="dom-if" if="[[false]]">
<span>I should not be selectable</span>
</template>
I'm currently using this:
Polymer.dom(this.root).querySelectorAll("span");
which also returns nodes that are in <dom-if> templates that evaluate to false.
Is there any to do this without using restamp?

Related

Insert named slot inside v-for loop vuejs

Does anyone know how to insert a named slot inside a loop?
I've got for example this code:
Children
<div v-for="num in nums" :key="num">
<slot name="foo"></slot>
</div>
And the parent is like:
<foo-component :nums="nums>
<template slot="foo">
<span>Inside the foo component</span>
</template>
</foo-component>
If I do so, the console will show this alert:
Duplicate presence of slot "foo" found in the same render tree - this will likely cause render errors.
Does anyone know how to accomplish that?
Thanks in advance
Slot names have to be unique. If you want to create slots inside a loop, you can add a number to the slot name, e.g.:
<div v-for="num in nums" :key="num">
<slot :name="'foo_' + num"></slot>
</div>
And then use them like this:
<foo-component :nums="3">
<template slot="foo_1">
<span>Inside the foo component slot 1</span>
</template>
<template slot="foo_2">
<span>Inside the foo component slot 2</span>
</template>
<template slot="foo_3">
<span>Inside the foo component slot 3</span>
</template>
</foo-component>

AngularJS hide element if empty

I need a way to hide a parent element if the element inside of it is empty using AngularJS.
Would this be a custom directive type issue or is there a way to put the logic into something like ng-show or ng-hide?
<div class="item"> <!-- item should be hidden -->
<div class="inside"></div>
</div>
I would assume the inside div would have some data from the scope displayed? If the data is an empty string of null, then you can check that with ng-hide in the parent. Something like the below perhaps?
<div ng-hide='myData == null' class="item"> <!-- item should be hidden -->
<div class="inside">{{myData}}</div>
</div>

Polymer equivalent to ng-show?

Is the a polymer equivalent for ng-show? Here's a snippet example of what I'm trying to convert:
<h1>Greeting</h1>
<div ng-show="authenticated">
<p>The ID is {{controller.greeting.id}}</p>
<p>The content is {{controller.greeting.content}}</p>
</div>
<div ng-show="!authenticated">
<p>Login to see your greeting</p>
</div>
dom-if is not necessary here. Simply use $= (attribute binding) to add/remove hidden attribute.
<style>
[hidden] {
display:none;
}
</style>
<h1>Greeting</h1>
<div hidden$=[[!authenticated]]>
<p>The ID is {{controller.greeting.id}}</p>
<p>The content is {{controller.greeting.content}}</p>
</div>
<div hidden$=[[authenticated]]>
<p>Login to see your greeting</p>
</div>
Use dom-if to make decisions about blocks of code that you don't want to be rendered, not just hidden.
I guess you could use dom-if to conditionally keep required HTML in DOM tree. properties should be defined there in properties of component.
<template is="dom-if" if="{{authenticated}}">
<p>The ID is {{controller.greeting.id}}</p>
<p>The content is {{controller.greeting.content}}</p>
</template>
<template is="dom-if" if="{{!authenticated}}">
<p>Login to see your greeting</p>
</template>
True and False will work once you add template with in template. I tried
<template>
<template is="dom-if" if="{{authenticated}}">
{{authenticated}}
<p>The ID is {{controller.greeting.id}}</p>
<p>The content is {{controller.greeting.content}}</p>
</template>
<template is="dom-if" if="{{!authenticated}}">
{{authenticated}}
<p>Login to see your greeting</p>
</template>
</template>
If you will not add template with in template True, false will never work. It will always show you the first template wheather you have True or False value of properties.
Hope it works.

Element transclusion

Is there something like angularjs directive's transclude attribute in polymer? Something what allows me to include some elements to a specific place in template?
I would like to achieve something like following:
<my-header title="My title">
<my-header-item name="Item 1"></my-header-item>
<my-header-item name="Item 2"></my-header-item>
</my-header>
which might be expressed:
<h1>My title</h1> <!-- "My title" given by my-header's title attribute -->
<ul>
<li>Item 1 <!-- given by my-header-item -->
<li>Item 2
</ul>
I am not sure if this is a task for polymer or if this is a typical way to use polymer. I am asking, because I started to like polymer and I would like to keep idiomatic thinking.
In Shadow DOM land, this is called distribution. To distribute light DOM nodes into the shadow dom, you use <content> insertion points.
http://www.polymer-project.org/platform/shadow-dom.html#shadow-dom-subtrees
It's quite literally a way to render nodes from light dom into placeholders in the shadow dom.
If you want to do tricky things with the my-header/my-header-item title/name attributes, you can do something like this:
<polymer-element name="my-header">
<template>
<ul>
<template repeat="{{item in items}}">
<li>{{item.name}}</li>
</template>
</ul>
<content id="c" select="my-header-item"></content>
</template>
<script>
Polymer('my-header', {
domReady: function() {
this.items = [].slice.call(this.$.c.getDistributedNodes());
}
});
</script>
</polymer-element>
Demo: http://jsbin.com/hupuwoma/1/edit
I have a more full-fledged tabs demo does this setup over on https://github.com/ebidel/polymer-experiments/blob/master/polymer-and-angular/together/elements/wc-tabs.html.
While admittedly I'm also new to polymer - I think I can answer this.
You should be able to substitute the value of an attribute into the template using the double-mustache syntax e.g.
<h1>{{title}}</h1>
See http://www.polymer-project.org/docs/start/creatingelements.html#publishing
In addition to this you can also substitute the content of a tag. For example if instead of using the "name" attribute in your my-header-item tag you instead had something like this...
<my-header-item>Item 1</my-header-item>
then you could substitute "Item 1" like this:
<li><content></content></li>
See http://www.polymer-project.org/platform/shadow-dom.html for this usage

ng-if without breaking stylesheet?

Is there a way to use an ng-if directive without adding a containing element? I'm playing around with dynamic menu items placed by the current view controller and want to handle a dropdown type and non dropdown type, however the ng-if has to be in some kind of element which breaks the bootstrap css.
Here's an example of what I'm trying to do:
<li ng-repeat="item in dynNavList">
<div ng-if="item.dd" ><!--There will be more stuff in here-->
Dropdown test {{item.title}}
</div>
<span ng-if="!item.dd">
NoDropDown {{item.title}}
</span>
</li>
Any nav item created in that html above doesn't style correctly in the navbar because it's inside a div or span element so the css doesn't apply.
I do not want to modify the bootstrap css to get this working and I'm trying to avoid writing any custom directives if possible.
Any suggestions?
ng-if directly on the anchor is fine, demo.

Resources