Polymer: Where exactly do I put my Javascript for an Element? - javascript

I have trouble loading Javascript in normal Polymer Elements:
Here is the test code that works perfectly fine, when executed without polymer:
<body>
<style>
#content {background-color: #f2f2f2;}
#button {padding: 10px 20px;}
</style>
<div id="content">
<h1 id="title">Title</h1>
<p>This example uses the addEventListener() method to attach a click event to the document.</p>
<button id="button">Testbutton</button>
</div>
<script>
function popup2() {
alert("What's up brow?");
console.log("deine mudda");
};
var button = document.getElementById("button");
button.addEventListener("click", popup2, false);
</script>
</script>
</body>
But I want to use Javascript inside Polymer Elements and have tried the following insertions:
Nr. 1: Javascript inside the script tag, after the template tag:
<polymer-element name="my-element">
<template>
<style>
#content {background-color: #f2f2f2;}
#button {padding: 10px 20px;}
</style>
<div id="content">
<h1 id="title">Title</h1>
<p>This example uses the addEventListener() method to attach a click event to the document.</p>
<button id="button">Testbutton</button>
</div>
</template>
<script>
Polymer('my-element', {
popup: function() {
alert('What the... dude?');
},
var button = document.getElementById("button");
button.addEventListener("click", popup, false);
});
</script>
</polymer-element>
And this doesn't work. I get the error message in firefox: "SyntaxError: missing : after property id.
Chrome instead says: "SyntaxError: Unexpected Identifier".
Both poin to the line "var button = document.getelementById("button");
According to the Polymer Documentation, javascript should just be placed at the end of the file:
https://www.polymer-project.org/docs/start/tutorial/step-1.html
So in a second attempt, I place my Javascript directly inside the template tags like this:
<polymer-element name="my-element">
<template>
<style>
#content {background-color: #f2f2f2;}
#button {padding: 10px 20px;}
</style>
<div id="content">
<h1 id="title">Title</h1>
<p>This example uses the addEventListener() method to attach a click event to the document.</p>
<button id="button">Testbutton</button>
</div>
<script>
function popup() {
alert("jajaja");
};
var button = document.getElementById("button");
button.addEventListener("click", popup, false);
</script>
</template>
<script>
Polymer('my-element', {
});
</script>
</polymer-element>
But this time I get: "Uncaught TypeError: Cannot read property 'addEventListener' of null", which points agian to the line where I write: "button.addEventListener("click", popup, false);".
I guess this means, that the compiler can't see the button id, because it is in the Shadow-Dom?
Please instruct me.

<polymer-element name="my-element">
<template>
<style>
#content {background-color: #f2f2f2;}
#button {padding: 10px 20px;}
</style>
<div id="content">
<h1 id="title">Title</h1>
<p>This example uses the addEventListener() method to attach a click event to the document.</p>
<button on-tap="{{popup}}">Testbutton</button>
</div>
</template>
<script>
Polymer('my-element', {
popup: function() {
alert('alert');
}
});
</script>
</polymer-element>
inside a polymer element you can bind directly to a function by using on-tap="{{function}}" attribute.
edited: all code didn't get into block
keeping eventlisteners in the js method
<polymer-element name="my-element">
<template>
<style>
#content {background-color: #f2f2f2;}
#button {padding: 10px 20px;}
</style>
<div id="content">
<h1 id="title">Title</h1>
<p>This example uses the addEventListener() method to attach a click event to the document.</p>
<button id="button">Testbutton</button>
</div>
</template>
<script>
Polymer('my-element', {
ready: function () {
var button = this.$.button;
button.addEventListener("click", function () {
alert('alert');
});
}
});
</script>
</polymer-element>
edited again: OP wanted to keep html separate from JS
edited 1 more time: i think using a anonymous function is the easiest way to go here if not using the declarative method. code edited

script tag goes between closing template tag and closing polymer element tag or before the element definition but in this case when you call Polymer('my-element') you need to include tag name
Here is the example above with external js file, you can do the same with css
<polymer-element name="my-element">
<template>
<link rel="stylesheet" href="my-element.css">
<div id="content">
<h1 id="title">Title</h1>
<p>This example uses the addEventListener() method to attach a click event to the document.</p>
<button id="button">Testbutton</button>
</div>
</template>
<script src="my-element/my-element.js"></script>
</polymer-element>
The folder name and js file name can be whatever you want but I think good practices you would structure like this
File Folder Structure
-myelements -folder
--my-first-element -folder
--my-first-element.html
--my-first-element.css
--my-first-element.js
--my-second-element -folder
--my-second-element.html
--my-second-element.css
--my-second-element.js
<polymer-element name="ouch-button">
<template>
<button on-click="{{onClick}}">Send hurt</button>
</template>
<script>
Polymer({
onClick: function() {
alert('ouch', {msg: 'That hurt!'}); // fire(type, detail, targetNode, bubbles?, cancelable?)
}
});
</script>
</polymer-element>
<ouch-button></ouch-button>

Related

How can I get rid of onclick in my js code, any alternative?

How can I execute the following js function inside js instead of using a button with it? Also, can it be achieved without jQuery?
The function is myFunction()
The button is:
<button onclick="myFunction()">Toggle dark mode</button>
The full code is:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
padding: 25px;
background-color: white;
color: black;
font-size: 25px;
}
.dark-mode {
background-color: black;
color: white;
}
</style>
</head>
<body>
<h2>Toggle Dark/Light Mode</h2>
<p>Click the button to toggle between dark and light mode for this page.</p>
<button onclick="myFunction()">Toggle dark mode</button>
<script>
function myFunction() {
var element = document.body;
element.classList.toggle("dark-mode");
}
</script>
</body>
</html>
Also, instead of using a button, use a span with a css pointer settle.
So basically I'm trying to achieve something like this:
HTML:
<span id="mybutton">Toggle nightmode</span>
JS:
<script>
function myFunction.getElementbyID(#mybutton).(click) {
var element = document.body;
element.classList.toggle("dark-mode");
}
</script>
It's ok if you offer a solution in jQuery, but I prefer vanilla javascript.
There are quite a few ways to achieve this, the shortest way would just be to do:
document.getElementById('mybutton').onclick = () => { /* CODE GOES HERE */ };
If your function is already defined somewhere, you can replace the lambda function (This ()=>{} thingy) with the name of your function, leaving you with this:
document.getElementById('mybutton').onclick = myFunction;
However, all that does is set the onlcick property of your element programatically, rather than setting it inline. If you want your element to not have the onclick property at all, you need to set an event listener for that element. This can be done like so:
document.getElementById('mybutton').addEventListener('click', () => {
/* CODE GOES HERE */
});
Once again, that lambda function can be swapped out for the name of your function if its already defined somewhere else.
tldr your script element should look like:
<script>
document.getElementById('mybutton').addEventListener('click', () => {
var element = document.body;
element.classList.toggle("dark-mode");
});
</script>

getElementById in Polymer element

How can I use getElementById in a Polymer custom element?
Here is my element:
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../styles/shared-styles.html">
<dom-module id="bb-calendar">
<template>
<style is="custom-style" include="shared-styles"></style>
<div class="card">
<paper-toolbar>
<div title>Calendar</div>
</paper-toolbar>
<div id="hideme">
<div>this should be hidden</div>
</div>
</div>
</template>
<script>
Polymer({
is: 'bb-calendar',
ready: function() {
document.getElementById("hideme").style.display = 'none';
}
});
</script>
</dom-module>
When I run the code I get this error message: Uncaught TypeError: Cannot read property 'style' of null
Obviously I'm doing something wrong but I don't know what.
I'd use
ready: function() {
this.$.hideme.style.display = 'none';
}
of when the element is inside <template dom-if...> or <template dom-repeat...>
ready: function() {
this.$$('#hideme').style.display = 'none';
}
In the end, I'd use class binding and bind a class to the element and update a property to reflect that change and use CSS to set style.display
<template>
<style>
.hidden { display:none; }
</style>
...
<div class$="{{hiddenClass}}">
<div>this should be hidden</div>
</div>
Polymer({
is: 'bb-calendar',
properties: {
hiddenClass: String,
},
ready: function() {
this.hiddenClass = 'hidden';
}
});
Your problem is actually that your element is not attached to the document DOM when the ready callback is fired. For simply showing/hiding an element you may use the hidden attribute like this: <div hidden$="{{!shouldShow}}">

Failure to edit div on nav click event

So I typed up most of the pertinent information into the code itself
I would love a explanation of whats happening and why, especially between the multiple outcomes of .text .html and not returning what i want
<DOCTYPE! Html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<style>
p{color: white;
background: black;}
</style>
<script>
$('document').ready(function() {
$(document).on('click', '.nav', function() {
document.getElementById('text').innerHTML=$(this).html;
});
});
</script>
</head>
<body>
This is a test html to trouble shoot the functionality of the script, the above script runs and does what it needs to in other aspects but when trying to add in the ability to edit a divs text based on the nav clicked on theres a error.
when using ".text" in the script i get <p> function (a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)} </p> in my div,when i use ".html" in my script i get <p> function (a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)} </p>
<ul id="nav">
<li class="nav"> This is the text that should be placed in the div </li>
</ul>
<div id="text"> this text should be changed </div>
</body>
</html>
The jQuery method .html() is a function you need to call it / use (). Or go vanilla and just do this.innerHTML.
That means:
$(document).on('click', '.nav', function() {
document.getElementById('text').innerHTML = this.innerHTML;
});
Example in the snippet:
$('document').ready(function() {
$(document).on('click', '.nav', function() {
document.getElementById('text').innerHTML=this.innerHTML;
});
});
p{color: white;
background: black;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This is a test html to trouble shoot the functionality of the script, the above script runs and does what it needs to in other aspects but when trying to add in the ability to edit a divs text based on the nav clicked on theres a error.
when using ".text" in the script i get <p> function (a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)} </p> in my div,when i use ".html" in my script i get <p> function (a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)} </p>
<ul id="nav">
<li class="nav"> This is the text that should be placed in the div </li>
</ul>
<div id="text"> this text should be changed </div>
Something like this:
$(document).ready(function () {
$(".nav").on('click', function() {
$("#text").html( $(this).html() ); // Getting too nested here
}
}

jQuery/CSS - Change IFRAME Height when click on button inside the iframe content

I'm working on a simple HTML/jQuery script.
Right now when i click on the button which is inside the iframe it is changing the iframe's height that is calling the content with the button.
Take a look at the code:
<div id="outerdiv" style="padding:20px;border:2px solid red;">
<iframe src="http://beta.sportsdirect.bg/test/iframe.php" id="inneriframe" scrolling="no" target="_parent"></iframe>
</div>
Here is the iframe.php content:
<HTML>
<head>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
</head>
<div style="display:block;height:300px;">
<h3>The iframe content</h3>
<button type="button" id="SuperWebF1">Click me to resize the holding Iframe!</button>
</div>
<script type="text/javascript">
$("#SuperWebF1").click(function(){
$('#inneriframe', window.parent.document).animate({height:'900px'}, 500);
})
</script>
The problem is coming when i try to add this:
<style>
#outerdiv
{
width:400px;
height:300px;
overflow:hidden;
position:relative;
border:2px solid #fff;
}
#inneriframe
{
position:absolute;
width:400px;
height:700px;
border:0px;
}
</style>
<div id="outerdiv" style="padding:20px;border:2px solid red;">
<iframe src="http://beta.sportsdirect.bg/test/iframe.php" id="inneriframe" scrolling="no" target="_parent"></iframe>
</div>
As you can see i've added a <style> tag where i added CSS for the elements outerdiv and the iframe inerriframe and now when i click on the button it's not chaning the iframe's height.
When i remove the <style>....</style> tags and all the content inside them the script is starting to work again.
Here is the demo: http://beta.sportsdirect.bg/test/
This is the working demo when i have not added the <style></style> tags.
Can you help me set up the CSS for these elements and make the jQuery script works as well ?
Thanks in advance!
The event will not trigger it's function when the document is not fully loaded inside the iframe page.
Instead of:
<script type="text/javascript">
$("#SuperWebF1").click(function(){
$('#inneriframe', window.parent.document).animate({height:'900px'}, 500);
});
</script>
Use:
<script type="text/javascript">
$(document).ready(function(){
$("#SuperWebF1").on('click',function(){
$('#inneriframe', window.parent.document).animate({height:'900px'}, 500);
});
});
</script>
For it to listen to the click event when all the .css,.js and whole documents in the page are completely ready.
I hope this will help?

jQuery slideToggle more than one panel

Im a complete noob when it comes to JavaScript and jQuery but here we go.
I want to make a slidetoggle that shows 3 slides, 3 "snowboardtricks" when i press "toggle".
As it is now only one "trick" is shown when i press toggle, the rest is already there from the beginning.
<html>
<head>
<script src="jquery-1.10.2.min.js"></script>
<script>
$(document).ready(function()
{
$("#flip").click(function()
{
$("#panel,#panel2,#panel3").slideToggle("slow");
});
});
</script>
<style type="text/css">
#panel,#panel2,#panel3,#flip
{
padding:1px;
text-align:left;
color:white;
background-color:black;
border:solid 1px yellow;
}
#panel
{
padding:5px;
display:none;
}
</style>
</head>
<body>
<div id="flip">Toggle</div>
<div id="panel">Switch back 1080 double cork</div>
<div id="panel2">Frontside triple cork 1440</div>
<div id="panel3">Ollie</div>
</body>
</html>
If I'm understanding correctly, on page load you only want to display "Toggle". When you click "Toggle" you want to show the three other sections.
To do that you want to place the three other sections inside of a wrapper div, and then use slide toggle on the wrapper div instead.
Quick jsfiddle: http://jsfiddle.net/43byX/
Here is a modified version of your code:
<html>
<head>
<script src="jquery-1.10.2.min.js"></script>
<script>
$(document).ready(function() {
$("#toggle").click(function() {
$("#drawer").slideToggle("slow");
});
});
</script>
<style type="text/css">
#toggle,
.panel {
padding:1px;
text-align:left;
color:white;
background-color:black;
border:solid 1px yellow;
}
#drawer {
padding:5px;
display:none;
}
</style>
</head>
<body>
<div id="toggle">Toggle Me</div>
<div id="drawer">
<div class="panel">Switch back 1080 double cork</div>
<div class="panel">Frontside triple cork 1440</div>
<div class="panel">Ollie</div>
</div>
</body>
</html>
#panel, #panel2, #panel3
{
padding:5px;
display:none;
}
You are in essence hiding only the div whose id is panel. But the other two div's are visible. Those need to be hidden as well. This way when you toggle all three will have their displays turned to true.
On a side note is there a reason you are creating your own toggle? It might be faster to use twitter bootstrap which already comes with it. See This
Correct me if I'm wrong, but it seems what you're trying to do can be more easily accomplished using accordion.
Quick jFiddle example here. Click the headers to see the effects.
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script>
$(function() {
$( "#flip" ).accordion({
collapsible: true,
active: false
});
});
</script>
</head>
You can erase the active code if you want one of the panes to be open when the page loads, and you can erase the collapsible line if you want one of the panes to always remain open.
and then the html layout:
<div id="flip">
<h3>Switch back 1080 double cork</h3>
<div><p>some text or whatevs here</p></div>
<h3>Frontside triple cork 1440</h3>
<div><p>some text or whatevs here</p></div>
<h3>Ollie</h3>
<div><p>some text or whatevs here</p></div>
</div>
Read more about accordion here.
Edit: It may be better to put the
<script>
$(function() {
$( "#flip" ).accordion({
collapsible: true,
active: false
});
});
</script>
just before the closing body tag instead of in the header. Best practices would have you put it in a separate file and link it in the header.
I think, you want to toggle that one hidden element one by one. Well, If I am not wrong, then here is the code:
$("#flip").click(function(){
var targets = $("#panel, #panel2, #panel3"),
hiddenElm = targets.filter(":hidden");
hiddenElm.slideDown();
if(hiddenElm.next().length){
hiddenElm.next().slideUp();
} else {
targets.first().slideUp();
}
});
Working jsfiddle: http://jsfiddle.net/ashishanexpert/jg2wg/

Categories

Resources