JavaScript Namespaces + Setter - javascript

Well, I'm using object orientation in JavaScript, but instead of using new, I just call the method from the namespace. In the moment, I have the following code:
var Component = {
Button: function(_text, use_image) {
button = $.createElement('button')
if (use_image != false)
{
button.innerHTML = _text;
}
else
{
button.innerHTML = _text
}
var text = _text
return button
}
}
When I want to return a button, I do:
x = Component.Button("Click me")
And after I can use x. But if I want to change the text of x, I must use x.textContent. I'd like to instantiate this and use a setter to apply its text, this way:
x = new Component.Button("Click me")
x.text = "Don't click me"
document.getElementsByTagName("body")[0].appendChild(x)
And if I try to apply the setter text, it becomes global, I want to have a unique for each button. Mix namespaces with get/set.
Thank you in advance

One way can be like, I am not sure if this is the best approach. Looking for more answers
var Component = {
Button: function(_text, use_image) {
var button = {
node : document.createElement('button'),
setText : function(txt){this.node.innerHTML = txt;}
};
if(_text){button.setText(_text);}
return button;
}
};
x = Component.Button("Click me");
x.setText("Don't click me");
document.getElementsByTagName("body")[0].appendChild(x.node);
y = Component.Button("Click me2");
y.setText("Don't click me2");
document.getElementsByTagName("body")[0].appendChild(y.node);
http://jsfiddle.net/2LCyn/

How about something like this:
var Component = (function($){
var buttonCount = 0;
function Button(text, use_image){
this.id = ++buttonCount;
this.text = text;
this.use_image = use_image;
this.$element = $('<button/>').text(text);
this.bindEvents();
}
Button.prototype.bindEvents = function(){
var that = this;
this.$element.on('click', function(){
console.log('hello, I\'m button ' + that.id);
});
};
Button.prototype.setText = function(text){
this.text = text;
this.$element.text(text);
};
return {
Button: Button
}
})(jQuery);
var button1 = new Component.Button('hello', false);
button1.setText('helloooo');
$('body').append(button1.$element);
var button2 = new Component.Button('world', true);
$('body').append(button2.$element);
http://jsfiddle.net/ATmAx/1/

Related

onclick excecutes does not work, only when creating DOM

I have the following HTML and javascript.
I can create the buttons without any problem, but the onclick function does not work when clicking the button. It does not do anything.
If I put the method without the ' it excecutes when generating the form, one after the other generating 3 dialogs
function makeUL(array) {
var list = document.createElement('ul');
for (var i = 0; i < array.length; i++) {
var btn = document.createElement("BUTTON");
/*
btn.onClick = function () {
buttonClicked(array[i]);
};*/
var t = document.createTextNode(array[i]); // Create a text node
btn.appendChild(t); // Append the text to <button>
btn.type = "button"
btn.onClick = 'buttonClicked()';
list.appendChild(btn); // Append <button> to <body>
var nextLine = document.createElement("td");
list.appendChild(nextLine);
}
return list;
}
/*
function buttonClicked(buttonName){
alert(buttonName);
}*/
function buttonClicked() {
alert("algo");
}
self.onInit = function() {
var boton = [];
for (var g = 0; g < self.ctx.settings.Botones.length; g++) {
boton[0] = self.ctx.settings.Botones[g].btnId;
boton[1] = self.ctx.settings.Botones[g].method;
boton[2] = self.ctx.settings.Botones[g].params;
document.getElementById('myList').appendChild(makeUL(boton));
}
self.ctx.$scope.sendCommand = function() {
var timeout = self.ctx.settings.requestTimeout;
var rpcMethod = self.ctx.settings.method;
var rpcParams = self.ctx.settings.params;
var commandPromise;
commandPromise = self.ctx.controlApi.sendTwoWayCommand(rpcMethod, rpcParams, timeout);
commandPromise.then(
function success(response) {
//alert("Comando recibido exitosamente\n Respuesta:" + angular.toJson(response));
alert("Comando recibido exitosamente");
},
function fail(rejection) {
alert("ERROR AL ENVIAR COMANDO");
}
);
};
};
<form name="rpcForm">
<md-content class="md-padding" layout="column">
<div id="myList"></div>
</md-content>
</form>
The problem is:
btn.onClick = 'buttonClicked()';
It looks like you were trying to assign to the onclick attribute of the HTML, in which case the proper syntax would be
btn.setAttribute('onclick', 'buttonClicked()');
But since you already have a reference to the element, there's no need to resort to attributes; inline handlers are pretty bad practice anyway. Change to:
btn.onclick = buttonClicked;
(note the lower-case c in onclick), or
btn.addEventListener('click', buttonClicked);
Also, you might consider simply assigning to the button's textContent rather than creating a text node explicitly, it's a bit easier to read and write: change
var t = document.createTextNode(array[i]); // Create a text node
btn.appendChild(t); // Append the text to <button>
to
btn.textContent = array[i];

dynamically create element with onclick

I'm obviously missing something, but I haven't been able to find what I am doing wrong and I have been staring at this for entirely too long
function message(options) {
...
options.onclose = options.onclose || null;
...
this.gui = document.createElement('div');
this.msg = document.createElement('div');
...
if (options.onclose != null) {
var close = document.createElement('i');
close.innerHTML = 'close';
close.className = 'material-icons close';
close.onclick = options.onclose;
console.log(close.onclick);
this.msg.append(close);
}
this.msg.innerHTML += options.msg;
this.gui.append(this.msg);
...
return this.gui;
}
msgContainer.append(new message({
class: 'update',
sticky: true,
icon: 'mic',
msg: 'You are in a call',
onclose: () => { console.log('click'); }
}));
from the developer console document.querySelector('.close').onclick is null, but if I add an on click document.querySelector('.close').onclick = () => { console.log('click'); }; it works?
Why it wont work is because on click is a function:
document.querySelector('.close').onclick
doesn't do anything so why call it.
document.querySelector('.close').onclick = () {
alert("did something");
}
so the real question is what do you want to do when clicked? create a new link or div.. look below. I would start using jQuery.
jQuery answer:
$(document).ready(function(){
$(".myclass").click(function(){
$(".container_div").append("<a href='test.php'>test link</a>");
// also .prepend, .html are good too
});
});
Here is working example. I changed your code a little bit. You can add more events by passing it to an array. I used addEventListener.
var msgContainer = document.getElementById('msgContainer');
function message(options) {
options.onclose = options.onclose || null;
this.gui = document.createElement('div');
this.msg = document.createElement('div');
if (options.onclose != null) {
var close = document.createElement('i');
close.innerHTML = 'closepp';
close.className = 'material-icons close';
close.dataset.action = 'close';
this.msg.append(close);
}
this.msg.innerHTML += options.msg;
this.gui.append(this.msg);
// Create listeners dynamically later on
events = [
{ selector: close.dataset.action, eventType: 'click', event: options.onclose }
];
renderElement(this.gui, events);
}
function renderElement(element, events) {
msgContainer.append(element);
for (i = 0; i < events.length; i++) {
var currentEvent = events[i];
var selector = element.querySelector('[data-action="' + currentEvent['selector'] + '"]');
selector.addEventListener(currentEvent['eventType'], currentEvent['event'].bind(this), false);
}
}
new message({
class: 'update',
sticky: true,
icon: 'mic',
msg: 'You are in a call',
onclose: () => { console.log('click'); }
});
<div id="msgContainer">
</div>
I finally figured it out! setting innerHTML makes chrome rebuild the dom and in the process it loses the onclick event, onclick works fine if I use textContent instead of innerHTML. In the below example if you comment out the last line of JS the onclick works, here's the same thing in jsFiddle
var blah = document.getElementById('blah');
var div = document.createElement('button');
div.style['background-color'] = 'black';
div.style.padding = '20px;';
div.style.innerHTML = 'a';
div.onclick = () => { alert('wtf');};
blah.appendChild(div);
// Uncomment this to make onclick stop working
blah.innerHTML += ' this is the culprit';
<div id="blah">
</div>

Javascript onclick event starts when reloading page

I wanted to create a Button via JavaScript through a constructor. Everything works fine, but the onclick event starts immediately after loading the page and not after clicking the button.
function Button(text) {
this.button = document.createElement('button');
this.button.id = text;
this.button.innerHTML = text;
this.button.style.width = 100;
this.button.style.height = 30;
document.body.appendChild(this.button);
};
b1 = new Button('button1');
b1.onclick = alert('hello');
It will start on load, because you call it explicitly with alert('hello').
Better "wrap" it:
b1.onclick = function() {
alert('hello')
}
This way you assign a function to b1.onclick event, and this function will be invoked on button click.
When you say b1.onclick = alert("hello");, it thinks that you want whatever the alert() function returns to go into b1.onclick, so it will run the function and find out. What you want is this:
b1.onclick = function(){
alert("hello");
};
This is an actual function object that will be called when b1 is clicked.
In your code you were calling alert, and asigning it's return value to b1.onclick.
function Button(text) {
this.button = document.createElement('button');
this.button.id = text;
this.button.innerHTML = text;
this.button.style.width = 100;
this.button.style.height = 30;
document.body.appendChild(this.button);
};
b1 = new Button('button1');
b1.onclick = function() {
//Handle click here
alert("hello");
};
b1.onclick should be a function.

Copy/Paste element with jQuery

I have a div that I'm appending to another div when a button is clicked. I'm also calling a bunch of functions on the div that gets created.
HTML
<a onClick="drawRect();">Rect</a>
JS
function drawRect(){
var elemRect = document.createElement('div');
elemRect.className = 'elem elemRect';
elemRect.style.position = "absolute";
elemRect.style.background = "#ecf0f1";
elemRect.style.width = "100%";
elemRect.style.height = "100%";
elemRect.style.opacity = "100";
renderUIObject(elemRect);
$('.elemContainer').draggableParent();
$('.elemContainer').resizableParent();
makeDeselectable();
handleDblClick();
}
var createDefaultElement = function() {
..
..
};
var handleDblClick = function() {
..
..
};
var renderUIObject = function(object) {
..
..
};
var makeDeselectable = function() {
..
..
};
I could clone the element when the browser detects a keydown event
$(window).keydown(function(e) {
if (e.keyCode == 77) {
$('.ui-selected').clone();
return false;
}
});
then append it to #canvas. But the problem is, none of the functions I mentioned above get called with this method.
How can I copy/paste an element (by pressing CMD+C then CMD+V) and call those above functions on the cloned element?
The jQuery.clone method returns the cloned node. So you could adjust your code to do something like this:
var myNodes = $('.ui-selected').clone();
myNodes.each(function () {
createDefaultElement(this);
appendResizeHandles(this);
appendOutline(this);
});

trying to remove and store and object with detach()

I am trying to remove an object and store it (in case a user wants to retrieve it later). I have tried storing the object in a variable like it says in the thread below:
How to I undo .detach()?
But the detach() does not remove the element from the DOM or store it. I am also not getting any error messages. Here is the code I am using to detach the element:
function MMtoggle(IDnum) {
var rowID = "row" + IDnum;
var jRow = '#' + rowID;
thisMMbtn = $(jRow).find(".addMMbtn");
var light = false;
var that = this;
if (light == false) {
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
$(this).unbind("click");
light = true;
}
);
}
else {
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
thisMM = thisRow.find(".mmCell");
SC[rowID].rcbin = thisMM.detach(); //here is where I detach the div and store it in an object
$(this).unbind("click");
light = false;
}
);
}
}
MMtoggle(g.num);
A fiddle of the problem is here: http://jsfiddle.net/pScJc/
(the button that detaches is the '+' button on the right. It is supposed to add a div and then detach it when clicked again.)
Looking at your code I don't think so you need detach for what you are trying to achieve.
Instead try this code.
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var $mmCell = thisTxt.find('.mmCell');
if($mmCell.length == 0){
$mmCell = $('<div class = "mmCell prep"></div>')
.appendTo(thisTxt).hide();
}
$mmCell.toggle();
//$(this).unbind("click");
}
);
Demo

Categories

Resources