How can I calculate a span's offset inside preformated text? - html

How can I calculate the offset of the first char of the substring My car is red relative to beginning of the predefined text (Burguer rocks.)?
<pre id="pref-text">
Burguer rocks. <span id="highlight-0">Without cheese please.</span>
Pizzaaaaaa time! <span id="highlight-1">My car is red.</span> blablabla.
</pre>

The HTMLElement.offsetLeft read-only method returns the number of pixels that the upper left corner of the current element is offset to the left within the HTMLElement.offsetParent node.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft
To answer your question
How can I calculate the offset of "My car is red"?
Use the javascript Element's .offsetLeft property.
alert(document.getElementById('highlight-1').offsetLeft);
<pre id="pref-text">
Burguer rocks. <span id="highlight-0">Without cheese please.</span>
Pizzaaaaaa time! <span id="highlight-1">My car is red.</span> blablabla.
</pre>

I solved it like that:
var span = document.getElementById('highlight-1');
var offset = 0;
var nextBlock = span.previousSibling;
while (nextBlock != null){
offset = offset + nextBlock.textContent.length;
nextBlock = nextBlock.previousSibling;
}

Related

Replace a specific set of special characters with text boxes and retrieve value from each of the text boxes

I'm trying to implement a scenario, where a student can answer fill in the blanks type question. There can be multiple number of blanks in a single question. The question is comping from API.
What I'm trying to achieve is, replacing each of the special characters with "text box", students can type their answers in that text boxes. When I'll save the answer, the entire string will be saved.
Eg:
Question: John ___ going ___ school. He is ___ good boy.
This should be rendered as:
John going school. He is good boy.
When sending it to API, I'll send this as a string, like John is going to school. He is a good boy.
How I'll achieve this in Angular with TypeScript..
Any help or idea to do this in other way, is really appreciated.
Thanks.
Here is a stackblitz
You need to split the question by ___ and then append an input after every index of the split result.
parts = [];
inputControls = [];
parts = this.question.split('___');
Then in your template
<div>
<span *ngFor="let p of parts; let i = index;">{{p}}
<span *ngIf="i < parts.length -1">
<input type="text" [(ngModel)]="inputControls[i]" /></span>
</span>
</div>
<div>
<button type="button" style="margin-top: 40px; background-color: green; color: white" (click)="submit()">Submit</button>
</div>
Inside submit method, compose your answer like
submit(){
let answer = '';
for(let i = 0; i < this.parts.length; i++){
answer += this.parts[i];
if(i < this.inputControls.length)
answer += this.inputControls[i];
}
console.log(answer);
}

RegEx Removing Span tags from HTML

I need some RegEx for removing span tags with a specific class including the end tag but don't want to remove what's in between ...
I do not want to remove any other span tags
I cannot come up with it since I tend to forget the RegEx Tricks :(
I have this
<span class="SpellE">system_user.user_name</span>
<span>This is some text</span>
<Span class="OtherCLass">Some other text</span>
<span class="SpellE">system_user.userid</span>
And I want this result
system_user.user_name
<span>This is some text</span>
<Span class="OtherCLass">Some other text</span>
system_user.userid
Yes I need to tidy up some messy MS Html :)
Thanks in advance
The following regex should match what you want:
<span class=\"SpellE\">(.*)</span>
It matches the span with class='SpellE', creating a Group of the span text.
Then you should replace the match with Group 1.
In JavaScript, you can use it like this:
var testStr = '<span class="SpellE">system_user.user_name</span>\n'
+ '<span>This is some text</span>\n'
+ '<Span class="OtherCLass">Some other text</span>\n'
+ '<span class="SpellE">system_user.userid</span>\n';
var regex = /<span class=\"SpellE\">(.*)</span>/gi;
var result = testStr.replace(regex, '\1');
Now the result should be your wanted output.

How to hide some text in string using CSS

Please find updated code
<html>
<title>css</title>
<head>
<style>
#st {
z-index: -114;
margin-right: -80px;
}
</style>
</head>
State Code : <span><span id="st"></span>Maharashtra - MH</span>
</html>
I got below output but i need clear overlapped text
enter image description here
the only way to approach this is using css display: none or visibility: hidden property , either one would work, i would advice display none. this is the only way CSS and HTML can hide data.
<span>State Code: <span id="st"><span style="display: none">Maharashtra - </span>MH</span></span>
You Can't do this by using CSS only here is the javascript solution for u
$("#st").html(function(){
var text= $(this).text().trim().split(" ");
var first = text.shift();
return (text.length > 0 ? "<span class='hide'>"+ first + "</span> " : first) + text.join(" ");
});
.hide {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>State Code: <span id="st">Maharashtra - MH</span></span>
see this is HTML version but it is working fine.
<span id="span_Id">Maharashtra - MH</span>
<script>
function getSecondPart(str) {
return str.split('-')[1];
}
var span_Text = document.getElementById("span_Id").innerText;
var html = getSecondPart(span_Text);
document.getElementById("span_Id").innerHTML = html;
</script>
Update 2
Layout has significantly changed...see 2nd updated demo.
Since OP has dynamically generated text, JavaScript is needed realistically. And probably the actual text will be more than one on the page.
This demo gathers all <span> nested within a <span> (could've used #id but realistically, it should be a .class). This NodeList is converted into an array.
This array is then map()'ped on each iteration a regex is matched vs. the <span>s text.
A replace()'ment of the unwanted portion of text is overwritten and the last 2 letters remain.
Demo
var tgt = Array.from(document.querySelectorAll('span'));
tgt.map(function(s, idx) {
var str = s.textContent;
var rgx = /(State Code:).*?- (\w\w)/g;
var rep = `$1 $2`;
var res = str.replace(rgx, rep);
s.textContent = res;
});
<span>State Code: <span class="st"></span>California - CA</span><br>
<span>State Code: <span class="st"></span>New York - NY</span><br>
<span>State Code: <span class="st"></span>Oregon - OR</span><br>
<span>State Code: <span class="st"></span>Mississippi - MS</span><br>
If you use PHP... try it below..
$string = explode("-","Maharashtra - MH");
<span>State Code: <span id="st"><span style="display:none;"><?php echo $sting[0]."-"; ?></span><?php echo $string[1]; ?></span></span>

html - Why my three buttons are vertical instead of horizontal?

Sorry for the confusing I caused. I did not paste my code because it is part of my big assignment. Also, I do not sure what parts of code cause the problem. So I paste the parts of the code that contains these three buttons
I want to make these three button display horizontally( Which I think is default). However, the website shows them vertically. Could anyone tell me the reason behind it? what should I do to make them horizontally.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</div>
<div id="Comparing Energy" class="tab">
<h3 style="color:darkblue;"> Units for comparing energy (Gasoline and Enthanol) </h3>
<p class="Sansserif">BTU stands for British Thermal Unit, which is a unit of energy consumed by or delivered to a building. A BTU is defined as the amount of energy required to increase the temperature of 1 pound of water by 1 degree Fahrenheit, at normal atmospheric pressure. Energy consumption is expressed in BTU to allow for consumption comparisons among fuels that are measured in different units. [think-energy.net]</p>
<pre class="Sansserif"><span style="font-family:sans-serif;">Below are some BTU content of common energy units:
1 gallon of heating oil = 138,500 BTU
1 cubic foot of natural gas = 1,032 BTU
1 gallon of propane = 91,333 BTU
</span></pre>
<p class="Sansserif"><b>Let's compare the different energy amount between burn gasoline and ethanol</b></p>
<button onclick="expandable()"><b>Calculate</b></button>
<p id="inputinfo" class="Sansserif" style="display:none"> By entering the amount of gasoline, this program will perform the appropriate calculations and display the equivalent amount of energy it produces in BTU. Please input a number: </p>
<input id="btu" style="display:none" onkeyup="myDefault()">
<button id="energybutton" onclick="energy()" style="display:none;"><b>Submit</b></button>
<button id="wizardbutton" onclick="wizard()" style="display:none;"><b>Wizard</b></button>
<button id="slidebutton" onclick="simple()" style="display: none;"><b>Simple</b></button>
<p id="numb2" style="display:none">
<input type=radio name=myradio onclick=document.getElementById("btu").value=1>Small<br>
<input type=radio name=myradio onclick=document.getElementById("btu").value=4>Medium<br>
<input type=radio name=myradio onclick=document.getElementById("btu").value=6>Large<br>
</p>
<p id="BTU"></p>
<p id="defaultValue"></p>
<script>
function energy() {
var x, text;
// Get the value of the input field with id="numb"
x = document.getElementById('btu').value;
j = x * 115000
t = x*76700
text = " "+x+" gallon of gas produces "+j+" BTU "+x+" gallon of ethanol produces "+t+" BTU";
document.getElementById("BTU").innerHTML = text;
}
function myDefault() {
var x = document.getElementById('btu').value;
if (x <= 10)
document.getElementById("defaultValue").innerHTML = "A typical small one is 5";
else if ((x > 10) && (x <= 20))
document.getElementById("defaultValue").innerHTML = "A typical medium one is 15";
else if (x > 20)
document.getElementById("defaultValue").innerHTML = "A typical large one is 25";
else
document.getElementById("defaultValue").innerHTML = " ";
}
function wizard() {
var v = prompt("By entering the amount of gasoline, this program will perform the appropriate calculations and display the equivalent amount of energy it produces in BTU. Please input a number: ");
if (v != null) {
document.getElementById('btu').value=v;
}
}
function simple() {
document.getElementById('btu').style.display='none';
document.getElementById('numb2').style.display='block';
}
function expandable() {
document.getElementById('inputinfo').style.display='block';
document.getElementById('btu').style.display='block';
document.getElementById('energybutton').style.display='block';
document.getElementById('wizardbutton').style.display='block';
document.getElementById('slidebutton').style.display='block';
}
</script>
</div>
</body>
</html>
display: inline-block;
This should solve your problem.
Hard to say without the rest of your code present, but probably some other CSS is causing the buttons to render as block elements instead of their standard inline display mode.
You could write the following CSS rule:
#energybutton, #wizardbutton, #slidebutton {
display: inline !important;
}
And it would probably solve it, but that seems a little ugly and the !important is undoubtedly overkill. If you'd like to provide some more context I or someone else could provide a more elegant answer, but my hunch is this might work for you.
Edit:
Seeing your exit with more code the issue is obvious- in your expandable method you are changing the buttons to display: block -- this is why they are displaying with breaks between then. Instead, set the display property to inline or inline-block to achieve the desired effect.
Incidentally, it might be more robust to hide/show the buttons not directly by directly manipulating styles in JS, but instead by adding/removing a class with the desired associated CSS set.
Change the display of your buttons to 'inline' instead of 'none'.
First I would place all the buttons within a div so you can property CSS them.
<div class="title_of_div">
<button id="energybutton" onclick="energy()" style="display:none"><b>Submit</b></button>
<button id="wizardbutton" onclick="wizard()" style="display:none"><b>Wizard</b></button>
<button id="slidebutton" onclick="simple()" style="display: none"><b>Simple</b></button>
</div>
Then your CSS would look something like this:
.title_of_div a {
display: block;
float: left;
height: 50px; <!-- You enter your own height -->
width: 100px; <!-- You enter your own width -->
margin-right: 10px;
text-align: center;
line-height: 50px;
text-decoration: none;
}

Angularjs : Selecting one span tag in one div selects another span tag ng-repeat

I have list of posts that gets displayed using ng-repeat. In this I have one question and multiple answers. Answers are displayed in span tag which behaves as option button. Here is the problem, if I select one answer (option button) from one question then similar numbered answer get selected in another question.
my code for html:
<div ng-repeat="post in posts" >
<form id="pollForm" ng-submit="submitPoll()">
<span class="quest"> <strong>Poll:</strong>{{post.question}}</span><br>
<div class="post-container">
<br>
<span ng-style="{'background-image':'url('+ img1 +')'}" ng-click="chgImg(1)"
class="Pollchoice--radio">
</span>
<span class="Pollchoice--text">{{post.choice1}}</span><br><br>
<span ng-style="{'background-image':'url('+ img2 +')'}" ng-click="chgImg(2)"
class="Pollchoice--radio"></span>
<span class="Pollchoice--text">{{post.choice2}}</span><br><br>
<span ng-style="{'background-image':'url('+ img3 +')'}" ng-click="chgImg(3)"
ng-show="post.choice3" class="Pollchoice--radio"></span>
<span ng-show="post.choice3" class="Pollchoice--text">{{post.choice3}}</span><br><br>
<span ng-style="{'background-image':'url('+ img4 +')'}" ng-click="chgImg(4)"
ng-show="post.choice4" class="Pollchoice--radio"></span>
<span ng-show="post.choice4" class="Pollchoice--text">{{post.choice4}}</span><br><br>
<hr/>
<div>
<button id="btn" type="submit" class="btn btn-default">Vote</button>
<span style="margin:0 0 0 20px"> 50,000 votes</span> • <span> 23 hours left</span>
</div>
<br>
</div>
<br><br><br>
</form>
</div>
javascript:
$scope.chgImg = function(varParam){
//alert(varParam);
if(varParam === 1){
$scope.img1 = "/images/chk.svg";$scope.img2 = undefined;
$scope.img3 = undefined;$scope.img4 = undefined;
}
if(varParam === 2){
$scope.img2 = "/images/chk.svg";$scope.img1 = undefined;
$scope.img3 = undefined;$scope.img4 = undefined;
}
if(varParam === 3){
$scope.img3 = "/images/chk.svg";$scope.img1 = undefined;
$scope.img2 = undefined;$scope.img4 = undefined;
}
if(varParam === 4){
$scope.img4 = "/images/chk.svg";$scope.img1 = undefined;
$scope.img2 = undefined;$scope.img3 = undefined;
}
};
Thanks in advance.
This problem happens due to there are many HTML tags that have the same id.
so you need to differentiate between every id.
for example you will add question id & answer id in order to make it unique.
OR
in your JSON data add a new property called ImageURL and set is undefiend
and in your binding
ng-style="{'background-image':'url('+{post.ImageURL}+')'}"
and in ng-click pass the object
ng-click="chkimg(post)"
and in chkimg function set the ImageURL with the value
post.ImageURL="/images/chk.svg";
IMO there are some problems with the code, you are iterating over posts array but not using post object in the param of chgImg also your ngrepeat would print as many img1, img2 img3 as many time it would iterate and hence when you set it in scope this would be ambiguous for the scope to reflect the change in any one div, solution to this would be through some index to be associated with the img1+postID something like this and then modify the method accordingly as well.
You can index each element using some index and keep incrementing that in ngrepeat, that way would make the elements unique and allow to keep and index.