Explain why function won't execute when button clicked - javascript

I can't get the button within the signIn function to execute on the onclick event. I need help understanding what I am doing wrong and what needs to be done to fix it. I am building a simple silly app to learn javascript/typescript. The other buttons earlier in the app work and I am able to transform the DOM but the button built within the signin function doesn't seem to fire and execute the isValid function. I have no errors within the web console. I am completely stumped as to why the button will not execute the isValid function.
var App = /** #class */ (function () {
function App() {
this.init();
}
App.prototype.init = function () {
if (!window['WebSocket']) {
console.log("BROWSER NOT SUPPORTED");
document.body.innerHTML = "BROWSER NOT SUPPORTED";
}
document.documentElement.style.background = "green";
document.title = "App";
var sin = document.createElement("button");
sin.id = "sin";
sin.innerHTML = "SIGN IN";
sin.onclick = this.signIn;
var sup = document.createElement("button");
sup.id = "signup";
sup.innerHTML = "SIGN UP";
sup.onclick = this.signUp;
var landing = document.createElement("div");
landing.id = "landing";
landing.style.position = "absolute";
landing.style.left = "50%";
landing.style.top = "50%";
landing.style.transform = "translate(-50%,-50%)";
landing.appendChild(sin);
landing.appendChild(sup);
document.body.appendChild(landing);
};
App.prototype.signIn = function () {
document.body.removeChild(document.getElementById("landing"));
var user = document.createElement("input");
user.type = "text";
user.id = "username";
user.placeholder = " username";
user.style.border = "1px solid";
user.style.width = "150px";
var pass = document.createElement("input");
pass.type = "password";
pass.id = "password";
pass.placeholder = " password";
pass.style.border = "1px solid";
pass.style.width = "150px";
var okay = document.createElement("button");
okay.innerHTML = "Sign in";
//I can't get the isValid function to execute.
okay.onclick = this.isValid;
var signin = document.createElement("div");
signin.id = "signin";
signin.style.position = "absolute";
signin.style.left = "50%";
signin.style.top = "50%";
signin.style.transform = "translate(-50%,-50%)";
signin.appendChild(user);
signin.appendChild(document.createElement("br"));
signin.appendChild(pass);
signin.appendChild(document.createElement("br"));
signin.appendChild(okay);
document.body.appendChild(signin);
};
App.prototype.signUp = function () {
alert("alert!");
};
App.prototype.isValid = function () {
alert("alert!");
};
return App;
}());
window.onload = function () {
var app = new App();
};

This is a classic scoping problem.
When the okay button is added, this is not pointing where you thinking it is pointing.
You assumed this would be referring to the App function. But the okay button is not created by the App function, is it created by the sin button. And that's why this, in that location, points to the sin button, and since there no isValid function in the sin button, you don't get the alert you wanted.
To fix this you can change this.isValid to App.prototype.isValid.
// from this
okay.onclick = this.isValid;
// to this
okay.onclick = App.prototype.isValid;
This will get the desired behavior.

Related

How to use localStorage to cache button result?

I have a button that I am making completely out of JS.
I want to save whether it was in a true or false state so that if a user leaves the page the button will be in the same state when they return. I'd like to use localStorage but I'm relatively new to JS so they may be a better solution.
Current Code:
var btn;
var btn = document.createElement("BUTTON");
btn.onclick = function() {myFunction()};
btn.style.height = "100%";
btn.style.width = "98%";
btn.style.border = "0px";
btn.innerHTML = "CLICK ME";
btn.id = "toggle";
document.getElementById("button").appendChild(btn);
function myFunction() {
document.getElementById('notepad').classList.toggle('hide'); return false
}
Edit Code:
window.onload = function initBt(){
var buttonState = localStorage.getItem('mybutton');
if ( null !== buttonState )
{
buttonState && document.getElementById('notepad').classList.add('hide');
}
}
var btn;
var btn = document.createElement("BUTTON");
btn.onclick = function() {myFunction()};
btn.style.height = "100%";
btn.style.width = "98%";
btn.style.border = "0px";
btn.innerHTML = "CLICK ME";
btn.id = "toggle";
document.getElementById("button").appendChild(btn);
function myFunction() {
var bt = document.getElementById('notepad');
bt.classList.toggle('hide');
localStorage.setItem('mybutton', bt.classList.contains('hide'))
return false;
}
you can use following functions in youir code to store and retrieve the button state:
localStorage documentation
function store(key, data)
{
localStorage.setItem(key, JSON.stringify(data));
}
function retrieve(key)
{
var data = localStorage.getItem(key);
return data ? JSON.parse(data) : null;
}
function remove(key)
{
localStorage.removeItem(key);
}
usage examples:
store('mybutton', buttonState);
var buttonState = retrieve('mybutton');
if ( buttonState !== null )
{
/* set button State*/
}
else
{
/* state has not been saved before, initialise */
}
NOTE since localStorage can handle ONLY string values, we use JSON.stringify when saving to make a string out of data and JSON.parse when retrieving in order to store and retrieve arbitrary data (that are of course JSON valid structures)
For your updated question try the following (it would be more helpfull if the whole html structure was added since some elements are missing, but anyway):
// include the needed localStorage manipulation methods
function store(key, data)
{
localStorage.setItem(key, JSON.stringify(data));
}
function retrieve(key)
{
var data = localStorage.getItem(key);
return data ? JSON.parse(data) : null;
}
function remove(key)
{
localStorage.removeItem(key);
}
// create and initialise the button
var btn = document.createElement("BUTTON");
btn.onclick = function() {myFunction()};
btn.style.height = "100%";
btn.style.width = "98%";
btn.style.border = "0px";
btn.innerHTML = "CLICK ME";
btn.id = "toggle";
document.getElementById("button").appendChild(btn);
var buttonState = retrieve('mybutton');
// make sure at this point element with id="notepad" exists on page
if ( null !== buttonState )
{
buttonState && document.getElementById('notepad').classList.add('hide');
}
function myFunction() {
var bt = document.getElementById('notepad');
bt.classList.toggle('hide');
store('mybutton', bt.classList.contains('hide'));
return false;
}
For a flexible caching library for web/browser that can support a variety of storage mechanisms (and also support for server-side php and node.js) check Unicache (ps. I am the author)
There are of course other libraries as well (eg localForage)

JavaScript - How to know which object has been clicked

I have a basic film search, now I'm trying to make it so that once you click on a film, it gets just that clicked films title property, at the moment it is bringing every film from the list of films that match the search term.
How do I go about finding out which film has been clicked and ONLY pass this objects properties through instead of every object? Do I need to use a loop?
screenshots added, e.g if I click the first film "John Wick" it creates a h1 title for every film title that has "John Wick"
function search() {
var userInput = $("#content-container-search").val().replace(/\s+/g,"%20");
var searchTerm = "".concat(standardURL, apiKey, 'query=', userInput);
var request = new XMLHttpRequest();
clear(); //runs the clear function to clear existing DOM results to make way for the new ones
request.open('GET', searchTerm , true);
request.onload = function(data) {
var data = JSON.parse(this.response);
createList(data);
}
request.send();
}
function createList(data){
var app = document.getElementById("film-results");
data.results.forEach(film => {
console.log(film.title);
var filmInfo = film;
var Filmcontainer = document.createElement("div");
Filmcontainer.setAttribute("class", "row film-container");
var filmContainerLeftPanel = document.createElement("div");
filmContainerLeftPanel.setAttribute("class", "film-container-left-panel column small-3");
var filmContainerRightPanel = document.createElement("div");
filmContainerRightPanel.setAttribute("class", "film-container-right-panel column small-9");
var li = document.createElement("li");
li.setAttribute("class", "film-container-right-panel-li");
var ul = document.createElement("ul");
var h1 = document.createElement("h1");
h1.setAttribute("class", "film-container-right-panel-h1");
h1.textContent = film.title;
var ahref = document.createElement("a");
// ahref.setAttribute("class", "button");
ahref.setAttribute("data-open", "exampleModal1");
var paragraph = document.createElement("p");
paragraph.setAttribute("class", "film-container-right-panel-p");
var paragraphMaxLength = 125;
var filmOverview = film.overview;
var trimmedFilmOverview = filmOverview.substr(0, paragraphMaxLength);
trimmedFilmOverview = trimmedFilmOverview.substr(0, Math.min(trimmedFilmOverview.length, trimmedFilmOverview.lastIndexOf(" ")));
trimmedFilmOverview = trimmedFilmOverview + "...";
paragraph.textContent = trimmedFilmOverview;
var baseImgURL = "https://image.tmdb.org/t/p/w154" + film.poster_path;
var filmImage = document.createElement("img");
filmImage.src = baseImgURL;
filmImage.setAttribute("class", "film-container-right-panel-img");
// film.forEach(filmImage.src.indexOf("null"))
// filmImage.src = "/img/imagenotavailable.png";
app.appendChild(Filmcontainer);
Filmcontainer.appendChild(filmContainerLeftPanel);
Filmcontainer.appendChild(filmContainerRightPanel);
filmContainerLeftPanel.appendChild(filmImage);
filmContainerRightPanel.appendChild(ul)
.appendChild(li)
.appendChild(ahref)
.appendChild(h1);
li.appendChild(paragraph);
generateModal(filmInfo);
})
}
function generateModal(filmInfo){
var modal = document.getElementById("exampleModal1");
var h1 = document.createElement("h1");
h1.textContent = filmInfo.title;
modal.appendChild(h1);
console.log(filmInfo);
}
Maybe you want to take a look at Event.target and currentTarget.
--UPDATE--
Here is an example:
let ctas = document.querySelectorAll('.see-details');
ctas.forEach(cta => {
cta.addEventListener('click', (movie) => {
let movieId = movie.target.getAttribute('data-movie-id');
console.log(movieId);
});
});
<button data-movie-id="toy-story-1" class="see-details">See movie details</button>
You can solve this problem using event.target in JavaScript.
var div = document.createElement('div');
document.body.appendChild(div);
var button = document.createElement("button");
button.innerHTML = "John Wick";
button.style.margin= "10px";
div.appendChild(button);
var button2 = document.createElement("button");
button2.innerHTML = "John Wick: chapter 2";
button2.style.margin= "10px";
div.appendChild(button2);
var button3 = document.createElement("button");
button3.innerHTML = "John Wick: chapter 3";
div.appendChild(button3);
function showName(e){
alert("you have clicked "+e.target.innerHTML);
}
div.addEventListener('click', showName, false);
In this code I have created 3 buttons and whenever you clicks on any button it will trigger an event showName and event.target helps us to get the element that triggered a specific event (i.e click in our case) .
and try to run console.log(event.target), this will give you the whole information about the event triggered here.
I hope this helps.

Create JQuery Mobile button using JavaScript

I need help to create jQuery mobile button using JavaScript, I am using the code below, it creates a button but it is not recognizing the jQuery mobile style.
thanks for your help :)
function SubmitForm() {
var list = document.getElementById("forMore"); // Get the <ul> element with id="forMore"
if (list.hasChildNodes()) { // It has at least one
list.removeChild(list.childNodes[0]);
}
var e = document.getElementById("services");
var strUser = e.options[e.selectedIndex].value;
var id = e.options[e.selectedIndex].id;
document.getElementById("desc").innerHTML = strUser;
document.getElementById("fields").style.visibility = "visible";
var td = document.getElementById('forMore');
var btn = document.createElement('input');
btn.setAttribute("data-role", "button");
btn.setAttribute("data-theme", "b");
btn.setAttribute("class", "ui-input-btn");
btn.style.cssFloat = "left";
btn.style.fontSize = "18px";
btn.style.fontFamily = "myAccountFont";
btn.style.color = "green";
btn.onclick = function () {
location.href = "/Pin/SendVas?id=" + id;
};
btn.value = "تفعيل";
td.appendChild(btn);
}
hope this will help:
var a = document.createElement("A");
a.appendChild(document.createTextNode("Name"));
a.setAttribute("data-role","button");
a.setAttribute("data-inline","true");
a.setAttribute("data-corner","false");
$(td).append(a).trigger('create');
//Or user parent container:
$("#container").trigger('create');

localStorage clearing when I use split()

I want to create an array of names based on localStorage variable called "names". I use the String.split() to detect a new line which seems to work well, but not if I refresh the page more than once.
var names = localStorage.names;
if (!names) {
textArea.style.display = "block";
mybutton.style.display = "block";
} else {
textSplit = localStorage.names.split(/\n/);
copyInput1.innerHTML = textSplit[0];
copyInput2.innerHTML = textSplit[1];
copyInput3.innerHTML = textSplit[2];
}
document.getElementById("textArea").focus();
var showText = function() {
var text = textArea.value;
localStorage.names = text;
textSplit = localStorage.names.split(/\n/);
copyInput1.innerHTML = textSplit[0];
copyInput2.innerHTML = textSplit[1];
copyInput3.innerHTML = textSplit[2];
}
mybutton.onclick = showText;
clearbutton.onclick = localStorage.clear();
Any help appreciated.
You are executing clear() on localStorage which explains why it clears:
clearbutton.onclick = localStorage.clear();
Change this to:
clearbutton.onclick = localStorage.clear;
This way you're referencing the function instead.

removing child from a child

I am having trouble removing the child of a child of an object created using JS.
Basically once I create a comment object I appendChild(replyBox) to it. Inside the replyBox there is a cancel button which is supposed to completely delete the replyBox.
Here is the code :
function Comment(message){
var self = this;
var message = message;
var comment = document.createElement("li");
comment.id = "comment";
comment.style = "display: none;";
comment.textContent = message;
createButtons(comment);
var parent = document.getElementById("wall");
parent.appendChild(comment);
return comment;
}
function deleteComment(comment){
var parent = document.getElementById("wall");
parent.removeChild(comment);
}
function newReply(comment){
var buttons = comment.getElementsByTagName("input");
buttons.item(0).disabled="disabled";
var replyBox = document.createElement("div");
replyBox.id="replyBox";
var replyTxt = document.createElement("input");
replyTxt.type="text";
replyTxt.value="Write a reply";
replyTxt.onfocus = "if(this.value==this.defaultValue) this.value='';" ;
replyTxt.onblur="if(this.value=='') this.value=this.defaultValue;";
replyBox.appendChild(replyTxt);
createButtons(replyBox);
comment.appendChild(replyBox);
}
function createButtons(parent){
var button = document.createElement("input");
button.type = "submit";
if(parent.id=="comment"){
var reply = button.cloneNode();
reply.value = "reply";
reply.addEventListener("click", function(){newReply(parent)},false);
parent.appendChild(reply);
var deleteBtn = button.cloneNode();
deleteBtn.value = "delete";
deleteBtn.addEventListener("click", function(){deleteComment(parent)},false);
parent.appendChild(deleteBtn);
}
else{
var submitBtn = button.cloneNode();
submitBtn.value = "submit";
//reply.addEventListener("click", function(){newReply(parent)},false);
parent.appendChild(submitBtn);
var cancel = button.cloneNode();
cancel.value = "cancel";
cancel.addEventListener("click", function(){cancel(parent)},false);
parent.appendChild(cancel);
}
}
function cancel(replyBox){
replyBox.parentNode.removeChild(replyBox);
}
cancel.addEventListener("click", function(){cancel(parent)},false);
Which cancel is which? You have an object called cancel as well as a function with the same name. Try renaming one.
I see a problem here:
comment.id = "comment";
If you're setting all IDs of the comment elements to comment, the DOM may be getting confused.

Categories