I have this JavaScript code that does createElement, but how can I style it from my separate CSS file?
JavaScript
emails.forEach(function(email) {
const element = document.createElement('div');
element.innerHTML = email.sender + ' ' + email.subject + ' ' + email.timestamp
document.querySelector('#email-container').append(element);
});
HTML
<div id="email-container">
</div>
CSS
#email-container .element{
border-width:2px;
border-style:solid;
border-color:black;
}
if you're styling it that way, then you expect the div to have class element. So you just need one extra line to add that class to the element. Full code here:
emails.forEach(function(email) {
const element = document.createElement('div');
element.classList.add('element');
element.innerHTML = email.sender + ' ' + email.subject + ' ' + email.timestamp
document.querySelector('#email-container').append(element);
});
I am working on a chat project, and have mostly finished everything that I needed. My chat box is a textarea and for the most part it works, until I wanted to implement changing the color of certain words in the chatbox by using regex.
But looking at how I have this set up:
function writeMessageToChatBox(message, from, serverMessage=false, direct=false){
let chat_box = $('#chatbox');
let val = chat_box.val();
if(!serverMessage){
if(direct){
console.log(replay);
if(replay){
chat_box.val(val + '[Whisper to: ' + tempRecepient + ' ] ' + from + ": " + message + "\n" );
replay = false;
tempRecepient = undefined
}
else{
chat_box.val(val + '[Whisper from: ' + from + ' ] ' + from + ": " + message + "\n" );
}
}
else{
chat_box.val(val + from + ": " + message + "\n");
}
}
else{
chat_box.val(val + message + "\n");
}
chat_box.scrollTop(document.getElementById("chatbox").scrollHeight);
I've come to realize that textareas hold text within them in their value, but the text are not elements within the textarea so I cannot pick and choose which text gets style. From some research I saw that what I'm trying to do is not possible with a textarea. What would be another option, I assume a div container that can hold text elements?
Use, <div> with contenteditable attribute.
.textarea{
width:200px;
height:50px;
border:1px solid black;
}
<div class='textarea' contenteditable>
</div>
contenteditable Attribute
Refactored the function but I had to guess on some parameters. Used Template Literals which are Strings on steroids -- they should be your best friend dealing with all that text. The method html() is used extensively so markup can be typed or inserted in as a string.
Demo
function writeMessage(message, from = '', reply = '', serverMessage = false, direct = false) {
let tempRx = '';
let chat = $('.chatbox');
let val = chat.text();
if (!serverMessage) {
if (direct) {
console.log(reply);
if (reply) {
chat.html(`${val} <mark>[Whisper to: ${tempRx} ]</mark> ${from}: ${message}<br>`);
reply = false;
tempRx = undefined;
} else {
chat.html(`${val} <mark>[Whisper from: ${from} ]</mark> ${from}: ${message}<br>`);
}
} else {
chat.html(`${val} ${from}: ${message}<br>`);
}
} else {
chat.html(`${val} ${message}<br>`);
}
chat.scrollTop(chat[0].scrollHeight);
}
writeMessage(`Whispering, whisper test, mumble test, <b style='color:red'>belch test</b>, 😫`, `<b style='color:green'>Rusty</b>`, 'reply', false, direct = true);
<form id='main' name='main'>
<fieldset class='chatbox' contenteditable='false'>
<legend>Status: </legend>
</fieldset>
<fieldset class='chatbox' contenteditable>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I'm trying to search a value in json
<input type="text" id="test" size="21" maxlength="120">
<button onclick="Zoek()" class="btn btn-info btn-block">
tijdelijke zoek knop
</button>
I'm using this to input a value and the button to call the search function
function Zoek() {
var qeustion = document.getElementById("test").value;
document.getElementById("accordion").innerHTML == "";
var text = '{ "FAQ" : [' +
'{ "vraag":"John" , "antwoord":"Doe" },' +
'{ "vraag":"Anna" , "antwoord":"Smith" },' +
'{ "vraag":"Peter" , "antwoord":"Jones" } ]}';
obj = JSON.parse(text);
for (i = 0; i < text.length; i++) {
if (obj.FAQ[i].vraag == qeustion) //(obj.FAQ[i].getString("vraag").contains(question))
{
document.getElementById("accordion").innerHTML += "<div class='panel panel-default'><div class='panel-heading' role='tab' id='heading" + i + "'><h4 class='panel-title'><a data-toggle='collapse' data-parent='#accordion' href='#" + i + "' aria-expanded='false' aria-controls='" + i + "''>" + obj.FAQ[i].vraag + " </a></h4></div><div id='" + i + "' class='panel-collapse collapse in' role='tabpanel' aria-labelledby='heading" + i + "'><div class='panel-body'> " + obj.FAQ[i].antwoord + "</div></div></div> WOWOWOWOWOWOWOWOWWOWOWOOW";
} else {
document.getElementById("accordion").innerHTML = "No results found"
}
}
}
and this is my search function
so lets say i enter John it goes straigt to the else and doesnt do the if statement even though i am pretty sure it kind of is right
could anyone give me some pointers on searching in a json object? is there a other way to do this?
Please see jsfiddle attached demonstrating what you are looking for and will show you what you need to do - https://jsfiddle.net/vuenume2/1/
It is essential to have a break statement in your loop.
Without the break statement your true value for success simply gets overwritten with false on the next iteration, except for the last possible credentials, for which there is no "next" iteration.
if (obj.FAQ[i].vraag == qeustion)
{
<!-- do stuff -->
break;
} else {
<!-- do other stuff -->
}
Also, if you haven't done so you need to add a div with an id accordion to your html
<div id="accordion"></div>
Use filter function. You parsed in obj that string into json so You could do:
var target = obj.FAQ.filter(function(element){ return element.vraag == qeustion})[0];
if(target == undefined) {
// there is no that object logic
} else {
// there is that object logic
}
I'm using JavaScript/jQuery. I'm having an issue with looping through an array to display the data as well as removing contents via button clicks.
Original Code in Question
HTML
<textarea id="sds">Apple
Banana
Grape
Orange</textarea>
<input type="hidden" id="sdh" />
Problem: Every button returns 5!
<div id="popup" title="Poof">
</div>
Script
var sds = $("#sds").val();
var sda = sds.split("\n");
var sdi = "";
$.each(sda, function(k, s) {
sdi += "<input type='text' id='sd" + k + "' value='" + s + "' /><button id='button" + k + "'>Click Me</button><br />";
$("#sdh").val(k);
});
$("#popup").html(sdi);
var h = $("#sdh").val();
var i = 0;
while (i <= h) {
$("#button" + i).click(function() {
// Here is where I have a problem trying to manipulate the input associated to the button.
alert(i); // Test to see what returns for the value of i.
$("#sd" + i).val("Clicked button " + i);
});
i++;
}
CSS (Thanks for providing the CSS to make the demo look better, Jose!)
#sds {
display: none;
}
jsFiddle
Revised Code
HTML
<textarea rows="4" cols="40" id="sds">Apple
Banana
Grape
Orange</textarea>
<input type="text" id="sd" value="Click here to verify" />
<input type="hidden" id="key" />
<div id="popup" title="Verify Multiple Fruits">
</div>
Script
$(document).ready(function() {
var sds = $("#sds").val();
var sda = sds.split("\n");
var sdi = "";
$.each(sda, function(key, sd) {
sdi += "<input type='text' id='sd" + key + "' value='" + sd + "' /><button id='button'" + key + "'>Remove</button><br />";
alert(key); // Test to see what returns for the value of i.
$("#button" + key).click(function() {
// Here is where I have a problem trying to manipulate the input associated to the button.
$("#sd" + key).val("Clicked button " + i);
});
$("#key").val(key);
});
$("#popup").html(sdi);
});
$(function() {
$("#popup").dialog({
autoOpen: false,
buttons: {
"Update": function() {
var key = $("#key").val();
var i = 0;
var sds = "";
while (i <= key) {
sds += $("#sd" + i).val() + "\n";
i++;
}
sds = sds.slice(0, -1);
$("#sds").val(sds);
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
},
close: function() {
},
height: 320,
hide: {
duration: 1000,
effect: "explode"
},
modal: true,
resizable: false,
show: {
duration: 1000,
effect: "blind"
},
width: 480
});
$("#sd").focus(function() {
$("#popup").dialog("open");
});
});
CSS (Thanks again for the CSS here, Jose!)
#sds {
display: none;
}
#popup input,
#popup button {
float: left;
width: auto;
}
#popup input {
clear: left;
}
jsFiddle
Revised Code after Applying One of the Answers
HTML
<textarea rows="4" cols="40" id="sds">Apple
Banana
Grape
Orange
Pear
Strawberry</textarea>
<input type="text" id="sd" value="Click here to verify." />
<input type="hidden" id="key" />
<div id="popup" title="Verify Multiple Fruits"></div>
Script
$(document).ready(function() {
$.each($("#sds").val().split("\n"), function(key, sd) {
$("#popup").append(
$("<input type='text' id='sd" + key + "' value='" + sd + "' />").add(
$("<button id='button" + key + "'>Remove</button><br />").click(function() {
$("#sd" + key).val("");
$("key").val(key);
})));
});
});
$(function() {
$("#popup").dialog({
autoOpen: false,
buttons: {
"Update": function() {
var key = $("#key").val();
var i = 0;
var sds = "";
while (i <= key) {
sds += $("#sd" + i).val() + "\n";
i++;
}
sds = sds.slice(0, -1);
$("#sds").val(sds);
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
},
close: function() {
},
height: 320,
hide: {
duration: 1000,
effect: "explode"
},
modal: true,
resizable: false,
show: {
duration: 1000,
effect: "blind"
},
width: 480
});
$("#sd").focus(function() {
$("#popup").dialog("open");
});
});
CSS (This is really awesome, Jose!)
#sds {
display: none;
}
#popup input,
#popup button {
float: left;
width: auto;
}
#popup input {
clear: left;
}
jsFiddle
Suppose the value of sds is Apple, Banana, Grape and Orange on different lines. Each button created by the .each() loop will have the correct number assigned, but when trying to change the value, the variable i returns 5 on the alert message box while the next line doesn't seem to work at all - due to the index being off.
How can I revise this code to make it work like it's supposed to?
Corrected the error mentioned by the loving and caring commentators. Still not working. Obviously that wasn't the issue as my original code that I copied off of had the parenthesis closed correctly. I was hand-jamming the code here since I have no ability to copy and paste the code here, so a small typo was made. My question is about the logic, not typo. Thanks!
In order to minimize the confusion, I've revised the code section of this question to reflect the original code I had, so it'll show the consistency with the answers Jose provided below.
Obviously, the revised code also had more issues, so I made a new revision yet again. Here is what I've gotten so far. It's still quirky, but works on most part. I'm going to need help with the cancel action on the modal dialog since it won't bring back the previous values from the textarea tag. Also, please, note the version changes on jQuery and addition of jQuery UI to the JSFiddle demo to reflect my development environment.
The Ultimate Solution
HTML
<textarea rows="4" cols="40" id="sds">Apple
Banana
Grape
Orange
Pear
Strawberry</textarea>
<input type="text" id="sd" value="Click here to verify." />
<div id="popup" title="Verify Multiple Fruits"></div>
Script
$(document).ready(function() {
if ($("#sds").val()) {
var i = 0;
$.each($("#sds").val().split("\n"), function(key, sd) {
$("#popup").append(
$("<input type='text' class='blah' id='sd" + key + "' value='" + sd + "' />").add(
$("<button id='button" + key + "'>Remove</button><br />").click(function() {
$("#sd" + key).val("");
})));
i++;
window["i"] = i;
});
}
});
$(function() {
$("#popup").dialog({
autoOpen: false,
buttons: {
"Update": function() {
var i = window["i"];
var sds = "";
$(".blah").each(function(i) {
if ($(this).val()) {
sds += $("#sd" + i).val() + "\n";
}
});
sds = sds.slice(0, -1);
$("#sds").val(sds);
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
},
close: function() {
$("#popup").html("");
if ($("#sds").val()) {
var i = 0;
$.each($("#sds").val().split("\n"), function(key, sd) {
$("#popup").append(
$("<input type='text' class='blah' id='sd" + key + "' value='" + sd + "' />").add(
$("<button id='button" + key + "'>Remove</button><br />").click(function() {
$("#sd" + key).val("");
})));
i++;
window["i"] = i;
});
}
},
height: 320,
hide: {
duration: 1000,
effect: "explode"
},
modal: true,
resizable: false,
show: {
duration: 1000,
effect: "blind"
},
width: 480
});
$("#sd").focus(function() {
if ($("#sds").val()) {
$("#popup").dialog("open");
}
});
});
CSS
#sds {
display: none;
}
#popup input,
#popup button {
float: left;
width: auto;
}
#popup input {
clear: left;
}
jsFiddle
Thoughts after Solving the Issue
I was initially irritated by the people who pointed out the typos rather than trying to see the entire picture to discover the "big" flaw with the program itself because that's what I thought I would have done for people who would ask me for guidance. Then, it hit me when I thought about how I would really react when I see petty mistakes like typos and bad grammars. I admit I hate seeing those petty mistakes, mostly because I have an obsessive-compulsive disorder when it comes to writing anything, including codes. Now that I've learned about JSFiddle, I'll test my code there before trying to post a question here from now on. It has been a terrific learning experience and thanks to all for the assistance.
There are several ways to solve this problem.
Use a closure
Inside the loop, declare an anonymous function and call it immediately, passing in i as the parameter local_i. In other words, i has a global scope, but the local_i has a scope limited to the anonymous function. This way, the click event "sees" the local_i value, not the i (5) as you had before.
while (i <= h) {
(function (local_i) {
$("#button" + local_i).click(function() {
alert(local_i); // Test to see what returns for the value of i.
$("#sd" + local_i).val("Clicked button " + local_i);
});
})(i); // <-- HERE I am calling the function
i++;
}
Click here for a live demo
Get the index from the button id
There is one pattern here: You want i=0 for #button0, i=1 for #button1.
So, just get the index from the id. This solution requires no loops.
// select all buttons inside #popup, that have an id starting by "button"
$("#popup button[id^=button]").click(function() {
var i = parseInt($(this).attr('id').replace('button', ''));
alert(i); // Test to see what returns for the value of i.
$("#sd" + i).val("Clicked button " + i);
});
Live demo
Optimized version, no loops, no global variables
$.each($("#sds").val().split("\n"), function(k, s) {
$("#popup").append(
// append the text box
$("<input type='text' id='sd" + k + "' value='" + s + "' />").add(
// and the button with the click already defined
$("<button id='button" + k + "'>Click Me</button>").click(function() {
alert(k);
$("#sd" + k).val("Clicked button " + k);
}))
);
});
Live demo
Final Solution
Brand new code was pasted into the question. To fix the problem in that code, just change
$("#button" + key).click(function() {
// Here is where I have a problem trying to manipulate the input associated to the button.
$("#sd" + key).val("Clicked button " + i);
});
to
$("#button" + key).click(function() {
var i = $(this).attr('id').replace('button', '');
$("#sd" + i).val("Clicked button " + i);
});
You can use the other alternatives I wrote above.
Hope this helps.
you have an error here
$("#button" + i.click(function() {
it should be
$("#button" + i).click(function() {
corrent that and it will work.
I'm attempting to split a string I'm passing into
$("#groupUL").append("<li>" + "<h2>About Item:</h2> " + response.data[i].message + "<br /> " + "<h2>Posted By:</h2> <a href='#' onclick='splitName('" + response.data[i].from.name + "');'>" + response.data[i].from.name + "</a>" + "<br />");
Seems to be passing me the error
SyntaxError: syntax error
splitName(
Not sure how that's wrong...Here is the splitname function if that helps
function splitName(txt){
var myString = txt;
var mySplitResult = myString.split(" ");
console.log("The first element is " + mySplitResult[0]);
console.log("<br /> The second element is " + mySplitResult[1]);
console.log("<br /> The third element is " + mySplitResult[2]);
};
It's too hard to get it right when you put quotes in quotes in quotes and you try to escape it right. You got it wrong.
A solution is to make it in small parts :
var action = "splitName('" + response.data[i].from.name + "');";
$("#groupUL").append("<li>" + "<h2>About ... onclick=\""+action+"\">...");
But the best solution would be to follow best practice, that is not inline the javascript but use jQuery's binding function :
$("#groupUL").append("... <a id=myid ...");
$("#myid").click(function(){ splitName(response.data[i].from.name) });
I think the only problem with your code is with your readability issue. So I would suggest please improve it. Lets have a look at it. My code example # JSbin.
Here is the code :- (which i think is better)
var response = {
data : {
message: 'Cleaning code',
from: {
name: 'Clean Code works'
}
}
};
var li = $('<li>'); //Create empty li (Not Appending to DOM now due to performance issues)
$('<h2>').html('About Item:' + response.data.message + '<br />').appendTo(li);
$('<h2>').html('Posted By:').appendTo(li);
$('<a>').attr('href', '#')
.html(response.data.from.name)
.appendTo(li)
.click(function() {
splitName(response.data.from.name);
});
$('<br>').appendTo(li);
// Append li to ul (Final operation to DOM)
li.appendTo('#groupUL');
function splitName(txt){
var myString = txt;
var mySplitResult = myString.split(" ");
console.log("The first element is " + mySplitResult[0]);
console.log("The second element is " + mySplitResult[1]);
console.log("The third element is " + mySplitResult[2]);
}