I have a Polymer <paper-collapse-item> inside a <div> inside another <div>. When the <paper-collapse-item> is opened, I want to change add another class to the <div class="container">. But Polymer tells me the function is undefined. Right now I have:
HTML:
<div class="container>
<h1>Header</h1>
<div class="box" onclick="[[_expandBox()]]">
<paper-collapse-item class="header" header="">
<p class="longText">Some long text</p>
</paper-collapse-item>
</div>
</div>
Script:
<script>
Polymer({
is: 'text-page',
_expandBox: function() {
var exp = this.getElementsByClassName("header")[0];
var expPar = this.getElementsByClassName("box")[0].parentNode;
if (exp.hasAttribute(opened)) {
expPar.className += " paropen";
}
}
});
</script>
So how I can I call the function properly and make it add a class to the container?
EDIT
I've made some changes to the entire setup for different reasons. Still left with this issue.
HTML:
<div class="container>
<h1>Header</h1>
<collapse-item opened="{{opened}}" on-tap="_expandBox(opened)"></collapse-item>
</div>
Script:
<script>
Polymer({
is: 'text-page',
_expandBox: function(opened) {
var exp = this.getElementsByClassName("container")[0];
if (opened) {
exp.className += " paropen";
}
}
});
</script>
This tells me that: listener method _expandBox(opened) not defined
Thanks for helping me learn. I'm new to Polymer.
Following Polymer Documentation, you have to write "on-" followed by gesture event type. You have to remove brackets within event handler too. In your case:
<div class="box" on-click="_expandBox">
EDIT:
On on-tap event declaration you must to add a listener, in this case on-tap="_expandBox" (without parameters). When the event tap occurs, an event object is passed automatically to the function as the first parameter:
_expandBox: function(event) {
console.log(event.detail);
}
Your code could be:
HTML:
<div class="container>
<h1>Header</h1>
<collapse-item id="collapseItem" on-tap="_expandBox" opened="[[_functionWithParamsThatChangesThis(param1, param2, ...)]]"></collapse-item>
</div>
Script:
<script>
Polymer({
is: 'text-page',
_expandBox: function() {
var exp = this.getElementsByClassName("container")[0];
if (this.$.collapseItem.opened) {
exp.className += " paropen";
}
}
_functionWithParamsThatChangesThis(param1, param2, ...) {
if (param1, param2, ...) return true;
return false;
}
});
</script>
Related
I want to make a Javascript function where it reads the class of the selected element and adds the class active. How can I get the class of the HTML element where my function is?
I tried to make an Javascript function with document.getElementsByClassName(class), but that doesn't work.
function menuicon(){
var className = $('div').attr('class');
className.$(className).addClass("active");
}
<section class="menubar">
<div class="menuicon" onclick="classAdd()">
<span></span>
<span></span>
<span></span>
</div>
</section>
<section class="home">
<button class="hbutton" onclick="classAdd()"></button>
</section>
I want that the Javascript function reads out the class of the HTML element where the function is placed in.
You need to pass the element to the function:
onclick="classAdd(this)"
Then in the function, you just use .addClass, you don't need to use className.
function classAdd(element) {
$(element).addClass("active");
}
This code snippet only include 'active' in the classList of the div
var classAdd = function() {
var menuIcon = document.querySelector('div.menuicon');
menuIcon.addEventListener('click',() => {
menuIcon.classList.add('active');
});
}
If encase you want to stick with the div and the menuicon class.
Below code will work fine for you.
function classAdd() {
$("div.menuicon").attr("class", "menuicon active");
}
I want to execute a function when I'm clicking on elements in the dom with a specific class. It just doesn't work, but I'm also receiving any error. This is my
code snippet:
methods: {
initTab: function(){
document.querySelectorAll('.element').onclick = this.nextTab()
}
},
mounted: function () {
this.initTab()
}
I
I want to execute the function every time I click on the element. Would be very thankful if anybody could help me :)
There's very little need (if at all) for document.querySelectorAll() in a Vue app.
In this situation you can take advantage of delegation:
<div #click="onClick">
<!-- Clicks on any element inside this div will be handled -->
</div>
methods: {
onClick(e) {
if (e.target.classList.contains('element')) {
// Handle the click
}
}
}
Add #click="initTab($event)" to the document or template root, that allows you to track every click event on your template, that way you could put your logic to the elements which have only .element class name. If you're using it in a component you could do : <template> <div #click="initTab($event)"> ... </div> </template>
var app = new Vue({
el: '#app',
data() {
return {
}
},
methods: {
nextTab(){
console.log("You clicked on an element with class name =element")
},
initTab(event){
let targetClassNames=event.target.className.split(" ");
targetClassNames.filter(e=>{
if(e==="element"){
this.nextTab();
}
});
}
},
mounted() {
}
})
#app{
height:100px;
display:grid
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<div id="app" #click="initTab($event)">
<button class="element">1</button>
<button class="element btn">2</button>
<button class="btn">3</button>
<button class="element btn-primary">4</button>
<button class="btn elementory">5</button>
</div>
You're trying to use general javascript logic within vue. This is not often a good idea.
What I do in such cases is something like this:
<component-name #click="nextTab(tabName)"></component-name>
However, in a v-for loop you can also do something like this:
<ul v-for="tab in tabs">
<li #click="nextTab(tab)">{{tab}}</li>
</ul>
That way in methods you only need:
methods: {
nextTab: function(tab){
// whatever it is you want to do here
}
},
And you won't need mounted at all.
Conclusion: try to avoid repetition by creating components or elements (like li) that repeat - not by trying to add an event-listener to a class.
I have a div that would need to pop-up when an outside button is pressed.
div id="Screen5" class="grid-item modalBox" data-bind="style: { display: Display() }"
Display is a computed observable in the script updated when a subscriber function updates and observable.
self.Screen5Visible = ko.observable(false);
self.Display = ko.computed(function () {
if (self.Screen5Visible() == false) {
alert("here1");
return 'none';
} else {
alert("here2");
return 'block';
}
});
Screen5shouter.subscribe(function (newValue) {
alert("subscriber" + newValue);
self.Screen5Visible(newValue);
}, self, "change");
self.Hide = function() {
self.Screen5Visible(false);
};
The Screen5shouter successfully gets true when called from outside viewmodel. I get to "here2" and supposedly return 'block' with computable. However the binding does not seem to work like this.
Regular javascript would work with getElementId. Also the hide function, which is data-bound on an image in div successfully updates the Display() binding, the div does recieve a 'none' value.
Thank you for help.
So I got a working example for you using the visible binding. Hopefully this will help you achieve what you initially intended.
function Screen5 () {
this.Screen5Visible = ko.observable(false);
var self = this
this.show = function () {
self.Screen5Visible(true)
}
this.hide = function() {
self.Screen5Visible(false);
}
}
ko.applyBindings(Screen5)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div id="Screen5" class="grid-item modalBox" data-bind="visible: Screen5Visible">
screen 5
</div>
<div id="Screen6" class="grid-item modalBox">
screen 6
</div>
<button data-bind="click: show">
Show Screen 5
</button>
<button data-bind="click: hide">
Hide Screen 5
</button>
I think your problem is with the display: Display() and more specifically the Display(). Knockout is evaluating the function on render and then it is done with it. It is no longer an observable from that point onward. I believe that it needs to be display: Display for knockout to subscribe to the Display property to have the effect that you are looking for.
From
<div id="Screen5" class="grid-item modalBox" data-bind="style: { display: Display() }"></div>
To
<div id="Screen5" class="grid-item modalBox" data-bind="style: { display: Display}"></div>
I an trying a simple test about observeNodes Polymer facility. Essentially my code defines an observer for child node changes on the component.
<dom-module id="wc-A">
<template>
<div>Added Nodes : <span id="added"></span></div>
<div>Removed Nodes : <span id="removed"></span></div>
</template>
<script>
Polymer ({
is: 'wc-A',
ready: function () {
Polymer
.dom (this)
.observeNodes (function (nodes) {
console.log (nodes)
this.$.added.textContent = nodes.addedNodes.length;
this.$.removed.textContent = nodes.removedNodes.length;
});
}
});
</script>
</dom-module>
This example works properly on creation time (from my test span#added contains 5 and span#removed contains 0), but when I programmatically add/remove elements on the light DOM, the observation mechanism does not respond (span's do not change). This is my test:
<div>
<button id="btnAdd">New</button>
<button id="btnRemove">Remove</button>
</div>
<wc-A> <!-- (1) Fires observer -->
<div class="data">1</div>
<div class="data">2</div>
</wc-A>
<template id=template>
<div class="data">3</div>
</template>
<script>
HTMLImports.whenReady (function () {
document
.querySelector ('#btnAdd')
.addEventListener ('click', function (e) {
var template = document.querySelector ('#template').content;
var div = template.querySelector ('div');
var wcA = document.querySelector ('wc-A')
wcA.appendChild (div.cloneNode (true)); // (2) Does not fire observer
});
document
.querySelector ('#btnRemove')
.addEventListener ('click', function (e) {
var wcA = document.querySelector ('wc-A')
var child = wcA.querySelector ('.data');
if (child)
wcA.removeChild ( // (3) Does not fire observer
child
);
});
});
</script>
The complete code can be checked http://plnkr.co/edit/DHiH40T3pBLx9Nu6Tv3W?p=preview
What is my error? Thanks in advance.
You need to use Polymer.dom(this).appendChild instead of this.appendChild to make it work with Polymer 1.0 according to this:
https://github.com/Polymer/polymer/issues/3102
I am trying to do an onclick event where when a light bulb image is clicked it goes from a light bulb off to a light bulb on image and vice versa.
I am using an external javascript file. when I click on the image nothing happens.
I cant figure out whats wrong,
my html portion:
<head>
<link rel="stylesheet" href="css/program-01.css" />
<script type="text/javascript" src="javascript/program-01.js"></script>
<title>
<h1>Program-01</h1>
</title>
</head>
<body>
<div id="LightOff">
<img src="images/light_off.png" id="light_off" alt="" onclick="LightBulbFunction()" />
</div>
</body>
my js file function:
function LightBulb() {
var image_change = document.getElementById("light_off");
if (image_change.src == "images/light_off.png") {
image_change = "images/light_on.png";
} else {
image_change = "images/light_off.png";
}
}
Suggestions/Problems:
You function names are different.
You're using the function LightBulbFunction on the onclick event. But, you don't have the function of that name in your script. You'll get
ReferenceError: LightBulbFunction() is not defined.
To change the image src attribute value, use image_change.src inside the event handler.
To solve the problem change the name of onclick attribute value to LightBulb.
function LightBulb() {
var image_change = document.getElementById("light_off");
if (image_change.src == "images/light_off.png") {
image_change.src = "images/light_on.png";
// ^^^^
} else {
image_change.src = "images/light_off.png";
// ^^^^
}
}
<div id="LightOff">
<img src="images/light_off.png" id="light_off" alt="" onclick="LightBulb()" />
<!-- ^^^^^^^^^^^ -->
</div>
Better approach will be to use addEventListener to bind events on the elements.
document.getElementById('light_off').addEventListener('click', function() {
var image_change = document.getElementById("light_off");
if (image_change.src == "images/light_off.png") {
image_change.src = "images/light_on.png";
} else {
image_change.src = "images/light_off.png";
}
}, false);
<div id="LightOff">
<img src="images/light_off.png" id="light_off" alt="" onclick="LightBulb()" />
<!-- ^^^^^^^^^^^ -->
</div>
Well in your html, the code is onclick="LightBulbFunction()" while in javascript it is LightBulb. Change either of them and make them match
You are not redefining the .src. Change
image_change =
to
image_change.src =
And your function needs to have the same LightBulb function name.