javascript write a line of html code with a button - javascript

hey guys i have got this far with a chat system but now i am stuck at this point.
the js script will look for a element called chat and if it is not found it will put it in with all of the other elements stated here
<div class='chat' id='chat'><div class='ch' id='ch'><h2>Chat</h2></div><div class='chatbox'><div class='messages'></div><textarea id='message' class='chatinp' rows='3' cols='27'></textarea><button class='send'>Send</button></div></div>
My problem is how to insert that whole line of code with javascript into the html document.
how would you do this?
My javascript script is you need to see
<script type="text/javascript">
var num = new Number();
num = 0
function chat(){
if(!document.getElementById("chat")){
document.write("<div class='chat' id='chat'><div class='ch' id='ch'><h2>Chat</h2></div><div class='chatbox'><div class='messages'></div><textarea id='message' class='chatinp' rows='3' cols='27'></textarea><button class='send'>Send</button></div></div>")
}
else
{
var obj = document.getElementById("chat").cloneNode(true);
var p = $(".chat");
var offset = p.offset();
num = num + 1;
if (num <15) {
obj.id = obj.id + num;
document.getElementById("ch").id = obj.id;
document.body.appendChild(obj);
document.getElementById("chat").style.left = "700px";
}
}
}
</script>

Don't use document.write (it will overwrite everything in your document), but create div#chat dynamically, something like:
if(!document.getElementById("chat")){
var chatdiv = document.createElement('div');
chatdiv.id = 'chat';
chatdiv.className = 'chat';
chatdiv.innerHTML =
['<div class="ch" id="ch">',
'<h2>Chat</h2></div>',
'<div class="chatbox">',
'<div class="messages"></div>',
'<textarea id="message" class="chatinp" ',
'rows="3" cols="27"></textarea>',
'<button class="send">Send</button></div>'
].join(' ')
document.body.appendChild(chatdiv);
}
[Edit 2022] A more modern approach may be:
document.querySelector(`#chat`) || (_ =>
document.body.insertAdjacentHTML(
`beforeend`, `
<div id="chat">
<div class="ch" id="ch">
<h2>Chat</h2>
</div>
<div class="chatbox">
<div class="messages"></div>
<textarea id="message" class="chatinp" rows="3" cols="27"></textarea>
<br><button class="send">Send</button>
</div>
</div>`)
)();
document.querySelector(`#chat #message`).placeholder = `Type something!`;

Related

querySelector - Cannot read properties of null. Dynamic Form with Suggestions

I am trying to create a dynamic form with Javascript, where it is possible to add more fields. And when the user starts typing in the added fields then suggestions should show based on a list. Suggested inputs based on written input
The added fields should look just like the one shown in 1. The Search function works by using querySelector to take the new field created. However, i receive a type error saying: TypeError: Cannot read properties of null.
The function works without newSearch(i), but i want to have this suggestion box appearing when adding more fields.
Source Code:
sites.html
<div class="sites-container">
<form class="sites-form" method = "POST" id="myForm" name="myForm">
<div class="wrapper">
<div id="Site-options">
<h1 class="sites-add-header"> Create a String </h1>
<p class="sites-add-text"> Choose Modules at String </p>
<div class="wrapper2">
<div class="search-input2">
<a href="" target="_blank" hidden></a>
<input type="text" placeholder="Type to search.." name="PV-modules">
<div class="autocom-box2">
</div>
<div class="icon2"><i class="fas fa-search"></i></div>
</div>
</div>
</div>
<div class="controls">
<i class="fa fa-plus"></i>Add Another String
<i class="fa fa-plus"></i>Remove Site
</div>
</div>
<button type="submit" class="sites-add-site button">Add Site</button>
</form>
</div>
<script>
let suggestions2 = {{ modules | safe}} ;
</script>
<script src="{{ url_for('static', filename='add-site.js') }}"></script>>
add-site.js
var site_options = document.getElementById('Site-options');
var add_more_fields = document.getElementById('add_more_fields');
var remove_fields = document.getElementById('remove_fields');
var count = 1;
add_more_fields.onclick = function(){
var i = count++;
var _div = document.createElement('div');
_div.setAttribute('id','new-div'+i);
_div.innerHTML = '<p class="sites-add-text"> Choose Modules at Site </p>' +
'<div class="wrapper2">' +
'<div class="search-input2" id="new-search-input' + i + ' ">' +
'<a href="" target="_blank" hidden></a>' +
'<input type="text" placeholder="Type to search.." name="PV-modules">' +
'<div class="autocom-box2 id="new-autocom-box' + i + '">' +
'</div>'+
'<div class="icon2" id="new-icon' + i + '><i class="fas fa-search"></i></div>'+
'</div>'+
'</div>';
newSearch(i);
site_options.appendChild(_div);
};
remove_fields.onclick = function(){
var elem = document.getElementById("new-div");
elem.parentNode.removeChild(elem);
}
function newSearch(i) {
// getting all required elements
var searchWrapper2 = document.querySelector("#new-search-input" + i);
var inputBox2 = searchWrapper2.querySelector("input"); // <- Here i get TypeError
var suggBox2 = searchWrapper2.querySelector(".autocom-box2");
var icon2 = searchWrapper2.querySelector(".icon2");
let linkTag2 = searchWrapper2.querySelector("a");
let webLink2;
// if user press any key and release
inputBox2.onkeyup = (e2)=>{
let userData2 = e2.target.value; //user enetered data
let emptyArray2 = [];
if(userData2){
icon2.onclick = ()=>{
webLink2 = `https://www.google.com/search?q=${userData2}`;
linkTag2.setAttribute("href", webLink2);
linkTag2.click();
}
emptyArray2 = suggestions2.filter((data2)=>{
//filtering array value and user characters to lowercase and return only those words which are start with user enetered chars
return data2.toLocaleLowerCase().startsWith(userData2.toLocaleLowerCase());
});
emptyArray2 = emptyArray2.map((data2)=>{
// passing return data inside li tag
return data2 = `<li>${data2}</li>`;
});
searchWrapper2.classList.add("active"); //show autocomplete box
showSuggestions2(emptyArray2);
let allList2 = suggBox2.querySelectorAll("li");
for (let i = 0; i < allList2.length; i++) {
//adding onclick attribute in all li tag
allList2[i].setAttribute("onclick", "select2(this)");
}
}else{
searchWrapper2.classList.remove("active"); //hide autocomplete box
}
}
function select2(element){
let selectData2 = element.textContent;
inputBox2.value = selectData2;
icon2.onclick = ()=>{
webLink2 = `https://www.google.com/search?q=${selectData2}`;
linkTag2.setAttribute("href", webLink2);
linkTag2.click();
}
searchWrapper2.classList.remove("active");
}
function showSuggestions2(list){
let listData2;
if(!list.length){
userValue2 = inputBox2.value;
listData2 = `<li>${userValue2}</li>`;
}else{
listData2 = list.join('');
}
suggBox2.innerHTML = listData2;
}
}
you need to call newSearch after adding the element
site_options.appendChild(_div);
newSearch(i);
and you need to remove extra space in the innerHTML, which is why id attribute doesn't get found, breaking all the code:
'<div class="search-input2" id="new-search-input' + i + '">' +
swap these two lines it should work fine . searchWrapper2 is null in your case.
newSearch(i); site_options.appendChild(_div);
site_options.appendChild(_div); newSearch(i);

How do I change from an alert message to a regular text output?

I have a code snippet of my function that will output the total calculated GPA which is:
alert("GPA = " + eval(gpa));
However, I do not want it outputted as an alert.
I want it outputted in regular text.
So how do I change that so in HTML it will just output it in regular text instead of an alert ?
Is there a way to just replace the
alert
part of the code with something else ?
First create a div where you want to show text
<div class="text-message" style="display:none;"></div>
And change alert message with
$(".text-message").text("GPA = " + eval(gpa)).show();
OR to animate it
$(".text-message").text("GPA = " + eval(gpa)).fadein();
You could try something like following with HTML + JavaScript.
function gpa(param1 = 1, param2 = 2){
let resultGPA = param1 + param2;
console.log("GPA = " + resultGPA);
document.getElementById('evalElement').innerHTML = resultGPA;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button name="btn" onclick='gpa()'>Calculate GPA</button>
<p id = "evalElement"></p>
</body>
</html>
This should help you achieve your goal!
If your html element id is gpa, then in your JavaScript-file use following:
document.getElementById("gpa").innerHTML = "GPA = " + eval(gpa);
Step 1
Let's change your alert code to:
myAlert("GPA = " + eval(gpa));
Step 2
Implement myAlert
function myAlert(content) {
let context = document.getElementById('message-block');
context.display = 'block';
context.querySelector('.content').innerHTML = content;
}
Step 3
Create the structure:
<div id="message-block" style='display: none;'>
<div class="content"></div>
<input type="button" value="Close" onclick="this.parentNode.display = 'none';"
</div>
let gpa = "'a'+'b'";
function myAlert(content) {
let context = document.getElementById('message-block');
context.style.display = 'block';
context.querySelector('.content').innerHTML = content;
}
myAlert("GPA = " + eval(gpa));
<div id="message-block" style='display: none;'>
<div class="content"></div>
<input type="button" value="Close" onclick="this.parentNode.style.display = 'none';">
</div>

Print JavaScript dictionary into div

I have a JavaScript map that looks like this
var code = {'as':'','db':'','id3':'','term':''};
And want to print for example as into a div. If I do this, I get 'Undefined' inside the div. As I understand, this means the value itself is undefined. How can I "predefine" the empty string?
Update:
As there seems to be a lot of confusion: If I put code[1] into a div using the code above, the div contains 'Undefined'.
Update:
The markup looks as follows
<div id="cont" class="diff">
<div id="editor">
<div id="funcRow">
<ul>
<li><a onclick="changeTab(0)">Settings</a></li>
<li><a onclick="changeTab(1)">Knowledge</a></li>
<li><a onclick="changeTab(2)">Layer 4</a></li>
<li><a onclick="changeTab(3)">Hardware</a></li>
</ul>
</div>
<div id="text" contenteditable=true>
</div>
</div>
</div>
and changeTab(i) looks as follows:
function changeTab(i) {
code[activeTab] = document.getElementById("text").innerHTML;
document.getElementById("text").innerHTML = code[i];
document.getElementsByTagName("ul")[0].getElementsByTagName("li")[i].getElementsByTagName("a")[0].className="active";
document.getElementsByTagName("ul")[0].getElementsByTagName("li")[activeTab].getElementsByTagName("a")[0].className="";
activeTab = i;
}
The code below should be self-explanatory, just stringify before outputting
var div = document.getElementById('test');
var code = {'as':'','db':'','id3':'','term':''};
div.innerHTML = '<pre>' + JSON.stringify(code, null, 4) + '</pre>';
<div id="test"></div>
If you just want to output one of the values, use the key to access it
var div = document.getElementById('test');
var code = {'as':'1','db':'2','id3':'3','term':'4'};
div.innerHTML = code.as; // dot notation, or "code['as']" for bracket notation
<div id="test"></div>
Try using for..in loop, .innerHTML ; using break to stop loop after as property printed to div
// "predefine" empty strings with `1` , `2, `3`, `4`
var code = {'as':'1','db':'2','id3':'3','term':'4'};
var div = document.querySelector("div");
for (var prop in code) {
if (prop === "as") {
div.innerHTML += code[prop];
break;
}
}
<div></div>
The problem was me trying to call code[i], which is not possible in JavaScript. Undefined popped up because JS tried to evaluate the value to the key, which was not present at first.
Like this, but since the value is "nothing", the output is "nothing".
var div = document.getElementById('test');
var code = {'as':'','db':'','id3':'','term':''};
// code['as'] = "hello, world"; // un-comment to see something
div.innerHTML = '[' + code['as'] + ']';
<div id="test"></div>
Here is a second idea, based on the revision of your question:
var div = document.getElementById('test');
var keys = ['as', 'db', 'id3', 'term' ];
var code = {};
for (var i = 0; i < keys.length; ++i) code[keys[i]] = '';
code['as'] = "hello, world";
// code[keys[0]] = "hello, world"; // or this
div.innerHTML = '[' + code['as'] + ']' + ' (' + code[keys[0]] + ')';
<div id="test">X</div>

Why does my onClick js function call only work once per page load?

I am trying to display an rss feed from google news using yql. Currently, if you enter a zip code into the form, it works once, but I cannot enter another code without refreshing the page. Any help would be greatly appreciated!
P1
<script>
function top_stories(o){
var items = o.query.results.item;
var output = '';
var no_items=items.length;
for(var i = 0; i < 4; i++) {
var title = items[i].title;
var link = items[i].link;
var desc = items[i].description;
output += "<h3><a href='" + link + "'>"+title+"</a></h3>" + desc + "<hr/>";
}
document.getElementById('results').innerHTML = output;
}
</script>
</head>
<body>
<form name="input" action="" method="get" id="zc">
Zip Code: <input id="zip" type="text" name="zip">
<input id ="zipbutton" type="Button" value="Submit" onClick="showDiv(document.getElementById('zc').zip.value);" >
<div id="results" ></div>
<script id="yql"></script>
<script>
function showDiv(zip) {
var a = "http://query.yahooapis.com/v1/public /yql?q=select%20*%20from%20rss%20where%20url%20%3D%20'http%3A%2F%2Fnews.google.com%2Fnews%3Fgeo%3D" + zip + "%26output%3Drss'%0A&format=json&diagnostics=true&callback=top_stories";
document.getElementById("yql").setAttribute("src",a);
}
</script>
</body>
Try to create new <script> element for every click.
var script = document.createElement('script');
script.setAttribute("src", a);
document.getElementsByTagName('head')[0].appendChild(script);

Convert textarea content to html

I need to make a simple Javascript converter, which would turn <textarea> input into html-formatted list.
This is how a sample input would look:
Brand: Brand1
Model1 /Model2 /Model3 /Model4 /Model5 /Model6 /
Brand: Brand2
Model1 /Model2 /Model3 /Model4 /Model5 /Model6 /
And this would be the html after conversion:
<h3>Brand1</h3>
<ul>
<li>Model1</li>
<li>Model2</li>
<li>Model3</li>
<li>Model4</li>
<li>Model5</li>
<li>Model6</li>
</ul>
<h3>Brand2</h3>
<ul>
<li>Model1</li>
<li>Model2</li>
<li>Model3</li>
<li>Model4</li>
<li>Model5</li>
<li>Model6</li>
</ul>
Could any one provide some sample code to do that?
Thanks a lot
jQuery would be the easy way to do this, but if you're forced to do it with pure Javascript, you'll have something that looks like this:
HTML:
<textarea id="input" rows="5" cols="60">Brand: Brand1
Model1 /Model2 /Model3 /Model4 /Model5 /Model6
Brand: Brand2
Model1 /Model2 /Model3 /Model4 /Model5 /Model6
</textarea>
<input id="convertButton" type="button" value="convert" />
<div id="output"></div>
Javascript:
var convertButton = document.getElementById('convertButton');
convertButton.onclick = function(){
var input = document.getElementById('input');
var output = document.getElementById('output');
var lines = input.value.split( '\n' );
var html = '';
for( var i=0; i<lines.length; i++ ) {
if( lines[i].indexOf('Brand')===0 ) {
var brand = lines[i].split(':')[1];
html += '<h3>' + brand + '</h3>';
}
if( lines[i].indexOf('/')!==-1 ) {
var models = lines[i].split('/');
html += '<ul><li>' + models.join('</li><li>') + '</li></ul>';
}
}
output.innerHTML = html;
};​
Note that this solution doesn't do a lot of error checking, and it would get pretty confused if you weren't careful with your input, but it should give you a starting place to do what you want. See a live demo here: http://jsfiddle.net/GUQXf/4/

Categories