onclick attribute is not being registered - html

const googleDiv = function(){
const container = document.createElement('div');
const btnEle = document.createElement('button');
btnEle.type = "button";
btnEle.className = "link-btn";
btnEle.appendChild(document.createTextNode("(Unlink)"));
btnEle.onclick = "unlinkGoogle()";
container.appendChild(btnEle);
container.id = "google-linked-container";
return container;
};
When I create a button via this method, the button appears in the DOM no problem and the button type and classes are as expected, but there is no onclick attribute. Why?
P.S.
btnEle.addEventListener("click", () => { console.log("clicked!"); }); doesn't work either.
Update
I have replicated it on JSFiddle: https://jsfiddle.net/fs1xhgnm/2/

You should assign your handler as a function, instead of string. Also, try to assign onclick handler after the element is appended.
container.appendChild(btnEle);
btnEle.onclick = unlinkGoogle;

You need to pass a reference to the function, either with the onclick, or the better addEventListener
const googleDiv = function() {
const container = document.createElement('div');
const btnEle = document.createElement('button');
btnEle.type = "button";
btnEle.className = "link-btn";
btnEle.appendChild(document.createTextNode("(Unlink)"));
btnEle.addEventListener('click', unlinkGoogle);
container.appendChild(btnEle);
container.id = "google-linked-container";
return container;
};
function unlinkGoogle() {
console.log('clicked');
}
document.body.appendChild(googleDiv());

You are assigning a string as the function. You can use addEventListener.
Here is a JSFiddle to explain what I mean.

Related

Can not stub private element in WCT

Using Polymer 1 and Web component tester... testing in shady dom on chrome.
In WCT, trying to stub spToast.display() with stub('sp-toast', { display: ()=> {} }); but I get error with Attempted to wrap undefined property display as function.... what I am doing wrong?
The reason why I am trying to stub it is because I get spToast.display is not a function when the test runs the code base.
original code:
showAgeWarning: function() {
var spApp = Polymer.dom(document).querySelector('sp-app');
var spToast = Polymer.dom(spApp.root).querySelector('sp-toast');
var msg = "foo"
spToast.display('information', msg);
},
test code:
<test-fixture id="sp-veteran">
<template>
<h2>edit veteran</h2>
<sp-app>
<sp-toast></sp-toast>
<sp-veteran>
</sp-veteran>
</sp-app>
</template>
</test-fixture>
setup(function() {
replace('sp-app').with('fake-sp-app');
replace('sp-ajax').with('fake-sp-ajax');
stub('sp-value-dropdown', { setInvalidState: (state)=> {} });
myEl = fixture('sp-veteran');
});
test('it should validate the veteran', function() {
var spApp = Polymer.dom(myEl.root).querySelector('sp-app');
var spToast = Polymer.dom(spApp.root).querySelector('sp-toast');
sinon.stub(spToast, 'display');
When you get Attempted to wrap undefined property display as function it means that it can't replace a method that doesn't exist (yet).
If you actually get a value for var spToast = Polymer.dom(spApp.root).querySelector('sp-toast') in your test, and nothing about your test is going to give display a value, you could just set it, a la spToast.display = function() {}; then you should be able to set a spy on it or what have you as needed.
Put it all together and you could have
test('it should validate the veteran', function() {
var spApp = Polymer.dom(myEl.root).querySelector('sp-app');
var spToast = Polymer.dom(spApp.root).querySelector('sp-toast');
spToast.display = function() {};
sinon.spy(spToast, 'display');
// Trigger the side effect that would lead to `display` being called
assert.equal(
spToast.display.calledOnces,
true
);
});

Html in AngulaJS does not change when I test with an alias controller

I have a problem in AngularJS, to test a html div with a dynamic value when I use controller's alias
Here my code
<div id="title_contract" class="caption">{{ ctrl.detail_title }}</div>
where crtl is the ContractController's alias.
My test is
describe('Testing create new or open detail contract', function() {
var template, ctrl, scope;
beforeEach(inject(function ($controller, $compile) {
scope = $rootScope.$new();
ctrl = $controller('ContractController', {$scope: scope});
var element = angular.element('<div id="title_contract" class="caption">{{ ctrl.detail_title }}</div>');
template = $compile(element)(scope);
}));
it('should prepare variable to create new contract', function () {
ctrl.create_clicked();
scope.$digest();
var templateAsHtml = template.html();
expect(templateAsHtml).toContain('New Contract');
});
}
MyController is
PageApp.controller('ContractController', function($rootScope, $scope ) {
var vm = this;
vm.create_clicked = doCreate;
vm.title_detail = '';
function doCreate() {
vm.detail_title = 'New Contract';
}});
When I call create_clicked the title in vm change its value but test fails 'cos the div value is empty.
I try to use $scope (so without alias) and it works.
But I'd like to use alias approach.
Did somebody encounter this problem?
Thanks' in advance
Try:
ctrl = $controller('ContractController as ctrl', {$scope: scope});
See $controller documentation:
The string can use the controller as property syntax

Activating dynamic button

I have created a dynamic button. and now I,m trying to add a dynamic anchor tag. But it doesn't work. Before posting this I went through all the other example, but no success. Please advice.
<script>
$(document).ready(function(){
//creating an dynamic button element
var btn = document.createElement('input');
var text = document.createTextNode('Click Me!')
btn.appendChild(text);
btn.id = "myBtn"
btn.type = "button";
btn.value="Click me!"
document.body.appendChild(btn)
//adding click event to the dynamic button
$("body").on("click", "myBtn", function(){
var myLink = document.createElement('a')
var myText = document.createTextNode('This is a dynamic link')
myLink.setAttribute("href", "http://www.example.com");
myLink.target = "_blank"
myLink.title = "www.example.com"
myLink.style.marginTop = "25px"
myLink.appendChild(myText);
document.body.appendChild(myLink);
})
})
</script>
$(document).on('click','#myBtn',function(){
//write your function here
});

can't apply style to a button on it's click event

I have created a button dynamically in HTML5 + Javascript. I have assigned a click event to that button. When i clicked it, it's content & background color should change. Content is changing fine, but bgcolor is not changing.
my code is;
<style>
.selectBtn{ height:60px;width:80px;background-color:yellow; }
</style>
<script>
var container = document.getElementById('abc');
function dx(){
var Btn = document.createElement('button');
Btn.type = 'button';
Btn.className = 'selectBtn';
Btn.innerHTML = 'SUBMIT';
container.appendChild(Btn);
Btn.onclick = function()
{
this.innerHTML='voted';
this.style.backgroundColor:'blue';
}
dx();
</script>
<body><div id='abc'></div></body>
Use = instead of colon. Use this:-
this.style.backgroundColor = "#f47121";
You will wan't to change some things
var container = document.getElementById('abc');
function dx(){
var Btn = document.createElement('button');
Btn.className = 'selectBtn';
Btn.innerHTML = 'SUBMIT';
container.appendChild(Btn);
Btn.onclick = function() {
this.innerHTML='voted';
this.style.backgroundColor = 'blue';
}
}
I'm not sure if Btn.type = 'button'; is valid but it sure is pointless
and on the style you want to change : to = you only use : in objects
Also you might wan't to use textContent instead of innerHTML
I could not resist to show how I would have done this, just for fun, and its educational purposes.
window.onload = function(){
(function(){
var doc = document;
var get = function(id){return doc.getElementById(id);};
var inject = function(el,str){el.innerHTML = str;return el;};
inject(get('content'),'<button type="button" id="btn-select">SUBMIT</button>');
get('btn-select').onclick = function(){inject(this,'Voted!').className = 'voted';};
})();
};
DEMO: http://jsfiddle.net/ZNfBe/

mootools variable scope

how to access outer function's argument 'parent' ??? please see comments in code
!!last edit : This question is misleading, my problem is caused by wrong input argument
renderData : function(parent, children){
children.each(function(e, index){
var li = new Element('li');
var hasChildren = false;
if(e.children && e.children.length >0){
var img = new Element('img');
img.src = 'a1.png';
img.inject(li);
hasChildren = true;
}
if(e.icon){
var img = new Element('img');
img.src = e.icon;
img.inject(li);
}else{
var img = new Element('img');
img.src = 'b1.png';
img.inject(li);
}
li.set('html',e.text);
console.log(this);
// how to access outer function's argument 'parent' ???
li.inject(parent);
if(hasChildren){
var ul = new Element('ul');
this.renderData(ul, e.childRen);
ul.inject(e);
}
}.bind(this));
within an each loop:
array.each(function(el) {
this.method(); // this == (instance / scope)
}, this); // where **this** is your parent scope.
another acceptable way is:
var self = this;
...
array.each(function(el) {
self.method(); // fine.
}); // where this is your parent scope.
http://mootools.net/docs/core/Types/Array#Array:Array-each
although, using .bind(this) should work too... http://www.jsfiddle.net/dimitar/fFy4J/ - so what is the problem?
if i understood correctly, your problem is that you cant do li.inject(parent)
there's no reason why you can't access 'parent' since it's been passed as a parameter to the function renderData()
I've tried this simple test
var test;
window.addEvent('domready', function(){
test = new TestClass();
});
var TestClass = new Class({
Implements: [Options, Events],
initialize: function(){
this.renderData($('parent'),$$('span'))
},
renderData : function(parent, children){
children.each(function(e, index){
console.log(parent);
}.bind(this));
}
});
and it works fine... but i'm no really sure what's the problem on your code