Split the value of input to array of characters - javascript

I want to get the value of the input on click then split the returned value into an array of characters, that what i've already tried :
window.onload = function() {
var textonaut = {
text: '',
letters: []
};
textonaut.text = document.getElementById('textonaut-text').value;
var go = document.getElementById('go-button');
go.addEventListener('click', function(e) {
e.preventDefault();
textonaut.letters = textonaut.text.split('');
for(var i = 0; i < textonaut.letters.length; i++) {
console.log(textonaut.letters[i]);
};
});
}
<input id="textonaut-text" type="text"><button id="go-button">go</button>
I can't figure out why this doesn't work.

Put textonaut.text = document.getElementById('textonaut-text').value; inside your addEventListener callback. Then it should work.
window.onload = function() {
var textonaut = {
text: '',
letters: []
};
var go = document.getElementById('go-button');
go.addEventListener('click', function(e) {
e.preventDefault();
textonaut.text = document.getElementById('textonaut-text').value;
textonaut.letters = textonaut.text.split('');
for(var i = 0; i < textonaut.letters.length; i++) {
console.log(textonaut.letters[i]);
};
});
}
<input id="textonaut-text" type="text"><button id="go-button">go</button>
If you set the value of textonaut.text outside the callback, it will remain as '' no matter what happens (this value is set when the JS file loads).
The callback function of the addEventListener is triggered at every click on the button. It means that at every click, the value textonaut.text is set at everything's inside your input.
Read addEventListener documentation for more information.

You should get the input value after the click not before, so put the line :
textonaut.text = document.getElementById('textonaut-text').value;
Inside the callback.
NOTE : As written now in your OP the document.getElementById('textonaut-text').value will always return an empty string "".
window.onload = function() {
var textonaut = {
text: '',
letters: []
};
var go = document.getElementById('go-button');
go.addEventListener('click', function(e) {
e.preventDefault();
textonaut.text = document.getElementById('textonaut-text').value;
textonaut.letters = textonaut.text.split('');
for(var i = 0; i < textonaut.letters.length; i++) {
console.log(textonaut.letters[i]);
};
});
}
<input id="textonaut-text" type="text"><button id="go-button">go</button>

Related

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>

Dynamically create buttons in js/html based on object state

I have the following situation which I cannot solve. I am relatively new to js. I have a js that runs on a webpage. The script runs when a KB shortcut is pressed. After modifying a few things, it pops up an html banner in which I want to put certain messages and buttons depending on what thing the user ran a script on. For a simple case, let's say there are two potential messages that can go in this popup. I have the details in an object array:
NH_Bann = {
STC: {
active: false,
bannText: "Force Title Case: ",
id: "toTitleCaseStrong",
value: "Yes",
action: function() {
var newNameStr = toTitleCaseStrong(vname);
if (newNameStr !== name) {
//**update function
NH_Bann.STC.active = false;
}
}
},
DTC: {
active: false,
bannText: "Enable DTC? ",
id: "addDTC",
value: "Yes",
action: function() {
//**update function
NH_Bann.DTC.active = false;
}
}
}
When the script is run, there are some if statments that can change the active keys to true. After the script runs, I want to run through the objects in NH_Bann, and if the active key is true, make a message with an action button that fires the action button. The part I am having trouble with is making the buttons dynamically. From other threads, I thought I could store the buttons in an array, but maybe the onclick doesn't work that way? This is what I have:
function setupButtons() {
var ixButt = 0;
var btn = [];
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++ ) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
btn[ixButt] = document.getElementById(NH_Bann[tempKey].id);
btn[ixButt].onclick = function(){
NH_Bann[tempKey].action();
assembleBanner(); // makes the html for the banner
}
ixButt++;
}
}
}
I make the buttons in another piece of code which sets up the ids:
function assembleBanner() {
sidebarMessageEXT = [sidebarMessage.slice(0)];
var EXTOption = false;
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++ ) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
sidebarMessageEXT.push(NH_Bann[tempKey].bannText + '<input id="' + NH_Bann[tempKey].id + '" type="button" value="' + NH_Bann[tempKey].value + '">');
EXTOption = true;
}
}
if (EXTOption) {
sidebarMessageEXT = sidebarMessageEXT.join("<li>");
displayBanners(sidebarMessageEXT,severity);
setupButtons();
} else {
displayBanners(sidebarMessage,severity);
setupButtons();
}
}
The issue i'm having is that I get the two distinct messages and two buttons in the banner if both objects are active==true, but pressing them always fires the update function of the DTC object. Any suggestions? I'm open to other methods, but I need to be able to add to the object list over time and have the buttons be displayed conditionally on the status of the active key for each object. Thx!
The problem has to do with closures. In this code:
function setupButtons() {
var ixButt = 0;
var btn = [];
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++ ) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
btn[ixButt] = document.getElementById(NH_Bann[tempKey].id);
btn[ixButt].onclick = function(){
NH_Bann[tempKey].action();
assembleBanner(); // makes the html for the banner
}
ixButt++;
}
}
}
...tempKey is a variable that lives within the call to setupButtons. Notice that you're creating two onclick function callbacks in a loop, and both make reference to tempKey. However, they're not going to be referencing the variable's value at the time of function creation, but rather the latest value of the variable. So once the loop completes, tempKey is going to reference the last value it had.
To work around this, you can use this trick to create a new closure for each onclick that will have the correct value:
function setupButtons() {
var ixButt = 0;
var btn = [];
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++ ) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
btn[ixButt] = document.getElementById(NH_Bann[tempKey].id);
btn[ixButt].onclick = (function(buttonId) {
return function() {
NH_Bann[buttonId].action();
assembleBanner(); // makes the html for the banner
}
})(tempKey);
ixButt++;
}
}
}
Essentially, this is binding the current value of tempKey to a new variable by passing it to an immediately-executing function, so both onclick functions no longer reference the variable which changes during the loop.
For a less esoteric way to do this, you could move the creation of each button into its own named function, passing the required data:
function setupButtons() {
var btn = [];
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
btn.push(setupButton(NH_Bann[tempKey]);
}
}
}
function setupButton(bannerData) {
var button = document.getElementById(bannerData.id);
button.onclick = function() {
bannerData.action();
assembleBanner();
};
return button;
}

Changing text inside of a dynamically created element

I want to change the text inside of an element for dynamically created elements. i = 2 because that's Why is it not working?
var loanName = function() {
for(var t=1; t < i; t++) {
$('body').on('keyup', '.loanNameV'+t, function () {
var loanN = $('.loanNameV'+t).val();
$('.nameLoan'+t).text(loanN);
});
}
};
$('body').on('keyup', '[class^="loanNameV"]', function () {
var numbesideclass = ($(this).attr('class').split('loanNameV'))[1];
var loanN = $(this).val();
$('.nameLoan'+numbesideclass).text(loanN);
});
Note: this code will work if you don't have another class for loanNameV elements like class="loanNameV1 anotherclass anotherclass" in this case this code will not work as expected

Javascript click event callback not working

I am using javascript to handle click event.
The code is below :
function addClickEventListenerToAllAnchorTag() {
var anchors = document.getElementsByTagName("a");
for(var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
var guid = anchor.attributes.getNamedItem('GUID');
if(guid)
{
anchor.addEventListener("click", onClickLoginPopup);
}
}
}
Here I am fetching all anchor tags that has GUID attribute and adding click event listener to it.
But my callback function onClickLoginPopup never gets called.
function onClickLoginPopup(e) {
console.log('onClickLoginPopup');
e.preventDefault();
var host = window.location.hostname;
var url = this.href;
var guid = this.attributes.getNamedItem("GUID");
var mainPopup = document.getElementById('popupMain');
var popupPayment = document.getElementById('popupPayment');
if( mainPopup == null ) {
console.log(mainPopup);
}
else if(userID)
{
showSocialLoginPopup();
return false;
}
if(popupPayment !== null){
showPaymentPopup();
}
//articleLinkClickAction(guid);
return false;
}
Calling Code:
function mpwInit() {
addPopupContents();
addClickEventListenerToAllAnchorTag();
}
includeScripts();
window.onload = mpwInit;
When are you calling addClickEventListenerToAllAnchorTag function ? Have you logged the list of selected anchor elements ? Is it an empty array ? If it is an empty array then you JavaScript code is getting executed before the page loads.

Access javascript object attribute in dynamically generated handler function

I have the following Javascript file, where some html is generated dynamically:
(function ($){
NunoEstradaViwer: {
settings: {
total: 0,
format: "",
num: 0;
},
init: function (el, options) {
if (!el.length) { return false; }
this.options = $.extend({}, this.settings, options);
this.itemIndex =0;
this.container = el;
this.total = this.options.total;
this.format = ".svg";
this.num = 0;
this.generateHtml(el);
},
generateHtml: function(container){
var bnext = document.createElement('input');
bnext.setAttribute("type", "button");
bnext.setAttribute("id", "bnext");
bnext.onclick = this.nextImage();
bnext.setAttribute("value", "Next");
container.appendChild(bnext);
},
nextImage: function(){
this.num++;
}
});
What I wanted to do was to access the NunoEstradaViwer attribute num inside the nextImage function but instead the this object points to the bnext button.
Do you know how I can manage that?
check the link
bnext.onclick = this.nextImage; // not bnext.onclick = this.nextImage();
another thing is
NunoEstradaViwer.num++ ; // instead of this.num++
#rahen, I tried your sugestions but unfortunately none worked.
What I found out that worked for me was a solution envolving jquery. I did the following:
generateHtml: function(container){
var bnext = document.createElement('input');
bnext.setAttribute("type", "button");
bnext.setAttribute("id", "bnext");
bnext.setAttribute("value", "Next");
container.appendChild(bnext);
$("#bnext").bind('click',{viewer: this}, function(event) {
event.data.viewer.nextImage();
});
},
nextImage: function(){
this.num++;
}
And this way I can access the value of num and it is changed for the NunoEstradaViwer.

Categories

Resources