Multiple RGB string to color boxes - javascript

Basically i have this JSFiddle,
As you can see on the fiddle there is a long string of numbers ( they are an rgb code)
You can see that there also is just one box inside mydiv (totally forgot to add the others in for the palette).
Basically i need all the other RGB codes to have their own box to show the colors that the RGB represents.
Here is the code for you none JS Fiddlers
HTML
<span class="glyphicon glyphicon-ok"></span>
<h3>Make a Custom Theme from your image</h3>
<p> Based on your logo we believe this is the best colour scheme for you</p>
<div id="mydiv" style="background-color: rgb({{dominantColor}})"></div>
<h4>{{palette}}</h4>
<h4>
[[59,214,252],[217,236,252],[14,137,250],[4,31,156],[43,188,251],[13,86,199],[107,162,231],[53,117,204],[61,159,245]]
</h4> <!-- This is whats returned via the {{palette}} -->
<p>is this correct?</p>
<!--<button type="submit" class="btn btn-danger">Submit</button>-->
</div>
Css
#mydiv {
width: 100px;
height: 100px;
border: 1px solid #000;
}
I'm expecting to use JS to split up the codes, I can return the data without the square brackets [] So in theory i need the js to grab each rgb code and display the colour inside the box.

Half baked jsfiddle doesn't help much, really. Fiddle is for working example so we can see the existing condition and debug right away, not for you to paste your code for people to read.
Please refer to the snippet for solution. You can use ng-style to dynamically place the rgb values as css style.
angular.module('test', [])
.controller('Test', function($scope){
$scope.data = [[59,214,252],[217,236,252],[14,137,250],[4,31,156],[43,188,251],[13,86,199],[107,162,231],[53,117,204],[61,159,245]];
});
.box {
width: 50px;
height: 50px;
border: 1px solid #000;
float: left;
margin-right: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.min.js"></script>
<div ng-app='test' ng-controller='Test'>
<div class='box' ng-style="{'background-color': 'rgb('+color[0]+', '+color[1]+', '+color[2]+')'}" ng-repeat='color in data'></div>
</div>

Related

Is there a way to have different colored text inside a textarea?

I have an HTML Textarea, which contains a custom-made live editable JSON file where you can see the results of the edits in real-time. I also have something that can cycle through the entries in a "points" attribute, being a list, where it shows the results in the canvas where the JSON results are seen, such that one can see what point is being selected.
I want the point in the textarea to be able to be formatted when selected, such as the selected point in the textarea JSON to be highlighted yellow or have the text color changed to blue or something like that.
I have tried this:
<textarea id="objtext">
not orange
<span style="color:orange">
orange
</span>
not orange
</textarea>
It just showed the textarea having that in it as text, instead of formatting inside the textarea.
How do I make it formatted (and editable and readable by code with textarea.value ideally without the formatting)?
I don't think this is possible with textarea. I think epascarello is trying to tell you that it is possible using a div with the attribute contenteditable="true".
Check out this similar question - Is it possible to have several different textcolors in one textarea?
You will need to style the div to look and feel like a textarea. Here's a basic mockup, you may need to add some Javascript to extend this.
<div id="objtext" contenteditable="true">
not orange
<span class="orange-text">
orange
</span>
not orange
</div>
#objtext {
-moz-appearance: textfield-multiline;
-webkit-appearance: textarea;
border: 1px solid gray;
overflow: auto;
padding: 4px;
width: 400px;
height: 200px;
font: medium -moz-fixed;
font: -webkit-small-control;
}
.orange-text {
color: orange;
}
::selection {
color:orange;
}
::-moz-selection {
color:orange;
}
https://jsfiddle.net/miainchambers/g07rcb5o/2/
Text value can be retrieved by using document.getElementById("objtext").textContent
Unfortunately, it's not possible to do this with a textarea nor input tags.
You can use instead:
contenteditable attribute
<div contenteditable="true">
Lorem Ipsum <span style="color: red;">Lorem</span>
</div>
WYSIWYG editor like https://github.com/tinymce/tinymce
Similar tools depending on the complexity you have to provide
Check out Highlight.js + an editable div.
Example:
<link rel="stylesheet" href="/path/to/styles/default.css">
<link rel="stylesheet"
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.2.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.2.0/highlight.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
document.querySelectorAll('code').forEach((el) => {
hljs.highlightElement(el);
});
});
</script>
<pre><code class="hightlight-json" contenteditable="True">{
"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": "None",
}
}
}
</code>
</pre>

classList.toggle() for multiple divs

I have 3 divs as colors to choose from and 3 blank divs. I want to let the user be able to:
(1) click a colored div and then a blank div, then the blank div is colored as the color the user choose. And the code seems to work.
(2) I want the user to be able to click the colored blank div again and it becomes white. And the code seems to work.
The problem is, if the blank div is colored and the user choose another color and click the colored blank div again, a newer color class will be added to the div, and things become unpredictable. You can open the console and track the messy change of the class of the blank div.
How can I solve this problem? I only want the blank divs to toggle between two classes.
var chosenColor;
function pickColor(arg){
chosenColor=arg.id;
}
function draw(id){
document.getElementById(id).classList.toggle("white");
document.getElementById(id).classList.toggle(chosenColor);
}
.box{
width: 100px;
height: 100px;
border: 1px solid black;
display: inline-block;
}
.red{background: red}
.blue{background: blue;}
.yellow{background: yellow;}
.white{background: white;}
<html>
<body>
<div class="box red" id="red" onclick="pickColor(this)">1</div>
<div class="box blue" id="blue" onclick="pickColor(this)">2</div>
<div class="box yellow" id="yellow" onclick="pickColor(this)">3</div>
<br><br>
<div class="box white" id="4" onclick="draw(4)">4</div>
<div class="box white" id="5" onclick="draw(5)">5</div>
<div class="box white" id="6" onclick="draw(6)">6</div>
</body>
</html>
Instead of using classes and running into the issue of assigning multiple nested classes or having to use complicated white logic...
I'd use data-* attribute:
var chosenColor;
function pick(el) {
chosenColor = el.dataset.color;
}
function draw(el) {
el.dataset.color = el.dataset.color ? "" : chosenColor;
}
body { background: #eee; }
.box {
width: 100px;
height: 100px;
border: 1px solid black;
display: inline-block;
background: white; /* BY DEFAULT !!! */
}
[data-color=red] { background: red; }
[data-color=blue] { background: blue; }
[data-color=yellow] { background: yellow; }
<div class="box" onclick="pick(this)" data-color="red">1</div>
<div class="box" onclick="pick(this)" data-color="blue">2</div>
<div class="box" onclick="pick(this)" data-color="yellow">3</div>
<br><br>
<div class="box" onclick="draw(this)">4</div>
<div class="box" onclick="draw(this)">5</div>
<div class="box" onclick="draw(this)">6</div>
What the ternary el.dataset.color = el.dataset.color ? "" : chosenColor; does is:
if the element has already any data-color set data-color to "" (nothing)
otherwise set data-color to the preselected chosenColor
Check to see if the element's classname is white. If not, set its class name to white - else, set it to the chosen color. You can put the boxes in a container and use .container > div selector, removing the need to give the boxes the .box class. Also, in a listener, this will refer to the clicked element - there's no need to use getElementById when you already have a reference to the element.
var chosenColor;
function pickColor(arg) {
chosenColor = arg.id;
}
function draw(element, id) {
if (element.className !== 'white') element.className = 'white';
else element.className = chosenColor;
}
.container > div {
width: 100px;
height: 100px;
border: 1px solid black;
display: inline-block;
}
.red {
background: red
}
.blue {
background: blue;
}
.yellow {
background: yellow;
}
.white {
background: white;
}
<div class="container">
<div class="red" id="red" onclick="pickColor(this)">1</div>
<div class="blue" id="blue" onclick="pickColor(this)">2</div>
<div class="yellow" id="yellow" onclick="pickColor(this)">3</div>
<br><br>
<div class="white" id="4" onclick="draw(this, 4)">4</div>
<div class="white" id="5" onclick="draw(this, 5)">5</div>
<div class="white" id="6" onclick="draw(this, 6)">6</div>
</div>
Answer
See - https://codepen.io/stephanieschellin/pen/xyYxrj/ (commented code)
or ...
var activeColor
function setPickerColor(event) {
activeColor = event.target.dataset.boxColorIs
}
function setThisBoxColor(event) {
let element = event.target
let the_existing_color_of_this_box = element.dataset.boxColorIs
if (the_existing_color_of_this_box == activeColor) {
delete element.dataset.boxColorIs
} else {
element.dataset.boxColorIs = activeColor
}
}
.box {
width: 100px;
height: 100px;
border: 1px solid black;
display: inline-block;
background: white;
}
[data-box-color-is="red"] {
background: red
}
[data-box-color-is="blue"] {
background: blue;
}
[data-box-color-is="yellow"] {
background: yellow;
}
<html>
<body>
<div id="box-1" class="box" data-box-color-is="red" onclick="setPickerColor(event)">1</div>
<div id="box-2" class="box" data-box-color-is="blue" onclick="setPickerColor(event)">2</div>
<div id="box-3" class="box" data-box-color-is="yellow" onclick="setPickerColor(event)">3</div>
<br>
<br>
<div id="box-4" class="box" onclick="setThisBoxColor(event)">4</div>
<div id="box-5" class="box" onclick="setThisBoxColor(event)">5</div>
<div id="box-6" class="box" onclick="setThisBoxColor(event)">6</div>
</body>
</html>
Using data- attributes you are able to decouple the JavaScript functional concerns form the CSS classes. This simplifies your logic but most importantly it allows folks styling your app to work independently from the folks adding JS functionality. This decoupling becomes really important when your team is using BEM or an OOCSS pattern.
Ideally instead of attaching styles to the data- attribute you would maintain the 'state' using data- and have another function that sets the classList based on the data- state. Allowing you to be 100% sure style changes you make will never effect JS functionality (QA will love you). But that's an evolution beyond this post.
With this setup we are not using the id's but I left them in because its an important best practice. Most likely this code would evolve into a component with listeners instead of inline onClick calls. JavaScript selectors should always be attached to id's or data- variables, never classes. Also, the id's should always be there for the QA team to utilize in their scripts. You risk some one changing a class name or removing it to adjust the styles and inadvertently breaking your JS listener.
I switched the arguments to pass the 'event' instead of the 'this' which is the element. Anyone using your JS event functions is going to expect the event object as the first parameter. You can pass 'this' as the second parameter if you like, but event.target will give you the same thing.
One other thing to note is the syntax change between declaring the data- variable and calling it from the JS.
HTML <div data-box-color-is="red">1</div>
JS event.target.dataset.boxColorIs
Regardless of how you format you data- attribute name it will always be parsed into camelCase when referencing it in JS ... data-box_color--IS would still become ... dataset.boxColorIs
Also as an evolution to your code you could remove the global JS var and store the value on the <body> or some other element on the page using data-. This will give you a single source of truth or 'state' that multiple features/components can reference without cluttering the global space.
Further Reading
https://css-tricks.com/bem-101/
https://en.bem.info/
https://philipwalton.com/articles/side-effects-in-css/
https://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/
https://philipwalton.com/articles/decoupling-html-css-and-javascript/

What would be the best way to make a sort of drop-down-more-info div?

I have 4 divs with a more-info button on the bottom of each, like so:
http://codepen.io/anon/pen/VpVbPq
And when a user presses ' more info ' I would like for it to extend to the bottom and show extra info, obviously.
The problem is under the more-info div, text is seen, but what if I want to hide whats under it, even if its opacity is 0.6 ?
I thought it would've been the best if I draw what I need, so here:
Codepen code below:
html
<body>
<div class="wrapper">
<div class="info">
<p>
dummy text
</p>
<div class="more-info">more info</div>
</div>
<div class="info"><div class="more-info">more info</div></div>
<div class="info"><div class="more-info">more info</div></div>
<div class="info"><div class="more-info">more info</div></div>
</div>
</body>
css
.wrapper {
width: 1045px;
margin: 0 auto;
}
.info {
width: 500px; height: 200px;
background-color: #1A5AB6;
display: inline-block;
margin: 10px;
position: relative;
font-size: 20px;
overflow: hidden;
}
.more-info {
width: 100%; height: 40px;
background-color: #0C1B44;
bottom: 0; left: 0;
display: inline-block;
position: absolute;
font-size: 20px;
color: white;
line-height: 35px;
text-align: center;
opacity: 0.6;
}
.more-info:hover {background-color: #010716;}
In order to have the text expand, you can use a little jQuery to set the height to automatically adapt to however much text there is, and hide the 'more info' button entirely:
$(".more-info").on("click", function() {
$(this).css("opacity", "0");
$(this).parent().css("height", "auto");
});
With regards to not having the text visible behind the 'more info' button, you would need to set the opacity to 1:
.more-info {
opacity: 1;
}
This naturally distorts the colour a little, but you can always change the background colour and hover colour to cover this.
I've created an updated pen showcasing this here.
Hope this helps! :)
change your class selector definition as shown below:
.more-info {
width: 100%; height: 20%;
background-color: #0C1B44;
font-size: 20px;
color: white;
display: block;
text-align: center;
opacity: 0.6;
}
Then add this css for your paragraph element:
p {
height: 75%;
overflow: hidden;
margin: 5px;
}
Your question: "what would be the best way to make a sort of drop-down-more-info div?"
There is a built in function in Boot Strap that allows you to use a "data" class that does all the crunching for you. Just call on their css and js files externally or host on your server. Familiarize yourself with their data classes and call on their css/js classes to simplify previously arduous coding, like revealing a hidden DIV on click!
Note the data-toggle="collapse" and data-target="#more_info" lines in my div that holds the span tag that is the control for revealing the hidden <div id="more_info">:
`<div data-toggle="collapse" data-target="#more_info"><span class="glyphicon glyphicon-search"></span> <span title="Click for more info">more info</span></div>`
Then note the class in my hidden div. Note the id of the hidden div and the data-target #more_info. This can be used for classes as well, ie: .more_info. Everything is explained in more detail at bootstrap Github or their official site: http://getbootstrap.com/
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"> </script>
</head>
<body>
<div class="wrapper">
<div class="info">
<p>
Honestly, Bootstrap would be the easiest way to accomplish this without a doubt. Just click the more info button below.
</p>
<div data-toggle="collapse" data-target="#more_info"><span class="glyphicon glyphicon-search"></span> <span title="Click for more info">more info</span></div>
<div id="more_info" class="collapse">Some hidden infomration you ony want to be seen when the user click on the control link.</div>
</div>
or add three divs floating perfectly without all the css, each with drop downs more info.
<body>
<div class="wrapper row">
<div class="col-md-4">
<p>
Honestly, Bootstrap would be the easiest way to accomplish this without a doubt. Just click the more info button below.
</p>
<div data-toggle="collapse" data-target="#more_info">
<span class="glyphicon glyphicon-search"></span>
<span title="Click for more info">more info</span> </div>
<div id="more_info" class="collapse">
Some hidden information you only want to be seen when the user click on the control link.
</div>
</div>
<div class="col-md-4">
<p>
Some other information we want to have a hidden drop down with more info for.
</p>
<div data-toggle="collapse" data-target="#more_info2">
<span class="glyphicon glyphicon-search"></span>
<span title="Click for more info">more info</span>
</div>
<div id="more_info2" class="collapse">
Some hidden information you only want to be seen when the user click on the control link.</div>
</div>
<div class="col-md-4">
<p>
Yet another div with info that has a drop down menu for more info included below.
</p>
<div data-toggle="collapse" data-target="#more_info3">
<span class="glyphicon glyphicon-search"></span>
<span title="Click for more info">more info</span>
</div>
<div id="more_info3" class="collapse">
Some hidden infomration you ony want to be seen when the user click on the control link.
</div>
</div>
Best of luck.

Button highlighting not working inside textarea [duplicate]

I need to be able to render some HTML tags inside a textarea (namely <strong>, <i>, <u>, <a>) but textareas only interpret their content as text. Is there an easy way of doing it without relying on external libraries/plugins (I'm using jQuery)?
If not, do you know of any jQuery plugin I could use to do this?
This is not possible to do with a textarea. You are looking for a content editable div, which is very easily done:
<div contenteditable="true"></div>
jsFiddle
div.editable {
width: 300px;
height: 200px;
border: 1px solid #ccc;
padding: 5px;
}
strong {
font-weight: bold;
}
<div contenteditable="true">This is the first line.<br>
See, how the text fits here, also if<br>there is a <strong>linebreak</strong> at the end?
<br>It works nicely.
<br>
<br><span style="color: lightgreen">Great</span>.
</div>
With an editable div you can use the method document.execCommand (more details) to easily provide the support for the tags you specified and for some other functionality...
#text {
width: 500px;
min-height: 100px;
border: 2px solid;
}
<div id="text" contenteditable="true"></div>
<button onclick="document.execCommand('bold');">toggle bold</button>
<button onclick="document.execCommand('italic');">toggle italic</button>
<button onclick="document.execCommand('underline');">toggle underline</button>
Since you only said render, yes you can. You could do something along the lines of this:
function render(){
var inp = document.getElementById("box");
var data = `
<svg xmlns="http://www.w3.org/2000/svg" width="${inp.offsetWidth}" height="${inp.offsetHeight}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml"
style="font-family:monospace;font-style: normal; font-variant: normal; font-size:13.3px;padding:2px;;">
${inp.value} <i style="color:red">cant touch this</i>
</div>
</foreignObject>
</svg>`;
var blob = new Blob( [data], {type:'image/svg+xml'} );
var url=URL.createObjectURL(blob);
inp.style.backgroundImage="url("+URL.createObjectURL(blob)+")";
}
onload=function(){
render();
ro = new ResizeObserver(render);
ro.observe(document.getElementById("box"));
}
#box{
color:transparent;
caret-color: black;
font-style: normal;/*must be same as in the svg for caret to align*/
font-variant: normal;
font-size:13.3px;
padding:2px;
font-family:monospace;
}
<textarea id="box" oninput="render()">you can edit me!</textarea>
This makes it so that a textarea will render html!
Besides the flashing when resizing, inability to directly use classes and having to make sure that the div in the svg has the same format as the textarea for the caret to align correctly, it's works!
Try this example:
function toggleRed() {
var text = $('.editable').text();
$('.editable').html('<p style="color:red">' + text + '</p>');
}
function toggleItalic() {
var text = $('.editable').text();
$('.editable').html("<i>" + text + "</i>");
}
$('.bold').click(function() {
toggleRed();
});
$('.italic').click(function() {
toggleItalic();
});
.editable {
width: 300px;
height: 200px;
border: 1px solid #ccc;
padding: 5px;
resize: both;
overflow: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="editable" contenteditable="true"></div>
<button class="bold">toggle red</button>
<button class="italic">toggle italic</button>
An addendum to this: You can use character entities (such as changing <div> to <div>) and it will render in the textarea.
But when it is saved, the value of the textarea is the text as rendered. So you don't need to de-encode. I just tested this across browsers (Internet Explorer back to version 11).
I have the same problem but in reverse, and the following solution. I want to put html from a div in a textarea (so I can edit some reactions on my website; I want to have the textarea in the same location.)
To put the content of this div in a textarea I use:
var content = $('#msg500').text();
$('#msg500').wrapInner('<textarea>' + content + '</textarea>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="msg500">here some <strong>html</strong> <i>tags</i>.</div>
This is possible with <textarea>.
You only need to use the Summernote WYSIWYG editor.
It interprets HTML tags inside a textarea (namely <strong>, <i>, <u>, and <a>).

Rendering HTML inside textarea

I need to be able to render some HTML tags inside a textarea (namely <strong>, <i>, <u>, <a>) but textareas only interpret their content as text. Is there an easy way of doing it without relying on external libraries/plugins (I'm using jQuery)?
If not, do you know of any jQuery plugin I could use to do this?
This is not possible to do with a textarea. You are looking for a content editable div, which is very easily done:
<div contenteditable="true"></div>
jsFiddle
div.editable {
width: 300px;
height: 200px;
border: 1px solid #ccc;
padding: 5px;
}
strong {
font-weight: bold;
}
<div contenteditable="true">This is the first line.<br>
See, how the text fits here, also if<br>there is a <strong>linebreak</strong> at the end?
<br>It works nicely.
<br>
<br><span style="color: lightgreen">Great</span>.
</div>
With an editable div you can use the method document.execCommand (more details) to easily provide the support for the tags you specified and for some other functionality...
#text {
width: 500px;
min-height: 100px;
border: 2px solid;
}
<div id="text" contenteditable="true"></div>
<button onclick="document.execCommand('bold');">toggle bold</button>
<button onclick="document.execCommand('italic');">toggle italic</button>
<button onclick="document.execCommand('underline');">toggle underline</button>
Since you only said render, yes you can. You could do something along the lines of this:
function render(){
var inp = document.getElementById("box");
var data = `
<svg xmlns="http://www.w3.org/2000/svg" width="${inp.offsetWidth}" height="${inp.offsetHeight}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml"
style="font-family:monospace;font-style: normal; font-variant: normal; font-size:13.3px;padding:2px;;">
${inp.value} <i style="color:red">cant touch this</i>
</div>
</foreignObject>
</svg>`;
var blob = new Blob( [data], {type:'image/svg+xml'} );
var url=URL.createObjectURL(blob);
inp.style.backgroundImage="url("+URL.createObjectURL(blob)+")";
}
onload=function(){
render();
ro = new ResizeObserver(render);
ro.observe(document.getElementById("box"));
}
#box{
color:transparent;
caret-color: black;
font-style: normal;/*must be same as in the svg for caret to align*/
font-variant: normal;
font-size:13.3px;
padding:2px;
font-family:monospace;
}
<textarea id="box" oninput="render()">you can edit me!</textarea>
This makes it so that a textarea will render html!
Besides the flashing when resizing, inability to directly use classes and having to make sure that the div in the svg has the same format as the textarea for the caret to align correctly, it's works!
Try this example:
function toggleRed() {
var text = $('.editable').text();
$('.editable').html('<p style="color:red">' + text + '</p>');
}
function toggleItalic() {
var text = $('.editable').text();
$('.editable').html("<i>" + text + "</i>");
}
$('.bold').click(function() {
toggleRed();
});
$('.italic').click(function() {
toggleItalic();
});
.editable {
width: 300px;
height: 200px;
border: 1px solid #ccc;
padding: 5px;
resize: both;
overflow: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="editable" contenteditable="true"></div>
<button class="bold">toggle red</button>
<button class="italic">toggle italic</button>
An addendum to this: You can use character entities (such as changing <div> to <div>) and it will render in the textarea.
But when it is saved, the value of the textarea is the text as rendered. So you don't need to de-encode. I just tested this across browsers (Internet Explorer back to version 11).
I have the same problem but in reverse, and the following solution. I want to put html from a div in a textarea (so I can edit some reactions on my website; I want to have the textarea in the same location.)
To put the content of this div in a textarea I use:
var content = $('#msg500').text();
$('#msg500').wrapInner('<textarea>' + content + '</textarea>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="msg500">here some <strong>html</strong> <i>tags</i>.</div>
This is possible with <textarea>.
You only need to use the Summernote WYSIWYG editor.
It interprets HTML tags inside a textarea (namely <strong>, <i>, <u>, and <a>).

Categories

Resources