Assign to each user a color - javascript

I am currently creating a web-chat and whenever a message is displayed in the chat-box, the user that sent the message is displayed and identified with a color. For every user I create a class and assign a value to the color style with the above function.
newHTML = '';
$.each(data, function(index, element) {
$('.user_' + element.senderId).attr("style","color:" + randColor());
newHTML = newHTML + '<div id="boxMsg"><b><span class="user_' + element.senderId + '">'
+ element.senderId + '</b></span></br>' + element.message + '&nbsp&nbsp<span class="dateMsg">' + dateTime.substring(11, 16) + '</span></div>';
});
$('#chatbox').append(newHTML);
},
A JSON protocol is used to extract all the information concerning the message displayed on the chat. But still it doesn't work and all the usernames are black. Do you know what am I doing wrong?
Thanks in advance for your replies!
EDIT: thanks to #Evan I solved the first part and the function to assign a random color works. But still, only the first and the third member of the chat color changes. The others are still black. Anyway, I leave the code for the function randColor().
function randColor(){
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
EDIT.2: I have corrected the function to reflect more the one I am working on.

for (var i = 0; i <= nUsers.length; i++ )
should be
for (var i = 0; i < 6; i++ )
to form a hex color. It should always be 6 (or 3 for short hex colors).

Try to use .attr("style",properties)
If you need to change de background color use the property "background-color":
$('.user_' + element.senderId).attr("style","background-color:" + randColor());
Or, if you need to change de font color use the property "color":
$('.user_' + element.senderId).attr("style","color:" + randColor());

You have error in your HTML-->
var newHTML = '';
newHTML = newHTML + '<div id="boxMsg"><b><span class="user_' + element.senderId + '">' + element.senderId + '</b></span></br>' + element.message + '&nbsp&nbsp<span class="dateMsg">' + dateTime.substring(11, 16) + '</span></div>';
$('#chatbox').append(newHTML);
The "bold" tag closes before the span.
Fix it -->
newHTML = newHTML + '<div id="boxMsg"><b><span class="user_' + element.senderId + '">' + element.senderId + '</span></b></br>' + element.message + '&nbsp&nbsp<span class="dateMsg">' + dateTime.substring(11, 16) + '</span></div>';
Other then that, you can call the randomColor when you build the HTML, instead calling it after with jquery... (and you won't need a special class)-->
newHTML = newHTML + '<div id="boxMsg"><b><span style="color:'+randColor()+'">' + element.senderId + '</span></b></br>' + element.message + '&nbsp&nbsp<span class="dateMsg">' + dateTime.substring(11, 16) + '</span></div>';

I managed to solve the issue and correctly assign a color to each user. This is how the final code looks like:
function randColor(){
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
userColor = [];
userColor.push(randColor());
$('.user_' + element.senderId).css("color", userColor);
// Create box messages of the other users
var dateTime = element.timestamp;
newHTML = '<div id="boxMsg"><b><span class="user_' + element.senderId +'" style="color:'+ userColor +'">'+ element.senderId + '</span></b></br>'
+ element.message + '&nbsp&nbsp<span class="dateMsg">' + dateTime.substring(11, 16) + '</span></div>';
$('#chatBox').append(newHTML);
What I did was to create an array, store the obtained colors inside it and finally assign to each class of each user one element inside this array. Thanks to all of you for your answers!

Related

Adapting a javascript class for interactive draggable pie charts on HTML5 canvas and integrate it in Webflow

I found this nice canvas pie on Github, but it's giving me some problem.
I'm not very good in JS, so I'm here asking for help.
https://github.com/jamesalvarez/draggable-piechart
In the example shown here, you can see a UI to manipulate the graphic.
https://codepen.io/Waterbear83/pen/vYOrbva?editors=0010
I don't understand how to display that UI even if I'm using the same js.
https://codepen.io/Waterbear83/pen/yLNqVBZ?editors=0010
Is there someone so nice to help?
Thanks!
function onPieChartChange(piechart) {
var table = document.getElementById("proportions-table");
var percentages = piechart.getAllSliceSizePercentages();
var labelsRow = "<tr>";
var propsRow = "<tr>";
for (var i = 0; i < proportions.length; i += 1) {
labelsRow += "<th>" + proportions[i].format.label + "</th>";
var v = "<var>" + percentages[i].toFixed(0) + "%</var>";
var plus =
'<div id="plu-' +
dimensions[i] +
'" class="adjust-button" data-i="' +
i +
'" data-d="-1">+</div>';
var minus =
'<div id="min-' +
dimensions[i] +
'" class="adjust-button" data-i="' +
i +
'" data-d="1">−</div>';
propsRow += "<td>" + v + plus + minus + "</td>";
}
labelsRow += "</tr>";
propsRow += "</tr>";
table.innerHTML = labelsRow + propsRow;
var adjust = document.getElementsByClassName("adjust-button");
function adjustClick(e) {
var i = this.getAttribute("data-i");
var d = this.getAttribute("data-d");
piechart.moveAngle(i, d * 0.1);
}
for (i = 0; i < adjust.length; i++) {
adjust[i].addEventListener("click", adjustClick);
}
}
[...] even if I'm using the same js
Not quite the same :) It misses this in your setup onchange: onPieChartChange
var newPie = new DraggablePiechart({
canvas: document.getElementById("piechart"),
data: data,
onchange: onPieChartChange
});
And then, after, in the onPieChartChange() there is also the dimensions (it's the same array but sorted randomly with the function knuthfisheryates2(), like you don't have this function in your code, it throws an error ReferenceError: dimensions is not defined because it does not exist) term to change in data in the function onPieChartChange(piechart). The same goes with proportions. But you can keep this one rather to replace it, it's handy to place common parameter like collapsed: false and to do operations on others like label: d.format.label.charAt(0).toUpperCase() + d.format.label.slice(1)
var proportions = data.map(function(d,i) { return {
label: d.format.label,
proportion: d.proportion,
collapsed: false,
format: {
color: d.format.color,
label: d.format.label.charAt(0).toUpperCase() + d.format.label.slice(1) // capitalise first letter
}
}});
function onPieChartChange(piechart) {
var table = document.getElementById("proportions-table");
var percentages = piechart.getAllSliceSizePercentages();
var labelsRow = "<tr>";
var propsRow = "<tr>";
for (var i = 0; i < proportions.length; i += 1) { // <------------------ HERE but keep --------
labelsRow += "<th>" + proportions[i].format.label + "</th>"; // <--- HERE but keep --------
var v = "<var>" + percentages[i].toFixed(0) + "%</var>";
var plus = '<div id="plu-' +
data[i] + // <----------------- HERE ------------------
'" class="adjust-button" data-i="' +
i +
'" data-d="-1">+</div>';
var minus =
'<div id="min-' +
data[i] + // <-------------- AND HERE -----------------
'" class="adjust-button" data-i="' +
i +
'" data-d="1">−</div>';
propsRow += "<td>" + v + plus + minus + "</td>";
}
labelsRow += "</tr>";
propsRow += "</tr>";
table.innerHTML = labelsRow + propsRow;
var adjust = document.getElementsByClassName("adjust-button");
function adjustClick(e) {
var i = this.getAttribute("data-i");
var d = this.getAttribute("data-d");
piechart.moveAngle(i, d * 0.1);
}
for (i = 0; i < adjust.length; i++) {
adjust[i].addEventListener("click", adjustClick);
}
}
Note: Couldn't make it works with the angles, I looked all his examples, he never uses it, he always uses proportions: proportions. So I just changed that in addition in your code.
The code is to large to be posted in a snippet here, here a codepen:
You can change the data from line 744 (see picture)
https://codepen.io/jghjghjhg/pen/rNVrwbd

this.id is not working to detect which link is clicked in href

I am new to javascript and I am creating a bookstore using the google API. I have a small issue which I couldn't figure out. In the below piece of code that I saw from example code of google api bookstore function, I am trying to create href for the title of the book and pass its selfLink to the destination page i.e book-description.html.
When I put alert(this.id) on onclick It works, but for a normal method get(this) it does not work. I do not need an alertbox I want to take the id of the link clicked in href and pass it to another html.
handleResponse(response) {
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var a = item.volumeInfo.title;
var selfL = item.selfLink;
//var b = a.link("book-description.html");
var image = item.volumeInfo.imageLinks.smallThumbnail;
document.getElementById("content").innerHTML += "</br>" + "</br>" + "<br>" + "<img src =" + "'" + image + "'" + " class='im'/>";
document.getElementById("content").innerHTML += "<h4 class='right'>" + "<a href = 'book-description.html'id = " + "'" + selfL + "'" +
"onclick ='get(this);'>" + a + "</a></h4>";
function get(e) {
var link = e.id;
localStorage.setItem("Link", link);
}
document.getElementById("content").innerHTML += "<h4 class='right'>" + "AUTHOR:" + item.volumeInfo.authors + "</h4>";
document.getElementById("content").innerHTML += "<h5 class='right'>" + "PUBLISHER:" + item.volumeInfo.publisher + "</h5>";
var rating = item.volumeInfo.averageRating;
if (rating) {
document.getElementById("content").innerHTML += "<h5 class='right' id='rating'>" + rating + "</h5>";
} else {
document.getElementById("content").innerHTML += "<h5 class = 'right' id ='rating'>Not Rated Yet</h5>";
}
//document.getElementById("content").innerHTML += "<br>" + "<br>" + "<br>" + item.volumeInfo.publisheddate;
}
}
There are a number of problems with your code, but specifically in answer to your question; your function get is scoped so it is only available within the function handleResponse. For it to be accessible from an onclick it must be in page scope.
Simply move this
function get(e) {
var link = e.id;
localStorage.setItem("Link", link);
}
Into the head of your page
In programming there is the concept of DRY (Don't repeat yourself). So store a reference to document.getElementById("content") and reuse that variable.
var content = document.getElementById("content");
content.innerHTML = ...
You're missing some spaces in your output html. This may work in some browsers, others will struggle
<a href = 'book-description.html'id=
Should have a space between the end of one attribute and the start of another
<a href='book-description.html' id=
And for heaven sake, sort out the concatenation of your strings. You dont need a + if its just a simple string
document.getElementById("content").innerHTML += "</br>" + "</br>";
should be
document.getElementById("content").innerHTML += "</br></br>";

Setting ID for "n" buttons

//Display
for (var z=0; z<n; z++) {
document.write("<tr><td>"+ z + "</td>"); // Serial
document.write("<td>" + RandonValue + "</td>"); // Random Number
document.write('<td><button onclick="reply_click()" id="button-' + z + '">Click me</button></td></tr>'); //onClick
}
//Set ID
function reply_click(clicked_id){
alert(clicked_id);
}
Somehow I got undefined for all of them.
The replay_click is only for checking, I want to change that when I have different IDs.
Your z variable is the counter in this case which you can use for your id, keep in mind you can't have an ID starting with a number.
document.write('<td><button onclick="somefunction" id="button-' + z + '">Click me</button></td></tr>');
I have created a fiddle for you. Check it. I hope it fulfills the requirements :)
https://jsbin.com/doxusi/edit?html,js,output
<table id="mytable"></table>
var html = '';
var random = 5;
for (var i = 1; i <= random; i++) {
html += '<tr>' +
'<td>' + i + '</td>' +
'<td>Some Number</td>' +
'<td><button id="id_' + i + '">Button ' + i + '</button></tr></td>';
}
document.getElementById('mytable').innerHTML = (html);
You can inject your z variable like this, also putting double quotes (best practice:
document.write('<td><button onclick="somefunction(this)" id="mycell-' + z + '">Click me</button></td></tr>');
Note that you better pass this to your function, so inside that function you can reference that id:
function somefunction(elem) {
alert('you clicked ' + elem.id);
}

Inserting custom text in JS output

I have below line in my js code. i runs from 0 to 2. I want to put a custom text in place of: ' + info[i] + ' for each of the i's(over iterations of i). How do I do that?
for(var i=0; i < origins.length-1; i++) {
var results = response.rows[i].elements;
output += '<tr><td>' + info[i] + '</td><td>' + origins[i] + '</td><td></td><td>' + destinations[i+1] + '</td><td></td><td>' + results[i+1].distance.text + '</td></tr>';
}
. I want to put a custom text in place of: ' + info[i] + ' for each of the i's(over iterations of i).
Not sure what is "custom text" but assume your custom text should be in an array:
var customText = ["Custom text for i=0",
"Custom text for i=1",
"Custom text for i=2"];
for(var i=0; i < origins.length-1; i++) {
var results = response.rows[i].elements;
output += '<tr><td>' + customText[i] + '</td><td>' + //....
}
Also how to align the out-put of the code at the center of my webpage?
This is connected to CSS rather than with JS. Use CSS property text-align: center for a table, div or wharever you want to center.
If the custom text isn't in a variable, just put it directly into the HTML that you're generating:
output += '<tr><td>Custom Text</td><td>' + origins[i] + '</td><td></td><td>' + destinations[i+1] + '</td><td></td><td>' + results[i+1].distance.text + '</td></tr>';

How can create toggleable divs using javascript's innerhtml function?

I am trying to import information from an XML file, and create a name which, when clicked, will show more information. This information will be inside a div with no display until the header has been clicked.
This is the idea. Doesn't work.
$(document).ready(function () {
$.ajax({
type: "Get",
dataType: "xml",
url: 'service.xml',
success: function (xml) {
$(xml).find('Service[Name="j1979"]').find("Define").each(function () {
var PID = $(this).attr("PID");
var name = $(this).find("Name").text();
var source = $(this).find("source").text();
var doffset = $(this).find("DOffset").text();
var type = $(this).find("Type").text();
var length = $(this).find("Lenght").text();
var scale = $(this).find("Scale").text();
var noffset = $(this).find("NOffset").text();
var units = $(this).find("Units").text();
var moreinfo = "<div id='moreinfo'>source += '\r\n' += doffset += '\r\n' += type += '\r\n' += length += '\r\n' += scale += '\r\n' += noffset += '\r\n' += units</div>";
document.getElementById("j1979").innerHTML += PID += " ";
document.getElementById("j1979").innerHTML += < p onclick = "document.getElementById('moreinfo').style.display = 'inline-block'" > += "\r\n";
document.getElementById("j1979").innerHTML += moreinfo;
});
}
});
});
Sorry for any obvious mistakes and/or ugly code.
I assume that this is what you want to achieve: DEMO
just assume that the script in the demo is inside the success function
first, you have some error in here
document.getElementById("j1979").innerHTML += < p onclick = "document.getElementById('moreinfo').style.display = 'inline-block'" > += "\r\n";
this will not add the p element to the element with id j1979 because you write it like that, where you should be writing it like this
document.getElementById("j1979").innerHTML += "<p onclick=\"document.getElementById('moreinfo').style.display = 'inline-block';\" ></p>";
note the quotes at start and end, and the closing tag
second, there's no word or anything inside the p element that indicates that you could click it to show more information, so put the PID inside the p like this
document.getElementById("j1979").innerHTML += "<p onclick=\"document.getElementById('moreinfo').style.display = 'inline-block';\">" + PID + "</p>";
here's the full code with some CSS style to hide it before the user click on the PID
$(document).ready(function () {
var PID = "testPID";
var name = "Random Name";
var source = "Google";
var doffset = "1000";
var type = "A-9001";
var length = "50CM";
var scale = "100";
var noffset = "0";
var units = "Some Units";
var moreinfo = "<div id='moreinfo'>source: " + source + "</br>" + "doffset: " + doffset + "</br>" + "type: " + type + "</br>" + "length: " + length + "</br>" + "scale: " + scale + "</br>" + "noffset: " + noffset + "</br>" + "units: " + units + "</div>";
document.getElementById("j1979").innerHTML += "<p onclick=\"document.getElementById('moreinfo').style.display = 'inline-block';\">" + PID + "</p>";
document.getElementById("j1979").innerHTML += moreinfo;
});
#moreinfo {
display: none;
}
#j1979 {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div id="j1979"></div>
From the code you have, you can use '+' operator to concatenate strings.
When you need to use single quote inside string defined with single quote, you can use backslash (\) as escape character before it.
Also, you need to hide the div with class "moreinfo" initially.
As for new line, if you want each attribute in new line in moreinfo class, it can be achieved by using HTML "pre" tag or "br" tag or some other way.
So code would be:
var moreinfo = "<pre id='moreinfo' style='display:none'> source = " + source + "\r\n doffset = " + doffset + "\r\n type = " + type + "\r\n length = " + length + "\r\n scale = " + scale + "\r\n noffset = " + noffset + "\r\n units = " + units +"</pre>";
document.getElementById("j1979").innerHTML += '<p onclick="document.getElementById(\'moreinfo\').style.display = \'inline-block\'">\r\n' + PID + "</p>";
document.getElementById("j1979").innerHTML += moreinfo;
or
var moreinfo = "<div id='moreinfo' style='display:none'> source = " + source + "<br> doffset = " + doffset + "<br> type = " + type + "<br> length = " + length + "<br> scale = " + scale + "<br> noffset = " + noffset + "<br> units = " + units +"</div>";
document.getElementById("j1979").innerHTML += '<p onclick="document.getElementById(\'moreinfo\').style.display = \'inline-block\'">\r\n' + PID + "</p>";
document.getElementById("j1979").innerHTML += moreinfo;
If you want to toggle display on click, you can use ternary operator to give condition in onclick function:
var moreinfo = "<div id='moreinfo' style='display:none'> source = " + source + "<br> doffset = " + doffset + "<br> type = " + type + "<br> length = " + length + "<br> scale = " + scale + "<br> noffset = " + noffset + "<br> units = " + units +"</div>";
document.getElementById("j1979").innerHTML += '<p onclick="document.getElementById(\'moreinfo\').style.display == \'inline-block\' ? document.getElementById(\'moreinfo\').style.display = \'none\' : document.getElementById(\'moreinfo\').style.display = \'inline-block\'">\r\n' + PID + "</p>";
document.getElementById("j1979").innerHTML += moreinfo;
I wrote a program where I needed to toggle a div with javascript. I found a solution with this code.
function toggle( selector ) {
var nodes = document.querySelectorAll( selector ),
node,
styleProperty = function(a, b) {
return window.getComputedStyle ? window.getComputedStyle(a).getPropertyValue(b) : a.currentStyle[b];
};
[].forEach.call(nodes, function( a, b ) {
node = a;
node.style.display = styleProperty(node, 'display') === 'block' ? 'none' : 'block';
});
You can then call the function with:
toggle('.idOrClass');
make sure you use single quotes around the class or id name
Hope this helps! :)

Categories

Resources