Prepend Element - javascript

I'm trying to dynamically generate chat but the messages get inserted below the previous meaning the user has to scroll down to see a new message which isn't very good! I'm trying to change it so the message gets inserted above the last message.
var elementDiv = document.createElement("div");
elementDiv.className = "chat-message error";
elementDiv.appendChild(document.createTextNode(chatBoxMessage));
//Insert message
var oldMsg = "chat-message";
document.getElementsByClassName('message-window').appendChild(elementDiv);
document.body.insertBefore(elementDiv, oldMsg);
The variable chatBoxMessage is used to define the text.
Running this throws the error -
Uncaught TypeError: Failed to execute 'insertBefore' on 'Node' : parameter 2 is not of type 'Node'.

Seems like oldMsg is a string type. You'll have to call document.createTextNode with the oldMsg in order for it to work.

I made a sample implementation. Hopefully this is what you are looking for:
HTML:
<div id='container'></div>
Javascript:
// select the container
var container = document.getElementById('container');
// create chat messages
var msg1 = createChatMsg('Chat1');
var msg2 = createChatMsg('Chat2');
var msg3 = createChatMsg('Chat3');
// Insert Messages
container.insertBefore(msg1, container.firstChild);
container.insertBefore(msg2, container.firstChild);
container.insertBefore(msg3, container.firstChild);
// create chatmessage
function createChatMsg(message) {
var chatMsg = document.createElement('div');
chatMsg.className = 'some-chat';
chatMsg.appendChild(document.createTextNode(message));
return chatMsg;
}
Hopefully this helps and is what you are looking for. Sample implementation: http://jsfiddle.net/f1d02e49/

You may need to wrap your message in a text node.
document.createTextNode("chat-message");
Your error message indicates that your text is not a valid node.
parameter 2 is not of type 'Node'
See: MDN - Document.createTextNode()
onReady('#message-window', function() {
pushNewMessage('Third!');
pushNewMessage('Second!');
pushNewMessage('First!');
});
function pushNewMessage(chatBoxMessage) {
var errorMessageDiv = document.createElement('div');
errorMessageDiv.className = 'chat-message error';
errorMessageDiv.appendChild(document.createTextNode(chatBoxMessage));
//Insert message
var messageWindow = document.getElementById('message-window');
messageWindow.insertBefore(errorMessageDiv, messageWindow.firstChild);
}
// Convinience function -- Wait for element or body load...
function onReady(selector, callback, ms) {
var intervalID = window.setInterval(function() {
if ((document.querySelector(selector) || document.body) !== undefined) {
window.clearInterval(intervalID);
callback.call(this);
}
}, ms || 500);
}
<div id="message-window">
</div>

Related

How to get the Element ID in a for loop?

Hello I have the following code:
function updateData() {
var element = document.getElementById('elementId');
element.remove(); ** //Here i want to remove my elements**
return firebase.database().ref(varurl3).child('UserCount/count').once('value').then(function(snapshot) {
var username = snapshot.val();
for (var i = 1; i <= username; i++) {
var ref = firebase.database().ref(varurl3).child('Users').child(i).child('User');
ref.once('value', function(snapshot) {
var changedPost = snapshot.val();
var log = document.createElement('div');
log.setAttribute('id', 'elementId');
log.style.height = '75px';
log.style.width = '300px';
log.style.overflow = 'auto';
log.style.border = '1px solid #666';
log.style.backgroundColor = '#ccc';
log.style.padding = '8px';
log.style.position = 'relative';
log.style.left = '1400px';
log.style.top = '300px';
log.style.margin = '10px';
log.textContent = changedPost;
document.body.appendChild(log)
});
}
});
}
(async function looper() {
while (true) { // forever
await updateData();
await delay(2000);
}
})(); // execute looper
My function is called every 2 seconds to retrieve values from my firebase database and write them into divs every 2 seconds. Therefore i create with a for loop as many divs as i have values in my database. When the function is called again from new all div elements with the same ID should be deleted, so that they don't duplicate on the next run.
But these div elements are not deleted and I get the error message:
Uncaught (in promise) TypeError: element is null
Could someone please help me how I can solve this problem?
Element Ids need to be unique, so there is no way to fetch all elements with the same ID in one call.
You could try setting your divs to have a common tag, and use getElementsByTagName to collect them all up for deletion.
This post may be a useful reference: Javascript: getElementById vs getElementsById (both works on different pages)

How to display HTML class of current node in JS

I have variables which:
display the result (result), and
reference the current node (thisNode).
What do I need to change in my code so that it would display the HTML class?
var thisNode = document.body.firstChild;
var result = document.getElementById("resultOfButton");
result.InnerHTML = thisNode.;
/* Here, in JS are there any ways like displaying the class name,
like nodeClass */
Please give recommendations for my code. There may be some errors. Thank you.
var thisNode = document.body.firstChild;
var result = document.getElementById("resultOfButton");
var block = false;
function buttonDown()
{
if(block == true)
{
thisNode = thisNode.parentElement.firstChild;
block = false;
}
thisNode = thisNode.nextSibling;
result.innerHTML = thisNode.nodeName;
if(thisNode == thisNode.parentNode.lastChild)
{
block = true
}
}
function buttonUp()
{
// not done now...
}
function buttonEnter()
{
thisNode = thisNode.firstChild;
result.innerHTML = thisNode.c;
}
function buttonBack()
{
// not done now...
}
I think you're asking for the className attribute. I copied your first sample and added some code so you can run it on this page. You'll get the second emoji replaced by the class name of the inserted element.
var thisNode = document.getElementById("thisNode"); // document.body.firstChild;
var result = document.getElementById("resultOfButton");
result.innerHTML = thisNode.className; /*Here, in JS are there any ways like displaying the class name, like nodeClass*/
<div id="thisNode" class="sample-class">🙂</div>
<div id="resultOfButton">🙃</div>
Quoting MDN:
"The className property of the Element interface gets and sets the value of the class attribute of the specified element."

Cannot read property 'enumNodeFragments' of undefined

I'm trying to change the color of elements in 3D Viewer using the Autodesk-forge platform, and for this I'm using this API https://forge.autodesk.com/cloud_and_mobile/2015/12/change-color-of-elements-with-view-and-data-api.html by Daniel Du.
But the problem is when running I got this
The error Pict
And this the function :
Autodesk.Viewing.Viewer3D.prototype.setColorMaterial = function(objectIds, color) {
var material = addMaterial(color);
for (var i=0; i<objectIds.length; i++) {
var dbid = objectIds[i];
//from dbid to node, to fragid
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, function () {
var it = viewer.model.getData().instanceTree;
console.log(it);
it.enumNodeFragments(dbid, function (fragId) {
var renderProxy = viewer.impl.getRenderProxy(viewer.model, fragId);
console.log("r prox : " + renderProxy);
renderProxy.meshProxy = new THREE.Mesh(renderProxy.geometry, renderProxy.material);
renderProxy.meshProxy.matrix.copy(renderProxy.matrixWorld);
renderProxy.meshProxy.matrixWorldNeedsUpdate = true;
renderProxy.meshProxy.matrixAutoUpdate = false;
renderProxy.meshProxy.frustumCulled = false;
viewer.impl.addOverlay(overlayName, renderProxy.meshProxy);
viewer.impl.invalidate(true);
}, false);
});
}
}
Hopefully, anyone has the solution to this problem...
Most likely you are running this code before the instance tree has been loaded, which provokes the error Cannot read property 'enumNodeFragments' of undefined on it variable. You would need to wait for the Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT before running that code.
Take also a look at previous question about modifying materials in the viewer.

Firebase, can't listen on child's ref() - JavaScript

I just started to use Firebase with JavaScript, I've read the doc on Firebase's site, but it talks just about the immediate reference of a node which invokes on('child_added',function(){}).
I'm trying to find a particular node to listen for.
But it seems that it can't invoke the handler startListening when data is changed.
Here is my code
var myFire = new Firebase('https://myProject.firebaseio.com/chat');
var myConversation = "notAssigned";
myFire.once("value", function(snapshot) {
snapshot.forEach(function(childSnapshot) {
childSnapshot.forEach(function(i){
var user = i.val();
if (user == "10") myConversation = childSnapshot.child("messages").ref();
});
});
});
var textInput = document.querySelector('#text');
var postButton = document.querySelector('#post');
postButton.addEventListener("click", function() {
var msgUser = "10";
var msgText = textInput.value;
var date = js_dd_mm_yyyy_hh_mm_ss (); //function that returns actual date
myConversation.push({content:msgText,date:date, status:"1", type:"text", user:msgUser});
textInput.value = "";
});
/** Function to add a data listener **/
alert (myConversation.key());
var startListening = function() {
myConversation.on('child_added', function(snapshot) {
alert("here i am");
alert (snapshot.content);
});
}
// Begin listening for data
startListening();
I think that I fail to manage references, although when I invoke push data is actually loaded, that is, when I look at Database in Firebase's console, the push method has successful pushed new node.

Javascript error while using EncryptedLocalStore

I am trying to make my first JS-based adobe air app.
But I've stuck at a point.
Here's the code which is causing the error
var RunUrl = 'http://www.lilpirate.net';
var firstRunUrl = 'http://www.netbloo.com';
var snxApp = air.EncryptedLocalStore.getItem( 'snxApp' );
var semail = snxApp.readUTFBytes( snxApp.bytesAvailable );
if( semail!='786') {
data = new air.ByteArray();
data.writeUTFBytes( '786' );
air.EncryptedLocalStore.setItem( 'snxApp', data );
var snxUrlToLoad = firstRunUrl;
}
else
var snxUrlToLoad = RunUrl;
When compiling it from adl, it throws error -
TypeError: Result of expression 'snxApp' [null] is not an object.
Help!
You are accessing properties (bytesAvailable and readUTFBytes) of snxApp without checking to make sure it exists first. If you haven't used setItem to store anything with that name yet, it will be null.
Here's an example of how it would look with an if statement:
var snxApp = ...;
var semail;
if (snxApp !== null) {
semail = snxApp.readUTFBytes( snxApp.bytesAvailable );
}
...

Categories

Resources