I have a input box of type text and the input value have 2 words and I need to strike only the first word not the second one and unfortunately I can't edit html. I should do it using javascript and css only. I have tried using css text-decoration: line-through; but it striking both the words. any help is very much appreciated.
.text-blot { text-decoration: line-through; }
<input type='text' value='two words' class='text-blot'>
The value attribute within an input element can be accessed using JavaScript with HTMLElement.value. Unfortunately, styles will apply to the whole input value. So this is a bit tricky.
Since the value is a single string, which will contain two words. I used some JavaScript to split the string into array of words so then you can strike-through the first word using CSS with text-decoration: line-through and the second word can have text-decoration: none (no strike-through).
I wouldn't recommend this in a production environment, but I made it work by creating two span elements to hold the two words and styled them accordingly. I then gave the original input value a transparent text color with color: transparent and positioned the two span elements on top of the input value to achieve your desired first word strike-through second word without.
const textBlot = document.querySelector(".text-blot");
const demo = document.querySelector(".demo");
const word1 = document.createElement("span");
const word2 = document.createElement("span");
word1.setAttribute("class", "strike");
word2.setAttribute("class", "no-strike");
demo.appendChild(word1);
demo.appendChild(word2);
const arr = textBlot.value.split(" "); // create an array of words
word1.innerHTML = arr[0];
word2.innerHTML = " " + arr[1];
.text-blot {
/* text-decoration: line-through; */
z-index: 1;
color: transparent;
}
.strike {
text-decoration: line-through;
}
.no-strike {
text-decoration: none;
}
.demo span {
position: relative;
left: -9.5rem;
z-index: 99;
}
<div class="demo">
<input type='text' value='two words' class='text-blot'>
</div>
Related
N.B.: I should note that the proper solution to this is to just use the 'placeholder' attribute of an input, but the question still stands.
Another N.B.: Since, as Quentin explains below, the "value" attribute stores the default value, and the input.value IDL attribute stores the current value, the JavaScript I used to "fix" the problem in my below example is non-conforming, as it uses the (non-IDL) value attribute to store current, rather than default, values. Besides, it involves DOM access on every key press, so it was always just a flawed demo of the problem I was having. It's actually quite terrible code and shouldn't be used ever.
CSS selectors made me think that I could make an input with a label that acts as a preview without any JS. I absolutely position the input at 0,0 inside the label (which is displayed as an inline-block) and give it a background of "none", but only if it's got a value of "" and isn't focussed, otherwise it has a background colour, which obscures the label text.
The HTML5 spec says that input.value reflects the current value of an input, but even though input.value updates as you type into an input, CSS using the input[value=somestring] selector applies based only on what was explicitly typed into the document, or set in the DOM by the JavaScript setAttribute method (and perhaps by other DOM-altering means).
I made a jsFiddle representing this.
Just in case that is down, here is an HTML document containing the relevant code:
<!doctype html>
<head>
<meta charset="utf-8" />
<title>The CSS Attribute selector behaves all funny</title>
<style>
label {
display: inline-block;
height: 25px;
line-height: 25px;
position: relative;
text-indent: 5px;
min-width: 120px;
}
label input[value=""] {
background: none;
}
label input, label input:focus {
background: #fff;
border: 1px solid #666;
height: 23px;
left: 0px;
padding: 0px;
position: absolute;
text-indent: 5px;
width: 100%;
}
</style>
</head>
<body>
<form method="post">
<p><label>name <input required value=""></label></p>
</form>
<p><button id="js-fixThis">JS PLEASE MAKE IT BETTER</button></p>
<script>
var inputs = document.getElementsByTagName('input');
var jsFixOn = false;
for (i = 0; i < inputs.length; i++) {
if (inputs[i].parentNode.tagName == 'LABEL') { //only inputs inside a label counts as preview inputs according to my CSS
var input = inputs[i];
inputs[i].onkeyup= function () {
if (jsFixOn) input.setAttribute('value', input.value);
};
}
}
document.getElementById('js-fixThis').onclick = function () {
if (jsFixOn) {
this.innerHTML = 'JS PLEASE MAKE IT BETTER';
jsFixOn = false;
} else {
this.innerHTML = 'No, actually, break it again for a moment.';
jsFixOn = true;
}
};
</script>
</body>
</html>
I could be missing something, but I don't know what.
The value attribute sets the default value for the field.
The value property sets the current value for the field. Typing in the field also sets the current value.
Updating the current value does not change the value attribute.
Attribute selectors only match on attribute values.
There are new pseudo classes for matching a number of properties of an input element
:valid
:invalid
:in-range
:out-of-range
:required
A required element with no value set to it will match against :invalid. If you insist on using the value instead of placeholder, you could simply add a pattern or a customValidity function to force your initial value to be counted as invalid.
I am building an "autofill" function. When the user types something in an input field and the system finds this string in the database it should display the string into the input field in grey, similar to what google used to/still have/has.
Therefore I built two input fields, one that's clearly visible:
html:
<input id="email_input" type="text">
<input id="autofill" type="text">
css:
#email_input{
background-color: transparent;
z-index: 100;
}
Then I position the autofill input via JS exactly where email_input is.
function positionAutocompleteInput(){
var top = $('#email_input').position().top;
var left = $('#email_input').position().left;
$('#autofill').css({'top':top});
$('#autofill').css({'left':left});
}
positionAutoFillInput();
The actual autfill I do like this:
function autofill(context){
var input = $('#email_input').val();
var replacement = context[0].email;
replacement = replacement.slice(input.length);
var display = input + replacement;
$('#autofill').val(display)
}
I tried calling positionAutoFillInput(); onInput, so that it gets repositioned with each input. If I look at the positions of both input fields in the console, they both have the same positions.
Both input fields have the same font-size and font-family.
For some reason it still looks off:
Anyone know an answer?
Can you just position them with CSS like this? This way it requires no JavaScript to position it.
#autofill, #email_input {
font-size: 20px;
}
#autofill {
position: absolute;
color: #CCCCCC;
}
#email_input {
position: relative;
z-index: 1;
background: transparent;
}
<h1>Test</h1>
<div>
<input id="autofill" type="text" value="1234567890">
<input id="email_input" type="text">
</div>
I've been trying to randomize a number with a button, but every time I clicked the button, the number randomizes, but the text loses it's CSS style.
CSS
.numberStyle {
padding: 10px 10px 10px 10px;
color: blue;
}
.numberStyle span {
font-size: 100px;
}
Html
<class id="number1" class="numberStyle"><span>1</span></class>
<input type="button" value="MATCH!" style="font-size:50px;"></input>
Javascript
function randomize() {
no1 = Math.ceil(Math.random() * 3);
}
function print() {
$("#number1").text(no1);
}
$().ready(function() {
$(":input").click(function() {
randomize()
print()
alert("Change")
})
})
my JSFiddle link : https://jsfiddle.net/he4rtbr0ken/9jfud4nz/2/
You want to change the text within the span rather than #number1
function print() {
$("span").text(no1);
}
You are targeting the parent of the <span> element and then changing its text which is essentially removing the span and replacing it with only the number. You can fix this by targeting the span or including the span in the text you are adding.
Thanks for the answer!
I've targeted <span> element and it works.
replaced print() function with the codes below.
function print() {
$("#number1 > span").text(no1);
}
How to skip a word in a hyperlink?
Imagine a random ordered sequence of words:
... Word 1 Word 2 Word3 ...
How would it be possible to have 1 unifying (i.e. not 2 seperate links) hyperlink on Word 1 & Word 3?
I.e.: when one hovers either Word 1 or Word 3, the spectator can immediately notice that the hyperlink will lead to a page that covers the meaning of both these words (visible by whatever the CSS of a:hover is in a particular document).
The result would be:
... Word 1 Word 2 Word3 ...
CRUCIAL REMARK: But then instead of having 2 seperate (in this case bold-formatted hyperlinks), they would be unified into 1 single hyperlink. Again: this could e.g. be visualised in CSS by having a text-decoraiton:underline on a:hover, covering Word 1 and Word 3 simultaneously.
Optionally:
It would be good to also have the possibility to add a second, other hyperlink to Word 2.
Use-case example:
In the sentence:
"This does not need any open (Word 1) bladder (Word 2) surgeries (Word 3)."
It would be nice to have 1 unifying hyperlink on Word 1 and Word3. This example clarifies the usefulness of such a word-skipping-hyperlink: Word 2 certainly shouldn't be included in the first unifying link, since the urinary bladder-Wikipedia han't got much to do with the open surgeries-Wikipedia.
The result would be:
"This does not need any open bladder surgeries."
CRUCIAL REMARK: Instead that the hyperlink on open and surgeries should be unified into one single hyperlink.
Optionally:
It would be good to also have the possibility to add a second, other hyperlink to Word 2:
"This does not need any open bladder surgeries."
The CRUCIAL REMARK from above, also applies here.
You cannot have one link that spans two separate words.
You can have one link on each of the words point to the same location and use a little bit of JavaScript to highlight all the links that have the same destination when the user hovers over one.
For convenience I'm using jQuery here, but the same thing isn't difficult to do without it.
$(function () {
function getKey(element) {
return element.href;
}
function sameGroupAs(element) {
var key = getKey(element);
return function () {
return getKey(this) === key;
}
}
$(document)
.on("mouseenter", "a", function () {
$("a").filter(sameGroupAs(this)).addClass("active");
})
.on("mouseleave", "a", function () {
$("a").filter(sameGroupAs(this)).removeClass("active");
});
});
a.active {
background-color: #A8C5FF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>"This does not need any open bladder surgeries."</p>
I've used the href as a grouping key, but you can use any other method of groping. Just modify the getKey() function.
Here's a pure HTML + CSS method. The trick is applying a negative z-index to the second word. That makes it unclickable:
a {
text-decoration: none;
}
a span:nth-child(1), a span:nth-child(3) {
font-weight: bold;
}
a:hover span:nth-child(1), a:hover span:nth-child(3) {
text-decoration: underline;
}
a span:nth-child(2) {
position: relative;
z-index: -1;
}
This does not need any
<a href="">
<span>open</span>
<span>bladder</span>
<span>surgeries</span>
</a>
.
If you want the second word to have a different link, I think you need to duplicate the HTML, making the first instance position: absolute, and the second word of the second instance position: relative. You can then change formatting based on hover:
a {
text-decoration: none;
font-weight: bold;
}
#a1 {
position: absolute;
}
#a2 span:nth-child(2) {
position: relative;
}
#a1:hover span:nth-child(1), #a1:hover span:nth-child(3) {
text-decoration: underline;
}
#a2:hover span:nth-child(2) {
text-decoration: underline;
}
This does not need any
<a id="a1" href="http://en.wikipedia.org/wiki/Invasiveness_of_surgical_procedures#Open_surgery">
<span>open</span>
<span>bladder</span>
<span>surgeries</span>
</a>
<a id="a2" href="http://en.wikipedia.org/wiki/Urinary_bladder">
<span>open</span>
<span>bladder</span>
<span>surgeries</span>
</a>
.
With Javascript it's easy - create a span for each word, style the two outer spans to look like links, and attach a single click function to both spans.
HTML
<span id = "one">one,</span>
<span id = "two">two,</span>
<span id = "three">three</span>
CSS
#one, #three {
cursor:pointer;
}
jQuery
$('#one, #three').click(function() {
location.href = 'http://www.google.com';
});
$('#one, #three').hover(function() {
$('#one, #three').css('text-decoration', 'underline');}, function(){
$('#one, #three').css('text-decoration', 'none');
});
using pure CSS, you can have one link that spans multiple words, and have only some of them clickable.
(and you can make it look nicer than my demo using some more CSS)
This answer doesn't fully meet the OP needs because it doesn't allow a different link within the context of the first link, but it's still worth mentioning.
In order to have one link only that spans multiple words, and also have a nested element that points to another link, we'd have to allow anchor tag nesting, but it's not supported, the best way to achieve the same behavior is to split the "big" anchor tag to pieces (manually or with JS like suggested in other answers)].
a span
{
color: black;
pointer-events: none;
}
first <span>second</span> third
The simplest way to go is maybe this css rule:
a {
text-decoration:none;
color:red;
}
span {
color:black;
cursor:default;
}
and a short inline js onclick event where you don't want the event propagated:
<span onclick="return false;"> Word2 </span>
jsFiddle example
But don't do that in production.
It's pointless and ugly.
If you want the second link inside the first one, for the sake of simplicity, i would do this:
<span onclick="document.location.href = 'YOUR_2ND_LINK_HERE'; return false;"> Word2 </span>
updated jsFiddle
Here you go then
new fiddle with visual hint
If this is what you want to achieve then:
Html:
<a href="http://www.wikipedia.org">
<span class="d">Link 1</span>
<span class="b">Link 2</span>
<span class="d">Link 1</span>
<span class="b">Link 2</span>
<span class="d">Link 1</span>
<span class="b">Link 2</span>
</a>
Css
a {
text-decoration:none;
}
.d {
color:blue;
text-decoration:underline;
}
.d.fake-hover {
background:blue;
color:#fff;
text-decoration:none;
}
.b {
color:darkRed;
text-decoration:underline;
}
.b.fake-hover {
background:darkRed;
color:#fff;
text-decoration:none;
}
Javascript:
var elems = document.getElementsByClassName('d');
var otherElems = document.getElementsByClassName('b');
var allElems = document.getElementsByTagName('span');
var _href = 'http://stackoverflow.com';
function fakeIt(what, el) {
var els = (el.classList.contains('d')) ? elems : otherElems;
for (var i = 0, x = els.length; i < x; i++) {
(what == 'hover') ? els[i].classList.add('fake-hover') : els[i].classList.remove('fake-hover');
}
}
function addCustomLink(e) {
e.preventDefault();
location.href = _href;
}
for (var i = 0, x = allElems.length; i < x; i++) {
var el = allElems[i];
el.addEventListener('mouseover', function(e) {
fakeIt('hover', e.target);
});
el.addEventListener('mouseout', function(e) {
fakeIt('out', e.target);
});
if (el.className == 'b') {
el.addEventListener('click', function(e) {
addCustomLink(e);
});
}
};
In jsFiddle apparently I can't use document.location.href so you have to manually edit the addCustomLink function.
Fiddle here
I am trying to make a textarea that only will type in caps, even if the user isn't holding down shift or has caps lock on. Ideally this would accept the input no matter what and just automatically shift it to all caps. Most of the ways I am thinking of seem kind of clunky and would also show the lowercase before it gets converted.
Any suggestions or strategies?
you can use CSS
textarea { text-transform: uppercase; }
however, this only renders on the browser. let's say if you want to inject the text into a script or db in the textarea as all caps then you'll have to use javascript's toUpperCase(); before injection or form submit.
here is the jsfiddle for example:
html:
<textarea>I really like jAvaScript</textarea>
css:
textarea{
text-transform: uppercase;
}
javascript:
var myTextArea = document.getElementsByTagName('textarea');
for(var i=0; i<myTextArea.length; i++){
console.log('Textarea ' + i + ' output: ' + myTextArea[i].innerHTML); //I really like jAvaScript
console.log('Textarea ' + i + ' converted output: ' + myTextArea[i].innerHTML.toUpperCase()); //I REALLY LIKE JAVASCRIPT
}
CSS:
textarea { text-transform: uppercase; }
Quintin,
Create a style in your CSS such as the following:
textarea{
text-transform:uppercase;
}
Try adding a
textarea{
text-transform: uppercase;
}
to the text area.
Add you can get it
CSS:
textarea { text-transform: uppercase; }
This can be achieved with the oninput attribute, like so:
<textarea oninput="this.value = this.value.toUpperCase()">
<label for="upperCaseTextArea" style="display:block;">
Upper Case Text Area
</label>
<textarea
id="upperCaseTextArea"
name="upperCaseText"
rows="5"
cols="15"
oninput="this.value=this.value.toUpperCase()"
>
</textarea>