Pass DOM nodes to Polymer as attributes - javascript

Ok, so I'm defining a polymer object like this:
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="my-element" attributes="content">
<template>
<div class="someclass">
{{content}}
</div>
</template>
<script>
Polymer({});
</script>
</polymer-element>
Which works fine if I instantiate it as:
<my-element content="test"></my-element>
However, I'd like to be able to pass HTML inside the element. If I do this:
<my-element content="<div>test</div>"></my-element>
The HTML is not added to the DOM, but displayed as text. Is it possible to pass HTML inside a polymer element? Or am I doing something completely wrong here?
Thanks for any help!

Here's some hackish code I made that may answer your question.
http://jsbin.com/hedutu/edit?html,output
Basically, I created an observer for an attribute that accepts DOMs in string format and then inserted that dom into a local dom node.

Related

How do you activate alpinejs?

I'm trying to add AlpineJS to a very simple html page that I'm working on and the package is being executed (from cdn) but it doesn't seem to get activated correctly. Even on this small snippet of HTML, it doesn't work:
<html>
<head>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js" defer></script>
</head>
<body>
<h1 x-show="false">hide me</h1> <!-- doesn't work-->
</body>
<script type="text/javascript">
console.log($el); //undefined
</script>
</html>
This is also loaded into a codepen where the problem can be observed: https://codepen.io/dwarburt/pen/gOgZyeR
I'm sure I've just missed a step, but what could it be? AlpineJS is executing its initialization routines, you can tell from the debugger.
To initialise an AlpineJs component you'll need an x-data attribute on the parent container:
<div x-data="{
isShowing: false
}">
<h1 x-show="isShowing">I am hidden</h1>
</div>
This contains an object with properties and functions you can use within the component instance.
It's definitely worth reading through the docs in the repo here: https://github.com/alpinejs/alpine#use
I have adjusted your example in order to achieve the result you require, along with an additional example so you can see how multiple object properties can exist and used within your Alpine.js components.
x-data does not need to be initiated on the body tag, however nested components will retrieve the object property from the closest x-data property match.
You can access from child nodes of nested x-data objects the properties.
Careful of your property naming conventions if you don't wish to overwrite proceeding object properties.
I would also suggest reading Build a Drop Down along with Toggle Element
Reading these points will be helpful in understanding the below example in further detail.
<html>
<head>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js" defer></script>
</head>
<body x-data="{show: false, button: 'Toggle'}">
<button #click="show = ! show" x-text="button"></button>
<span x-show="show">
<h1 #click.outside="show = false">hide me</h1> <!-- doesn't work-->
</span>
</body>
</html>

How to use intro.js with Polymer 2?

I want to use intro.js for first-time user experience in my Polymer 2 application. Below is the code how I'm trying to use but it's not working out for me.
<base href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<script src="intro.js/minified/intro.min.js"></script>
<link rel="import" type="css" href="intro.js/minified/introjs.min.css">
<dom-module id="my-app">
<template>
<style>
</style>
<p class="line1" data-intro='Hello step one!' data-step="1">Line 1</p>
<p class="line2" data-intro='Hello step two!' data-step="2">Line 2</p>
<p class="line3" data-intro='Hello step three!' data-step="3">Line 3</p>
<p class="line4" data-intro='Hello step four!' data-step="4">Line 4</p>
</template>
</dom-module>
connectedCallback(){
super.connectedCallback();
introJs().start();
}
Here's the Codepen for the same. Since, intro.js is not a polymer web component so, I'm not able to figure out how to use it with Polymer 2.
It won't work as you have it right now
Asides
If you are importing external styles into a polymer element, you need to use style-modules Read here , henceforth, preferably.
The link rel=import type=css is deprecated, but If you still want to use them, they should be placed inside your dom-module for polymer to shim it.
intro.js , can not be scoped to your polymer element. JS is scoped via IIFE's and you might have to code a wrapper to do that yourself for any external scripts
That is if you strictly want everything scoped.
Regarding Your question
The problem is, that intro.js, can not access DOM inside your element.
Hence, it can not reach any of your P tags
One solution, is to move / distribute them to an outer scope like the document itself, by using slots
<dom-module id="my-app">
<template>
<!-- uncomment this, if you have a style module pointing to intro'scss only-->
<!--<style include="intro-css"></style>-->
<slot>
</slot>
</template>
</dom-module>
Now, all you need to do is, place all your DOM inside the tags <my-app></my-app>
Only then will intro.js work on them. plunker

How to access root element's text in Polymer?

I'm writing an Polymer element that's supposed to be used like this:
<x-elem>Some text</x-elem>
The element would transform the text content. But when I try to access it in attached callback, it's empty:
attached: function() {
var text = this.root.textContent;
console.log(text); // Outputs ''
}
Frankly, the number of all child nodes is 0:
attached: function() {
console.log(this.root.childNodes.length); // Outputs 0
}
According to these docs I would think that at least my attempt at getting child nodes is correct, but apparently I do something wrong here. Perhaps I need to put something in my template (right now it's simple <template></template>, but it is not clear what.
this.root provides access to the element's local DOM (i.e., the DOM locally declared in the <dom-module>'s template), but you're trying to access light DOM (i.e., the DOM passed in). Use Polymer.dom(this).textContent for that:
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo',
attached: function() {
console.log('textContent:', Polymer.dom(this).textContent);
}
});
});
<head>
<base href="https://polygit.org/polymer+1.7.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<x-foo>hello world</x-foo>
<dom-module id="x-foo">
<template>
</template>
</dom-module>
</body>

How to attach an HTML element or a DocumentFragment to the DOM?

I’ve got an HTML fragment like <p>Hello, World!</p> and want to attach it to the container HTML page that includes
<script src="lib/kotlin.js"></script>
<script src="my-app.js"></script>
There are two package that came to my mind:
kotlin.js.dom.html.window.document.*
kotlin.browser.document.*
Which should I use and how do I access the document’s root? I’ve already tried document.getElementById("container") whereby container is the id of a DIV. But this returns null. I also tried document.appendChild(node)...
Also which of the above packages should I prefer?
I just figured out that the JS output of the compiled app needs to be below the element that is referenced inside the app.
I’ve created a demo case that illustrates this:
<!DOCTYPE html>
<meta charset="utf-8"/>
<script src="lib/kotlin.js"></script>
<p>Look inside the JavaScript Console of your browser…</p>
<div id="container"></div>
<script>
console.log("Native JavaScript");
</script>
<!-- This script tag was misplaced. It needs to be placed after all elements you want to access in your DOM -->
<script src="kotlin-javascript-hello-world.js"></script>

Transclusion property in angular js

I am learning angularjs.I got stucked in the tranclusion property as it confused me.How ng-transclude works? Will it replace the content inside the dom marked with ng-transclude with transcluded element(the element to be transcluded) or simply append the transcluded element to the dom marked with ng-transclude?
I referred egghead angularjs video tutorial for transclusion property
https://egghead.io/lessons/angularjs-transclusion-basics
There It was mentioned that ng-transclude simply appends the transcluded element to the dom marked with ng-transclude.But when I tried this,it is not so
Here is my html file
learning.hmtl
<html ng-app="learnangular">
<head>
<title></title>
<script type="text/javascript" src="angular.js"></script>
<script type="text/javascript" src="learnscript.js"></script>
</head>
<body>
<div ng-controller="firstcontroller">
<custom-directive><div>This is transcluded part</div></custom-directive>
</div>
</body>
</html>
and here is my script file
learnscript.js
var app=angular.module("learnangular",[]);
app.controller("firstcontroller",function($scope){
$scope.dirobject="directive object";
});
app.directive("customDirective",function(){
return {
restrict:"E",
transclude:true,
replace:false,
template:"<input type='text' ng-model='dirobject'></input>"+
"<div ng-transclude>{{dirobject}}</div>",
link:function(scope,element,attr){
}
};
});
ng-transclude replaces the content inside the dom marked with ng-transclude.why is it so?
I have understood now.The video was recorded with angular js version 1.0.x and the version I am using is the latest one. Actually,the transcluded markup completely replaces the contents of the element with the ng-transclude attribute in latest versions. In previous versions, the transcluded markup would be appended.Thanks everyone

Categories

Resources