removeChild is not a function - javascript

window.onload = initPage;
var firstname = false;
var lastname = false;
function initPage() {
addEventHandler(document.getElementById("firstname"), "blur", verifyFirst);
addEventHandler(document.getElementById("lastname"), "blur", verifyLast);
addEventHandler(document.getElementById("submit"), "click", showName);
}
function verifyFirst(e) {
var me = getActivatedObject(e);
if (me.value === "") {
me.className = "error";
me.focus();
me.select();
return;
}
else {
me.className = "";
firstname = true;
enabledButton();
}
}
function verifyLast(e) {
var me = getActivatedObject(e);
if (me.value === "") {
me.className = "error";
me.focus();
me.select();
return;
}
else {
me.className = "";
lastname = true;
enabledButton();
}
}
function enabledButton() {
if (firstname && lastname) {
document.getElementById("submit").disabled = false;
}
else {
document.getElementById("submit").disabled = true;
}
}
function showName() {
var first = document.getElementById("firstname").value;
var last = document.getElementById("lastname").value;
var word = first.toLowerCase() + last.toLowerCase();
for (var i = 0; i < word.length; i++) {
var letter = word.charAt(i);
var img = document.createElement("img");
img.setAttribute("src", "images/" + letter + ".png");
img.setAttribute("style", "left:" + 50 * i);
document.getElementById("displayname").appendChild(img);
}
var t = setInterval(removeName, 2000);
}
function removeName() {
var display = document.getElementById("displayname").getElementsByTagName("img");
var lengthOfDisplay = display.length;
for (var i = 0; i < lengthOfDisplay; i++) {
document.getElementById("displayname").removeChild(display[i]);
}
var t = setInterval(showName, 2000);
}
This is my current code that I am working on. I am creating a website with two input fields for first name and last name. On blur of each field after they are verified they will enabled the submit button. When the submit button is clicked, it will combine the first and last name and then separate each letter and call an image that will relate to each letter entered and display it on the displayname div.
Here is where I get the problem:
What I want is to display the image then remove the images and display it again continuously using setInterval. (i.e. the name spelled with the images will be flashing). unfortunately with my code when I try to remove the images using the removeChild function, I get an error of:
UPDATE
Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.
Below is an image of the of the inspection tool with the error and line that is getting the error.
Why am I getting this error when I am asking it to remove the images with removeChild(display[i])?

Replace line 68 with
document.getElementById("displayname").innerHTML = '';

Change the code on the line 68 from this
document.getElementById("displayname".removeChild(display[i]));
to this
document.getElementById("displayname").removeChild(display[i]);

removeChild() is a method applicable to a Node (and not a string or a selector as you have used in your code).
document.getElementById("displayname").removeChild(display[i])); should be the appropriate syntax.

Related

How do I stop my program from outputting the same thing twice in a row?

So, I have created this HTML page with some JavaScript in it. And I have this button that outputs one out of six emojis. It worked fine and then I added some code to stop the program from outputting the same emoji twice in a row, but it doesn't make any difference and I don't know why.
This is my code:
function randEmoji()
{
var oldEmoji = emoji;
var emojiList = [";)", ":D", "xD", ":O", ":X", ":P"];
var emoji = emojiList[Math.floor(Math.random() * emojiList.length)];
if (oldEmoji == emoji)
{
randEmoji();
}
else
{
document.getElementById("emojiText").innerHTML = "Look how fun! ---> " + emoji + " <--- An emoji!";
console.log(emoji);
}
}
I'm not very good at programming and have no idea what's causing this problem.
Please help me!
you have to declare your variables outside the function and set them inside. otherwise their values get reset in each function call.
Try this:
var oldEmoji = '';
var emoji = '';
var emojiList = [";)", ":D", "xD", ":O", ":X", ":P"];
function randEmoji() {
oldEmoji = emoji;
emoji = emojiList[Math.floor(Math.random() * emojiList.length)];
if (oldEmoji == emoji) {
randEmoji();
} else {
console.log(emoji);
}
}
var i = 0;
while (i < 20) {
randEmoji();
i += 1;
}
The problem is that any variables local to the function scope (meaning declared inside the function) are thrown away after the function completes its execution. Thus, every time you run the function emoji and oldEmoji are reinstantiated from undefined
One solution would be to move one of those declarations to a parent scope, like so:
var oldEmoji;
function randEmoji() {
var emojiList = [";)", ":D"];
var emoji = emojiList[Math.floor(Math.random() * emojiList.length)];
if (oldEmoji == emoji) {
randEmoji();
} else {
console.log(emoji);
oldEmoji = emoji;
}
}
randEmoji();
randEmoji();
randEmoji();
randEmoji();
randEmoji();
randEmoji();
randEmoji();
See here, we never actually get a repeat.
In addition to #full-stack answer, you could:
var oldEmoji = '';
var emoji = '';
var emojiList = [";)", ":D", "xD", ":O", ":X", ":P"];
function randEmoji(){
// remove old emoji first to avoid doing a recursive call
var check = oldEmoji? emojiList.filter(e => e !== oldEmoji ) : emojiList;
var emoji = check[Math.floor(Math.random() * check.length)];
oldEmoji = emoji
document.getElementById("emojiText").innerHTML = "Look how fun! ---> " + emoji + " <--- An emoji!";
console.log(emoji);
}

Why searchbox become lagging when typing word to search data in CSV?

I developed the store locator using open street map and leaflet. The problem is when I want to type in searchbox it will become lagging to finish the word. That store locator read from the CSV file that has 300++ data. Below is the code for the searchbox:
var locationLat = [];
var locationLng = [];
var locMarker;
var infoDiv = document.getElementById('storeinfo');
var infoDivInner = document.getElementById('infoDivInner');
var toggleSearch = document.getElementById('searchIcon');
var hasCircle = 0;
var circle = [];
//close store infor when x is clicked
var userLocation;
$("#infoClose").click(function() {
$("#storeinfo").hide();
if (map.hasLayer(circle)) {
map.removeLayer(circle);
}
});
var listings = document.getElementById('listingDiv');
var stores = L.geoJson().addTo(map);
var storesData = omnivore.csv('assets/data/table_1.csv');
function setActive(el) {
var siblings = listings.getElementsByTagName('div');
for (var i = 0; i < siblings.length; i++) {
siblings[i].className = siblings[i].className
.replace(/active/, '').replace(/\s\s*$/, '');
}
el.className += ' active';
}
function sortGeojson(a,b,prop) {
return (a.properties.name.toUpperCase() < b.properties.name.toUpperCase()) ? -1 : ((a.properties.name.toUpperCase() > b.properties.name.toUpperCase()) ? 1 : 0);
}
storesData.on('ready', function() {
var storesSorted = storesData.toGeoJSON();
//console.log(storesSorted);
var sorted = (storesSorted.features).sort(sortGeojson)
//console.log(sorted);
storesSorted.features = sorted;
//console.log(storesSorted)
stores.addData(storesSorted);
map.fitBounds(stores.getBounds());
toggleSearch.onclick = function() {
//var s = document.getElementById('searchbox');
//if (s.style.display != 'none') {
//s.style.display = 'yes';
//toggleSearch.innerHTML = '<i class="fa fa-search"></i>';
//$("#search-input").val("");
//search.collapse();
//document.getElementById('storeinfo').style.display = 'none';
//$('.item').show();
//} else {
//toggleSearch.innerHTML = '<i class="fa fa-times"></i>';
//s.style.display = 'block';
//attempt to autofocus search input field when opened
//$('#search-input').focus();
//}
};
stores.eachLayer(function(layer) {
//New jquery search
$('#searchbox').on('change paste keyup', function() {
var txt = $('#search-input').val();
$('.item').each(function() {
if ($(this).text().toUpperCase().indexOf(txt.toUpperCase()) != -1) {
$(this).show();
} else {
$(this).hide();
}
});
});
I dont know what is the cause of the lag in the search box. It is something wrong in code or the csv file? Thank you
Every iteration of $('.item').each is causing a layout change because $(this).hide() or $(this).show() causes the item to removed/added to the DOM as the style is set to display:none back and forth. DOM manipulations and the corresponding layout changes are expensive.
You can consider accumulating the changes and doing one batch update to the DOM using a function like appendChild

Firebase: Using callback function to decide whether data is in the database

I am creating search bar, which shows results from database dynamically on keypress, when they match the string that is in the search bar. Also when the string doesn't match anything in my database, I want to show message to user, that nothing matches his input. Problem is that I don't know how to do this in javaScript. I tried using callback function, but my implementation doesn't work. It is my first time using callback function, so I guess something is not right. Can anybody help me?
Here is simplified code:
var bars = firebase.database().ref("bars").orderByChild("rating");
var types = firebase.database().ref("types");
var searcher = document.getElementById("searcher");
var results = document.getElementById("searchResults");
function search(){
var value = searcher.value.toUpperCase();
clearTimeout(timeout);
timeout = setTimeout(function () {
if(value == null || value == ""){
results.style.display = "none";
} else{
results.innerHTML = "";
//callback function here
function findResults(callback) {
types.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var type = childSnapshot.key;
if(type.toUpperCase().startsWith(value)){
results.style.display = "block";
var typeItem = createDiv("result-item");
typeItem.innerHTML = type;
results.append(typeItem);
}
callback(true);
});
});
bars.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var bar = childSnapshot.key;
if(bar.toUpperCase().startsWith(value)){
results.style.display = "block";
var barItem = createDiv("result-item");
barItem.innerHTML = type;
results.append(barItem);
}
callback(true);
});
});
}
//This needs to work, when callback didn't return true
findResults(function(callback){
if(!callback){
var empty = createDiv("emptyResult");
empty.innerHTML = "No matching results";
results.appendChild(empty);
results.style.display = "block";
}
});
}
}, 400);
}
function createDiv(name){
var div = document.createElement("div");
div.className = name;
return div;
1.Let me start by pointing out that querying the Firebase Database on Keypress can be very expensive, since you'll be downloading data more frequently and Firebase has a price on data downloaded. I recommend querying the database when the user presses Enter or a Search Button.
2.I don't see why you need a callback function for this. You can use plain functions to achieve that. Like this:
function search(){
var value = searcher.value.toUpperCase();
clearTimeout(timeout);
timeout = setTimeout(function () {
if(value == null || value == ""){
results.style.display = "none";
} else{
results.innerHTML = "";
types.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var type = childSnapshot.key;
var foundUnderTypes = false;
if(type.toUpperCase().startsWith(value)){
results.style.display = "block";
var typeItem = createDiv("result-item");
typeItem.innerHTML = type;
results.append(typeItem);
foundUnderTypes = true;
}
bars.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var bar = childSnapshot.key;
if(bar.toUpperCase().startsWith(value)){
results.style.display = "block";
var barItem = createDiv("result-item");
barItem.innerHTML = type;
results.append(barItem);
}
else{
if(!foundUnderTypes)
emptyResult();
}
});
});
});
});
}
}, 400);
}
function emptyResult(){
var empty = createDiv("emptyResult");
empty.innerHTML = "No matching results";
results.appendChild(empty);
results.style.display = "block";
}

Making an ajax request with jsonp(no jquery)

I need some help on an assignment that I need to do. Basically the question is a number guessing game. We're assigned a number in the interval [0,1023] based on our student number and we have 11 guesses to get the right number. I know I have to use a binary search to get the number, my only problem is connecting to the server and getting a result.
We're given this:
A sample request looks as follows:
http://142.132.145.50/A3Server/NumberGuess?snum=1234567&callback=processResult&guess=800
And also given that the request returns the following parameters:
1: A code to determine if your guess is equal, less than or greater than the number
2: Message string
3: Number of guesses made by my application
This is what I've tried so far, just as a test to get the server request working. All I get in return is "object HTMLHeadingElement"
window.onload = function() {
newGuess();
}
function newGuess() {
var url = "http://142.132.145.50/A3Server/NumberGuess?snum=3057267&callback=processResult&guess=600";
var newScriptElement = document.createElement("script");
newScriptElement.setAttribute("src", url);
newScriptElement.setAttribute("id", "jsonp");
var oldScriptElement = document.getElementById("jsonp");
var head=document.getElementsByTagName("head")[0];
if (oldScriptElement == null) {
head.appendChild(newScriptElement);
} else {
head.replaceChild(newScriptElement, oldScriptElement);
}
}
function processResult(code,message,guesses) {
var code = document.getElementById("code");
var message = document.getElementById("message");
var guesses = document.getElementById("guesses");
code.innerHTML = code;
message.innerHTML = message;
guesses.innerHTML = guesses;
}
EDIT: Current state of my code.
window.onload = function() {
min = 0;
max = 1023;
mid = 0;
setInterval(newGuess,1000);
};
function newGuess() {
mid = Math.floor((max-min)/2);
var url = "http://142.132.145.50/A3Server/NumberGuess?snum=3057267&callback=processResult&guess="+mid;
var newScriptElement = document.createElement("script");
newScriptElement.setAttribute("src", url);
newScriptElement.setAttribute("id", "jsonp");
var oldScriptElement = document.getElementById("jsonp");
var head=document.getElementsByTagName("head")[0];
if (oldScriptElement == null) {
head.appendChild(newScriptElement);
} else {
head.replaceChild(newScriptElement, oldScriptElement);
}
}
function processResult(codeJ,messageJ,guessesJ) {
code = document.getElementById("code");
message = document.getElementById("message");
guesses = document.getElementById("guesses");
code.innerHTML = codeJ;
message.innerHTML = messageJ;
guesses.innerHTML = guessesJ;
if(codeJ == 0){
return;
}else if(codeJ == -1){
min = mid + 1;
}else if(codeJ == 1){
max = mid -1;
}
console.log(mid);
}
Check your variable-names. You are overwriting the function-patameters.
Something like
code.innerHTML = code;
message.innerHTML = message;
guesses.innerHTML = guesses;
just CAN'T work, you should see the problem yourself...

parameter count mismatch exception thrown when event handler of button called from javascript

I have a few textboxes on a page whose values are getting populated from the return value of
a modal window like this and I have a javascript method that calls the event handler of a button in the following way. The values are being returned properly and the textbox is getting populated properly but i am getting an exception parameter count mismatch.
res = window.showModalDialog('frm_VisitorSearchPopUp.aspx', "", "dialogWidth:1024px;dialogHeight:600px");
getElementById('<%=AddVisitorID.ClientID %>').click();
This problem does not occur when i am using window.open() method can anybody tell me why this problem is occurring.
My Code
function openup() {
var left = screen.width / 2 - 1024 / 2;
var tops = screen.height / 2 - 600 / 2;
var d = new Date();
var res;
res = window.showModalDialog('frm_VisitorSearchPopUp.aspx', "", "dialogWidth:1024px;dialogHeight:600px");
setvalues(res.PersonName, res.Address, res.CompanyName, res.ContactNumber, res.Email);
}
function setvalues(PersonName, Address, CompanyName, ContactNumber, Email) {
var RowId = $("#<%= VisitorDetailsGrid.ClientID%>").getDataIDs();
for (i = 0; i < RowId.length; i++) {
rowData = $("#<%= VisitorDetailsGrid.ClientID%>").getRowData(RowId[i]);
if (rowData.PersonName == PersonName && rowData.ContactNumber == ContactNumber && rowData.CompanyName == CompanyName && rowData.Email == Email && rowData.Address == Address) {
alert("The visitor \"" + PersonName + "\" has already been added to the visitor's list.");
document.getElementById('<%=PersonNameID.ClientID%>').value = "";
document.getElementById('<%=AddressID.ClientID%>').value = "";
document.getElementById('<%=CompanyNameID.ClientID%>').value = "";
document.getElementById('<%=ContactNumberID.ClientID%>').value = "";
document.getElementById('<%=EmailID.ClientID%>').value = "";
return;
}
}
document.getElementById('<%=PersonNameID.ClientID%>').value = PersonName;
document.getElementById('<%=AddressID.ClientID%>').value = Address;
document.getElementById('<%=CompanyNameID.ClientID%>').value = CompanyName;
document.getElementById('<%=ContactNumberID.ClientID%>').value = ContactNumber;
document.getElementById('<%=EmailID.ClientID%>').value = Email;
elem = document.getElementById('<%=AddVisitorID.ClientID %>').click();
}

Categories