Highlight selected text from JSONPath using CSS - javascript

I am using JSONPath to select some elements from a JSON file. I want the selected elements to be displayed on an html page. (The entire JSON should be displayed with only the selected tags highlighted)
The final result should look like the
XPath Evaluator in the Defient.js site.
So far, I've managed to use the JSONPath to select the element I want and get it as the output. Also, I can use JSON.stringify in a <pre> tag to print the JSON to the webpage.
What I want to know is how I should go about highlighting the selected text. The output can't be simply used to generate a regex because it might match fields that are not selected by the JSONPath filter.

As you've told that you can get the path, it'll be just matter of wrapping the value for the corresponding path with a html tag and give a class. Then you can highlight with css.
pre {
background-color: ghostwhite;
border: 1px solid silver;
padding: 10px 20px;
margin: 20px;
}
.json-key {
color: brown;
}
.json-value {
color: navy;
}
.json-string {
color: olive;
}
<pre><code id="planets">[
{
<span class="json-key">name</span>: <span class="json-string">"Earth"</span>,
<span class="json-key">order</span>: <span class="json-value">3</span>,
<span class="json-key">stats</span>: {
<span class="json-key">life</span>: <span class="json-value">true</span>,
<span class="json-key">mass</span>: <span class="json-value">5.973600000000001e+24</span>
}
},
{
<span class="json-key">name</span>: <span class="json-string">"Saturn"</span>,
<span class="json-key">order</span>: <span class="json-value">6</span>,
<span class="json-key">stats</span>: {
<span class="json-key">life</span>: <span class="json-value">null</span>,
<span class="json-key">mass</span>: <span class="json-value">5.6846e+26</span>
}
}
]</code></pre>
Example replacer - but not necessarily.

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>

Get data from a nested span element

I want to make platform to learn CSS kind of like code-academy, I want to have some client-side code validation. Using codemirror I managed to do a codepen-like app and now I want to implement the validation. My Idea was to use take advantage of the editor format to create an object and then compare that object with one of my own with the correct answer.
For example:
This is what the user puts on the editor:
.container {
/* Your code goes here */
padding: 10px;
display: flex;
justify-content: center;
align-items: center;
}
Each of those lines translate to the following
<span class="cm-qualifier">.container</span> {
<span class="cm-comment">/* Your code goes here */</span>
<span class="cm-property">padding</span>: <span class="cm-number">10px</span>;
<span class="cm-property">display</span>: <span class="cm-atom">flex</span>;
<span class="cm-property">justify-content</span>: <span class="cm-atom">center</span>;
<span class="cm-property">align-items</span>: <span class="cm-atom">center</span>;
}
With javascript I would like to get the text line by line, my problem is that I don't know how to get the value from inside the span tag and outside of it.
This is what I did to get that working.
let data;
window.onload = function() {
dataBlock = document.querySelectorAll('.CodeMirror-lines')[0];
data = dataBlock.querySelectorAll("span[role='presentation']");
let dataArr = Array.from(data).map(x => {
console.log(x.innerHTML);
});
}
I have one idea, to split the innerHTML from the character '<' to the character '>' and so on. But I believe there should be a better approach. Thanks in advance.

Hide certain content from a parent element but show child in CSS

I have the following code on a Wordpress Woocommerce website which outputs "From £189.00"
I am trying to remove the word "From". I'm sure there must be a simple way using something like .price:pre {display:none;}.
<p class="price">From: <span class="woocommerce-Price-amount amount"><span class="woocommerce-Price-currencySymbol">£</span>189.00</span></p>
How can I hide the word "From" from this code, ideally using CSS? I am open to javascript in the functions.php as an alternative.
Due to the restrictive nature of Wordpress and the code it outputs, I'm unable to edit the snippet above. I have to manipulate the above code in CSS or in the functions.php
You can use font-size to hide the text, then overwrite it for the child span elements like so:
.price {
font-size: 0px;
}
.price span {
font-size: 16px;
}
<p class="price">From: <span class="woocommerce-Price-amount amount"><span class="woocommerce-Price-currencySymbol">£</span>189.00</span>
</p>
Since this is already said to be impossible, have a look at https://stackoverflow.com/a/23247837/1587329. Short answer:
.price>.woocommerce-Price-amount
{
visibility: visible;
}
.price
{
visibility: hidden;
width: 0;
height: 0;
margin: 0;
padding: 0;
}
jsfiddle thanks to #Anthony's comment.
Like this:
.price {display:none;}
<p class="price">From: </p>
<span class="woocommerce-Price-amount amount">
<span class="woocommerce-Price-currencySymbol">
£
</span>189.00
</span>
change the format of your html
<p class="price"><span class="from">From:</span> <span class="woocommerce-Price-amount amount"><span class="woocommerce-Price-currencySymbol">£</span>189.00</span></p>
and apply css like
.price .from {display:none;}

Multiple RGB string to color boxes

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>

Nested text links in HTML

In HTML nested links are not permitted. However, for my purpose (text notes which sometimes refer to whole sentences and sometimes to just one single word within already anotated sentences) I need them. So I have to find a way to solve this problem.
However, all I have now is a basic idea on how it should look and behave. The following mock up shows two links: one to target A, one to B. The "outer" a link is, the lower is the line under it. A is the outer link, thus, its line is lower than that of B. Clicking on the lines of a link should always lead to the target of that link - even if the text above that line is the text of an inner link.
I've tried to show that intended behaviour with hover colors: Blue for A, pink for B.
Any ideas how I could realize this in HTML with the help of CSS (and maybe SVG?). I'd prefer solutions without scripting, but any suggestions are welcomed.
You can use <span>s inside links:
a {color: #00f; border-bottom: 1px solid; text-decoration: none;}
a span {color: #66f; text-decoration: underline;}
Hello, this is link. This is <span>inner link</span> here.
A small problem or extra work is, you need JavaScript to make them follow the links.
But as you asked, you can get the UI Effect without any scripting, but the following of link, definitely needs scripting!
Expanding on the answer from #connexo, you can wrap them all in a span and use a border-bottom on that.
.split-link {
border-bottom:1px solid blue;
padding-bottom:1px; /* for visual reference only */
}
.split-link a {
text-decoration: none;
}
.split-link a.inner-link {
text-decoration: underline;
text-decoration: red;
color:red;
}
<span class="split-link">
Hello, this is a link. It has an
inner link
here.
</span>
You will want to stay within valid HTML, so your only chance (aside of JS) is splitting the outer link into two links.
Hello, this is link. This is inner link here.
.inner-link { color: #66f; text-decoration: underline; }
This will split the blue line in your example into two parts as well, which I assume you do not want. But it's not possible otherwise.
Use JavaScript for best results
I know:
I'd prefer solutions without scripting,
but…
any suggestions are welcomed.
You can add an inline onclick handler to a child span:
AAAA <span onclick="event.preventDefault(); window.location.assign('#B'); return false;">BBBB</span> AAAA
Or, to be DRY, pass in a reference to the handler instead:
AAAA <span onclick="embedLink('#B');">BBBB</span> AAAA
Definition of handler:
function embedLink(url) {
event.preventDefault();
window.location.assign(url);
return false;
}
Working example:
a {
display: inline-block;
text-decoration: none;
color: blue;
border-bottom: 1px solid blue;
padding: 1px;
}
a .annotation {
color: fuchsia;
border-bottom: 1px double fuchsia;
background-color: white;
}
a:hover {
background-color: lightblue;
}
a .annotation:hover {
background-color: lightpink;
}
AAAA <span data-href="#B" class="annotation" onclick="event.preventDefault(); window.location.assign(this.getAttribute('data-href')); return false;">BBBB</span> AAAA
With JS, you can handle other possibilities as well:
Open in new window. Use: window.open() instead of window.location.assign().
Copy to clipboard. Add an event listener to the context and copy events on the parent link. In the handler, use document.execCommand('copy') to grab the url from the clicked child span instead; perhaps its URL is stored in a data-href attribute.
Display URL in status bar. Add a mouseover event listener. In the handler, set window.status = url.
Thank your all for your answers! They all have inspired me!
After some hard thinking and merging your answers together I came to the following solution whose greatest advantage is that the basic functions of all links work without JavaScript.
My main idea is to wrap all links inside a <span> element and, as connexo has suggested, to split up those links which contain links themself. Thus, the HTML skeleton of my above example looks like this:
<span>
<a>AAA</a>
<span><a>BBB</a></span>
<a>AAA</a>
</span>
All JavaScript is associated just with the <span>. Onmouseover, it removes the hover-class from all ancestor <span>. Onclick, it takes the url of the first link child and redirects there.
The CSS is rather simple. It removes the underline from links and defines just how the span should look like (and behave in case of hover).
Another advantage of this design is that nested nested links are also supported, as you can see in the snippet below.
function link_span_click(current_element,current_event)
{
current_event.preventDefault();
current_event.stopPropagation();
var target_href = current_element.getElementsByTagName('a')[0].href;
window.location.assign(target_href);
}
function link_span_mouse_over(current_element)
{
while (current_element)
{
current_element.parentNode.classList.remove('link_span_hover');
current_element = current_element.parentNode;
}
var target_href = current_element.getElementsByTagName('a')[0].href;
window.status = target_href;
}
function link_span_mouse_out(current_element)
{
while (current_element)
{
current_element.parentNode.classList.add('link_span_hover');
current_element = current_element.parentNode;
}
window.status = '';
}
a.nested_link {
text-decoration: none;
}
span.link_span {
cursor: pointer;
display: inline-block;
padding-bottom: 3px;
background-color: white;
border-bottom: 1px solid blue;
}
span.link_span_hover:hover {
background-color: lightblue;
}
<div>
<span
class="link_span link_span_hover"
onclick="link_span_click(this, event)"
onmouseout="link_span_mouse_out(this)"
onmouseover="link_span_mouse_over(this)"
>
AAA
<span
class="link_span link_span_hover"
onclick="link_span_click(this, event)"
onmouseout="link_span_mouse_out(this)"
onmouseover="link_span_mouse_over(this)">
BBB
</span>
AAA
</span>
</div>
<div>
<span
class="link_span link_span_hover"
onclick="link_span_click(this,event)"
onmouseout="link_span_mouse_out (this)"
onmouseover="link_span_mouse_over (this)">
AAA AAA AAA AAA
<span
class="link_span link_span_hover"
onclick="link_span_click(this, event)"
onmouseout="link_span_mouse_out(this)"
onmouseover="link_span_mouse_over(this)">
BBB BBB
<span
class="link_span link_span_hover"
onclick="link_span_click(this, event)"
onmouseout="link_span_mouse_out(this)"
onmouseover="link_span_mouse_over(this)">
CCC
</span>
BBB BBB
</span>
AAA AAA AAA AAA
</span>
</div>
Still, there remains one problem: If a rather long textlink gets split up into to lines only the second (or last to be precise) line gets underlined.

Categories

Resources