Get data from a nested span element - javascript

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.

Related

Highlight selected text from JSONPath using CSS

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.

Aligning numbers at decimal point angular ui grid

I am looking at aligning numbers on the decimal point in Angular UI Grid like below.
11.293
.89
233424
.34345
I have had a few ideas including a cell template with three aligned divs and using transparent 0s.
Has anyone had any luck with this.
I think that the best way is to select all the numbers with Javascript, then break them and encapsulate them in 2 span elements like this:
<div>
<span class="int">11.</span><span class="float">293</span>
</div>
<div>
<span class="int">233424.</span><span class="float">89</span>
</div>
Then you can assign a with to the elements and align the .int to right and .float to the left with css:
.int, .float{
display: inline-block;
width: 100px;
}
.int{
text-align: right;
}
.float{
text-align: left;
}
This way the selection is ok and div and span doesn't disturb the meaning of your html5 code. Also, you do not deppend on a fixed width font.
Hope this works, if not, please let me know.
In my component.ts file I added a method splitNumbers, which converts each number into a array with the integer and fractional part:
splitNumbers() {
return this.numbers.map(number => {
let str = number.toString();
return str.split(".");
});
}
In my component.html I added separate <span> elements to the integer and fractional parts. Don't use whitespace between the tags unless you want extra whitespace in your output:
<li *ngFor="let parts of splitNumbers()">
<span class="integer">{{ parts[0] }}</span>.<span class="fractional">{{ parts[1] }}</span>
</li>
Then in the CSS I set the integer part to inline-block, give it a width and make it align right:
.integer {
text-align: right;
width: 10em;
display: inline-block;
}
The result:
As you can see the last number is very small and written in scientific notation instead of expanded. So this doesn't work perfectly.

html text field to have pre appended text which is not modifiable

I would like to have a text field which has pre appended text which is not modifiable.
So when user tries to add text it starts after the pre text.
Also when the form is submitted it should not pass the pre appended text. Its mainly for display purpose but within the text field. I have attached the image which will clarify my question further. For example I would like to add "$" as pre text in the image below. Any help is greatly appreciated.
Note: the $ is dynamic text and so could not be image.
I've made a fiddle with two solutions, both using CSS.
The first uses a data URI of a PNG that contains a dollar sign for the background image of the text input. The second uses a label containing a dollar sign and shifts it over to be on top of the input (you probably should use a span instead of a label, for accessibility's sake).
HTML:
<input type="text" id="bob" />
<br/>
<label for="fred">$</label><input type="text" id="fred" />
CSS:
#bob {
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAG1BMVEX///8AAAC/v7/f398/Pz8fHx9/f3+fn59fX19QuZN1AAAAbElEQVQokWNgGFyASRiN7ygYhiKgGCYW6IAs4KgsYCqELCDKLMCehCwQyCyAamhjM5qAiaC4AqpIiaAoqgizuKMQqoAAuwgytxxoiyiSABvQHcwoKgSVBVjEkI1IlEDzCzu6bxnQnY4pQFsAAC/cCbAPkBI2AAAAAElFTkSuQmCC') no-repeat;
background-size: contain;
padding-left: 1.1em;
}
label[for="fred"] {
position: relative;
left: 15px;
z-index: 1000;
font-size: smaller;
}
#fred {
padding-left: 1.2em;
}
Both of these methods are hacky. A JS solution would be more involved, but handle much more nicely (I just don't have time to implement one).
Here's a neat way using background-image
http://jsfiddle.net/dxu2s/1/
HTML:
<label for="RefundAmount">Enter a refund amount: </label>
<input type="text" name="RefundAmount" id="RefundAmount">
CSS:
#RefundAmount {
margin: 0;
padding: 0 0 0 25px;
width: 100px;
height: 25px;
background: #FFF url(http://oi57.tinypic.com/nmncz5.jpg) no-repeat left center;
}
I've also tried using the css psuedo-element :before but it didn't work as input tags doesn't have content in em'.
This is a class i wrote you can use it for free, i didnt test it a lot. if you find a bug let me know
HTML: <input type="text" id="inputA" value="$" />
in script add this Class constructor
//***************************************************************
//-------------------------------------- Class halfEditable_INPUT
//***************************************************************
//-- divides an Input into an non editable area from 0 to index, but not including the index, the rest is editable
//-----------------------------------------------------
//-------- constructor
//-----------------------------------------------------
function halfEditable_INPUT (inputField,index)
{
if (typeof index=="undefined") index=inputField.value.length;
//------------------------------------ PUBLIC Objects, Properties
this.element=inputField;
this.index=index;
//-- a reference to the instance of the halfEditable_INPUT class saved in the html element, to get instance values in DOM events
Object.defineProperty (inputField,"halfEditable_instance",{value:this,writable: false, enumerable:true, configurable:true});
//-- get the value of the input directly
Object.defineProperty (this,"value", {get:this.PRIVATE_getValue,set:this.PRIVATE_setValue});
inputField.addEventListener ("keydown",this.PRIVATE_checkStatus_ONKEYDOWN);
}
//-----------------------------------------------------
//-------- prototype
//-----------------------------------------------------
//------------------------------------ PRIVATE Methods
/* this --- points to the input field
checks if the cursorPosition is in the non Editable area or is at the limit Point
if it is at the limitPoint - dont allow backspace or cursor left
if it is inside allow nothing and move cursorPosition to the limit
reset the Position1 key to index */
halfEditable_INPUT.prototype.PRIVATE_checkStatus_ONKEYDOWN=function (event)
{
var keyCode=event.keyCode;
var index=this.halfEditable_instance.index;
var selectionStart=this.selectionStart, selectionEnd=this.selectionEnd;
if (keyCode==36) //-- position1 key
{
event.preventDefault();
this.setSelectionRange (index,index);
return;
}
if (selectionStart<index)
{
if (selectionEnd>index) this.setSelectionRange (index,selectionEnd);
else this.setSelectionRange (index,index);
}
else if (selectionStart==index) {if (keyCode==8 || keyCode==37) event.preventDefault();} //-- backspace, left cursor
}
halfEditable_INPUT.prototype.PRIVATE_setValue=function (value) {this.element.value=value;}
halfEditable_INPUT.prototype.PRIVATE_getValue=function () {return this.element.value;}
//-----------------------------------------------------
//-------- prototype -- END
//-----------------------------------------------------
//***************************************************************
//-------------------------------------- Class halfEditable_INPUT -- END
//***************************************************************
var inputA=new halfEditable_INPUT(document.getElementById ("inputA"));
if you have further questions let me know.

How to account for user-entered typos in a JavaScript prompt?

First off, hello! I'm new to this website so I apologize for any errors that I make posting-wise.
I am in a web technology class where we are learning JavaScript. In a previous class we learned HTML5 and CSS. Our current assignment is to make a webpage that will either display 1 of 3 images or no images when the user enters the corresponding word in the prompt window.
I was wondering if there was a way to account for user-entered typos? For example, I have in the code "Spn" but was wondering if there was a way to easily make it so that if a user were to enter "Son" by mistake, they would still be shown the image.
Is there a way to do this without having to add a separate if statement?
Below is the code I have so far, which includes my little "test" to see if I could do this. I thought it had worked when I only had two items (ex: "Spn, "spn"), but when I added a third it stopped working, and now it isn't working again. I may have very well been mistaken that there was ever a success, though.
Oh, also, we are only allowed to use JavaScript, HTML, and CSS. So if you have a solution that is jquery (I have no idea what that is), then thank-you, but I'm afraid I can't use it.
Please let me know if there is any other information that you need and I will gladly supply it to you. Thank-you very much for your help, I very much appreciate it!
-Carly
JavaScript Code (file name is switch.js):
var temp = "None";
function choose()
{
temp = prompt("Spn, DW, SH, or None?");
if (temp == "Spn","spn")
{
document.getElementById("picture").src="first.jpg";
document.getElementById("sub").innerHTML="Supernatural";
document.getElementById("picture").style.visibility="visible";
};
if (temp == "DW","dw","Dw")
{
document.getElementById("picture").src="second.jpg";
document.getElementById("sub").innerHTML="Doctor Who";
document.getElementById("picture").style.visibility="visible";
};
if (temp == "SH","sh","Sh")
{
document.getElementById("picture").src="third.jpg";
document.getElementById("sub").innerHTML="Sherlock";
document.getElementById("picture").style.visibility="visible";
};
if (temp == "None","none")
{
document.getElementById("picture").src="blank.jpg";
document.getElementById("sub").innerHTML="Click button to reveal image";
document.getElementById("picture").style.visibility="hidden";
};
}
HTML Code (file name is userchoice.html):
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="switch.js"></script>
<title>What is this not working I'm going to cry</title>
</head>
<body>
<h1>SuperWhoLock</h1>
<h2 id="sub">Click button to reveal image</h2>
<div id="picblock">
<img src="blank.jpg" id="picture">
</div>
<div id="buttons">
<button onclick="choose()">Choose Picture</button>
</div>
</body>
</html>
CSS code (the file name is style.css):
body
{ background-image:url('background.jpg');
}
h1
{ width: 25%;
text-align: center;
margin-left: auto;
margin-right: auto;
background: black;
color: white;
}
h2
{ width: 25%;
text-align: center;
margin-left: auto;
margin-right: auto;
background: white;
color: black;
}
#picblock
{ width: 25%;
text-align: center;
margin-left: auto;
margin-right: auto;
}
#picture
{visibility:hidden;
}
#buttons
{ text-align: center;
margin-left: auto;
margin-right: auto;
}
Barring the foray into putting intelligence in the code, I will give a rather simplistic approach, detailed below:
Since you are the one who is deciding that "Son" should pull up the image ideally meant for "Spn", we should use a mapping that is created by you yourself. We can have something like this:
`
var spn = "Spn", dw ="DW",sh="SH";
//creating a custom mapping
var dict = {
"Son":spn,
"Sln":spn,
"Spn":spn,
"DW":dw,
"DE":dw,
"SH":sh
}
//Your if would look like:
temp = (dict && dict[temp])?dict[temp]:null;
if (temp && temp.toLower() == "spn")
`
2. For creating that dictionary, you will just have to consider the characters around the letter that you are typing.
Note: This approach assumes you have only these three things to compare. If you want a more generic solution that should work beyond Spn,DW,SH, None, please let me know.

CSS incompetent - cannot figure out why my page is rendering the way it is

To preface, I am utterly incompetent with CSS. However, I have been watching/reading tutorials, and still cannot figure out why my page would render the way it is. I'm hoping that this will be quick and obvious for somebody here.
I want the page to be shaped something like this:
Filter by: CPM Owner: [DROPDOWN] CP: [DROPDOWN] Series: [DROPDOWN]
[APPROVE SELECTED] [REJECT SELECTED]
[there's a table down here, but it isn't relevant to the question]
However, it looks like this when I load the page:
EDIT: I changed the flexbox container to a span instead of a div, and now the page looks like:
There are all kinds of newlines I don't want, and strange spacing being put before the dropdowns. Here are the relevant bits of CSS, JS, and HTML that are making this part of the page:
HTML:
<div id="filters">
<span id="filter_dropdowns_label" class="dropdowns_bar_label">
Filter by:
</span>
<ul id="filter_dropdowns" class="dropdowns_bar">
<!-- populated by changerequest.js -->
</ul>
</div>
<ul id="buttons_top" class="buttons">
<li><input type="button" value="Approve Selected" id="approve_button_top" class="approve_button" onclick="approveSelected()"/></li>
<li><input type="button" value="Reject Selected" id="reject_button_top" class="reject_button" onclick="rejectSelected()"/></li>
</ul>
CSS:
.dropdowns_bar {
margin: 0;
padding: 0;
list-style-type: none;
}
.dropdowns_bar li {
display: inline;
}
.buttons li {
display: inline;
}
.hidden_column {
display: none;
}
#filters {
display: inline;
}
And the JS:
// Create a dropdown
function createDropdown(id, label, data, defaultValue) {
// initialize elements
listEl = document.createElement('li');
flexboxContainerEl = document.createElement('div');
spanEl = document.createElement('span');
// setup dropdown
$(flexboxContainerEl).flexbox(data);
$(flexboxContainerEl).attr('id', id);
if (defaultValue != null) {
$(flexboxContainerEl).setValue(defaultValue);
}
// setup label
$(spanEl).html(label + ':');
// add to document
$(listEl).append(spanEl);
$(listEl).append(flexboxContainerEl);
$('#filter_dropdowns').append(listEl);
}
// Creates and populates the filter dropdowns, selects default if present
function createDropdowns() {
createDropdown('cpm_dropdown', 'CPM Owner', cpmList, cpmDefault);
createDropdown('cp_dropdown', 'CP', cpList, cpDefault);
createDropdown('series_dropdown', 'Series', seriesList, seriesDefault);
}
Sorry, I realize that this question is very much "help, my code's broken, fix it." I am just spending a lot of time looking at CSS tutorials and documents and I cannot find anything resembling my problem.
EDIT: Modified my CSS according to this answer: https://stackoverflow.com/a/17417451/1532702
The page now looks like:
I've tried swapping the .appends, but nothing affects the order on the labels. Obviously, they should be in front of each of the corresponding inputs.
EDIT: I solved my problem by just rewriting that portion as a table instead of a list. Made everything much, much simpler.
EDIT: Ok, better answer I think. Try this:
.dropdowns_bar li {
display: inline-block;
}
.buttons {
display:block;
margin-top:10px;
}
.buttons li {
display: inline-block;
}

Categories

Resources