Boolean test HTML textbox input compared to array values - javascript

I am trying to create a single textbox form on a webpage to boolean test the input submitted by the user. The input will be the website user's zip code. I want to make a predetermined array of zip codes that will test true.
If it is true (the zip code entered is included in the predetermined array), I want to display one bit of HTML, and if it tests false, I want to display another bit.
I've searched around and looked in some of my JavaScript books (I've just started learning) and haven't found an answer; could someone help me out with this? Thanks!

HTML:
<label id="input-label" class="invalid">
ZIP code: <input id="zipcode" />
<div class="valid-message">
Valid
</div>
<div class="invalid-message">
Invalid
</div>
</label>
CSS:
#input-label.valid .valid-message { display: block; }
#input-label.valid .invalid-message { display: none; }
#input-label.invalid .valid-message { display: none; }
#input-label.invalid .invalid-message { display: block; }
Javascript
function isValidZip(z) {
return ['12345','67890'].indexOf(z) != -1;
}
var label = document.getElementById('input-label');
var input = document.getElementById('zipcode');
input.onkeydown = function() {
label.className = isValidZip(input.value) ? "valid" : "invalid";
}

You could try something like this(might be a little off I'll double check then get back to you :) ):
var zipArr = ['98671','97006'];//insert the zip/post codes here
var userInputEl = document.getElementById('userInput');//Get the element could use tag names or it would be better actually if you used jQuery but yeah
var elToShow = document.getElementById('elementToShowIfNotFound');
var otherElToShow = document.getElementById('idOfOtherelementToShow');
var userInput = userInputEl.value();//might be .text()
if(zipArr.indexOf(userInput) === -1){//-1 means it isn't found in the array
zipArr.push(userInput);//pushes the new one onto the array
elToShow.style.display = 'block';//this changes the css display to block instead of it being hidden.
}else{
otherElToShow.style.display= 'block';
}
Might not be the best way to do this, but I'd suggest using jQuery it makes this process a lot easier.

Related

replace a image in html with using of java script

I don't understand what am I doing wrong here, I try to debug the code, but I did not found what I did wrong here.
I tried to replace the image in html with using of java script, I would appreciate some useful help for my problem
Html code:
<img id = "lamp" src = "js/Capture.PNG"/>
<!--make a button to turn on or off the lamp in this case -->
<button id = "off" name = "offf" onclick="change_attribute()" >Turn off the light</button>
<button id = "on" name = "offf" onclick="change_attribute()"> turn on the light </button>
Javacript code:
function change_attribute() {
var x = document.getElementsByName("offf");
if (x.id === "off")
{
document.getElementById('off').src = "js/Capture.PNG/";
}
else
{
document.getElementById('on').src = 'js/Capture2.PNG/'
}
}
The getElementsByName() method returns a collection of all elements in the document with the specified name. you are trying to reference an id property which doesn't exist in the array but on the actual array elements.
You should propbably refactor your code to use a single html element which calls the change_attribute() and it will toggle the state respectively between on and off.
getElementsByName() returns an array of HTML elements that specifies the given condition.
In your condition you are getting array of buttons html element as a result of which, when you are accessing x.id then it is giving error as x is array, rather than object.
try to refactor your code and call change_attribute from one place only
function change_attribute(e) {
if (e.target.id === "off")
{
document.getElementById('lamp').src = "https://cdn-icons-png.flaticon.com/512/2910/2910914.png";
}
else
{
document.getElementById('lamp').src = 'https://cdn-icons-png.flaticon.com/512/702/702797.png'
}
}
#lamp{
width: 50px;
height: 50px;
margin-right:15px;
}
<img id="lamp" src ="https://cdn-icons-png.flaticon.com/512/2910/2910914.png"/>
<!--make a button to turn on or off the lamp in this case -->
<button id="off" class="lightBtn" onclick="change_attribute(event)" >Turn off the light</button>
<button id="on" class="lightBtn" onclick="change_attribute(event)"> turn on the light </button>

Selectively adding and removing values of same CSS property

I’m creating an Open Type features tester using jquery and want to give the user the possibility of seeing several open type features applied at the same time.
The first dropdown sets the property to font-feature-settings: ‘frac’ 1;, he second dropdown sets the property to font-feature-settings: ‘smcp’ 1;
Currently if both of the dropdowns are active one overrides the instructions of the other one. What I need is that if both of them are active at the same time the property is set to font-feature-settings: ‘frac’ 1, ‘smcp’ 1; and consequently if only one of them is deactivated only the corresponding value is removed from the property.
Note: I'm aware that the Open Type features don't work when I link the font from the Google fonts site, so I've been testing it with it installed.
Thanks in advance.
.font-tester{
color: #000;
line-height: normal;
width: 100%;
word-wrap: break-word;
padding-top: 30px;
}
<style> #import url('https://fonts.googleapis.com/css2?family=EB+Garamond&display=swap'); </style>
<div class="tester-container">
<select id="tester-figures">
<option value="none" selected>Default</option>
<option value="'frac' 1">Fractions</option>
</select>
<select id="tester-smcp">
<option value="none" selected>Default</option>
<option value="'smcp' 1">Small caps</option>
</select>
<div class="font-tester" contenteditable="true" spellcheck="false" style="font-family: 'EB Garamond', serif; font-size:65pt;">
abc 123
</div>
</div>
<script>
$("#tester-figures").change(function() {
$('.font-tester').css("font-feature-settings", $(this).val());
});
$("#tester-smcp").change(function() {
$('.font-tester').css("font-feature-settings", $(this).val());
});
</script>
There are many ways to solve a task. Additional here is an alternative solution which has less and more simplyfied and code.
It works with only one function which add the change event to both selects. On change it reads out the actual values from both selects and builds a simple css string based on the actual values of both selects.
$('#tester-figures').add('#tester-smcp').each( function(){
const $this = $(this);
$this.change(function(){
let actualVals = {};
actualVals.TesterFigures = $('#tester-figures').val();
actualVals.TesterSmcp = $('#tester-smcp').val();
let myVal = '';
if('none' == actualVals.TesterFigures){
myVal = 'none' == actualVals.TesterSmcp ? '' : actualVals.TesterSmcp;
}else {
myVal = 'none' == actualVals.TesterSmcp ? actualVals.TesterFigures : actualVals.TesterFigures + ', ' + actualVals.TesterSmcp;
}
$('.font-tester').css("font-feature-settings", myVal);
});
});
NOTE: I don't have worked with css attribute font-feature-settings yet. So I don't have any experience with this special item. What I notice is, that the strings in the selects (i.e. 'frac' 1) changes. The inner quotes and the number get lost when the css is added to the html element. But the style still works without them. Maybe you like to check if it works if you only use frac and smcp in your selects. In actual FF it works ;-)
What you need to do is basically concatenate the values into a comma-separated string as you update them, instead of just whatever the input value is. You could write your own function to do this if you wanted to. It would have to include logic for whether there is only one value or multiple values in order to make sure you don't end up with a trailing comma for no reason. However, there's an easier way: if we store the values in an array, we can use Array.join(), which will automagically handle that logic for us.
Array.join() joins all the elements in an array into one big string, and it takes an optional parameter that specifies how to join them. So we can do like so:
['one', 'two', 'three'].join(', '); // => 'one, two, three'
Note how there's not an extra comma and space at the end.
So now that we know how to get the end result, we just need to work on getting the values. You will need to either add elements to the array or remove them based on how you interact with the dropdowns. Since you only have two items in each dropdown right now, that logic can be pretty simple. If you are going to have multiple items in any dropdowns, the overall approach is the same, but you'll have to tweak the if…else part in the snippet below.
Keep in mind that, if you want to remove an item from the array, you need to know what to remove. But that's the old value. If you run $(myInput).val() inside your .change() function, you're going to get the current value. So you need to keep track of the old values separately.
Once you have the new array set up, you just have to apply the Array.join() magic and then you have your string that you can use in the jQuery .css() function.
It will be much easier to maintain this if you cut out as much repeated logic as possible and just have one single function that the inputs can each call. So I've done that for you below. You can add more inputs to the .each() function by chaining on more .add()s before it, if you need to.
let oldValues = ['none', 'none']; // whatever the default values are for each select
let currentValue = [];
const getNewValue = input => {
const val = $(input).val();
const index = input.index();
const oldValue = oldValues[index];
if (val !== 'none') {
currentValue.push(val);
} else {
const indexOfValue = currentValue.indexOf(oldValue);
currentValue.splice(indexOfValue, 1);
}
oldValues[index] = val;
const newCssValue = currentValue.join(', ');
console.clear();
console.log(`new value is "${newCssValue}"`);
return newCssValue;
};
$(function() {
const $fontTester = $('.font-tester');
$('#tester-figures').add('#tester-smcp').each(function() {
const $this = $(this);
$this.change(function() {
const newCssValue = getNewValue($this);
$fontTester.css('font-feature-settings', newCssValue);
});
});
});
.font-tester {
color: #000;
line-height: normal;
width: 100%;
word-wrap: break-word;
padding-top: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tester-container">
<select id="tester-figures">
<option value="none" selected>Default</option>
<option value="'frac' 1">Fractions</option>
</select>
<select id="tester-smcp">
<option value="none" selected>Default</option>
<option value="'smcp' 1">Small caps</option>
</select>
<div class="font-tester" contenteditable="true" spellcheck="false" style="font-family: 'EB Garamond', serif; font-size:65pt;">
abc 123
</div>
</div>

How to display/hide a div in another html page

I have two html pages (produse.html and item.html) and a menu in one of them. When I click a link from the menu I need to go to the other page and in the same time display a specific div and hide the original one from item.html.
I tried it with javascript using onclick method, but it doesn't work. I think the problem is that the javascript code can't get the class name of a div that is in another page.
Can there be something done?
This is the code that I tried.
produse.html
<div class="sideMenu">
prod 1
prod 2
prod 3
prod 4
</div>
item.html
<div class="displayBox yes">
1
</div>
<div class="displayBox">
2
</div>
<div class="displayBox">
3
</div>
<div class="displayBox">
4
</div>
javascript
var prevN = 0;
function displayTheBox(n){
var products = document.getElementsByClassName("displayBox");
products[prevN].className = products[prevN].className.replace(" yes", "");
products[n].className += " yes";
prevN = n;
}
css
.displayBox{
float: left;
height: 200px;
overflow: auto;
position: relative;
box-shadow: 1px 1px 4px 2px #9b9b9b;
background-color: #bbe5f8;
border-radius: 6px;
width: 995px;
margin: 0 0 0 235px;
display: none;
}
.yes{
display: block;
}
JS is a client-side script and it's variables are reset on page load. You can either pass the values by passing as GET parameters or by saving and retriving persistent data using localStorage or cookies.
Here is a simple js function to get GET variables and process function.
function findGetParameter(parameterName) { // Gets the GET variables
var result = null,
tmp = [];
var items = location.search.substr(1).split("&");
for (var index = 0; index < items.length; index++) {
tmp = items[index].split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
}
return result;
}
if(findGetParameter("item")) { // Check if parameter matches
displayTheBox(findGetParameter("item"));
}
var prevN = 0;
function displayTheBox(n) {
var products = document.getElementsByClassName("displayBox");
products[prevN].className = products[prevN].className.replace(" yes", "");
products[n].className += " yes";
prevN = n;
}
Change your hyperlinks to
<div class="sideMenu">
prod 1
prod 2
prod 3
<a href="item.html?item=3">prod 4<a>
</div>
For more info on storage methods, check this SO question What is the difference between localStorage, sessionStorage, session and cookies?
For a good example on js session storage, check this answer to a SO question here https://stackoverflow.com/a/49805713/6060602
Actually, when you're making a function call in a page, it can't be reflected in another one. You've to use backend for that job. But as per your problem is concerned, you may use a language like PHP for doing this job.
Otherwise, you can make a function call at the beginning when the new page is opened.
like,
window.onload()
or jQuery may also be helpful in this case,
$(document).ready(function() { /* code here */ });
That is impossible through normal click events like that.
Two pages will need to interact and since requests are stateless, everything that belongs to one page only really lives in there and nowhere else.
So to perform that, you will need to pass the communication through the request object.
Options:
First - Either create a form line this:
<form action="targetPage" method="get">
<input type="hidden" value="hideSomething" />
<button></button>
</div>
Then inside your TargetPage, retrience the query string from the URL, FInd out more about this here
Second - Either you're not sure if that is the right approach you want to take. Look closer into what you're trying to achieve and see if it's really necessary. I am not sure why you're trying to put those buttons( sideMenu ) on their own page seperate from where the boxes you're trying to control are.

Using checkboxes to update UI in realtime

I'm currently in the process of trying to develop a smarter UI for one of my clients. However the only code I can use to develop this 'feature', is pure JS. I have no access to the source HTML or CSS files the only access I have is the ability to inject JavaScript through an external .js file.
I'm not too familiar with JS, but I can work my way around a basic script or two.
Scenario
What we're doing is allowing users to edit PDF Templates online using a software called Core Create. The UI accessed through the browser is quite cluttered and I would like to provide an option to hide and show UI elements <textareas>/<inputs> through the use of checkboxes.
Here is a very basic JS Fiddle that I have built with the
intention of hiding and displaying UI.
The page in question
Above is a screen grab of the page I am working with, on the left you can see the UI and its composition on the right within the 'Inspect Element' tool.
I have come to the conclusion that I need to iterate through the highlighted selection and link them accordingly with seven checkboxes. The result would then be a selection of checkboxes that would hide / display the correct UI element.
The Caveat
In realizing I cannot edit or introduce new HTML I noticed the lack of on-click attributes. So I'm a bit lost on how to invoke the JavaScript I will eventually build.
My Question
With my limited knowledge of JS I don't know how I would iterate though div elements editoraccvar - editoraccvar6 picking out the ones I need to manipulate.
Due to the lack of ID's / Names (I assume it would have to be done using Parent/Child rules somehow, as the classes are widley used by the rest of the UI. I would appreciate a small example demonstrating how I could achieve this, so I can learn from it.
I should clarify, I have already added the checkboxes to the page, I just need to build the JS link between the Checkbox and the UI element I'm attempting to target. You can find all attributes linking to these checkboxes included in the JS Fiddle.
EDIT // A Working Simplified Example;
Due to some confusion I have 'frankensteined' some code together to show the final result I am after. A working example of sorts. The actual result needs to target 7 Checkboxes and 7 Divisions. I'll list thier common properties below.
// This script is already in place and constructed by the system.
// Written inside script tags and located straight after 'editopt1'.
// $(document).ready(function() {
// $('#checkboxopt1').click(function() {
// if ($('#checkboxopt1').val() == 'true') {
// $('#opt1').val('false');
// $('#checkboxopt1').val('false');
// $('#checkboxopt1').prop('checked', false);
// $('#previewrefresh').trigger('click');
// } else {
// $('#opt1').val('true');
// $('#checkboxopt1').val('true');
// $('#checkboxopt1').prop('checked', true);
// $('#previewrefresh').trigger('click');
// };
// });
// });
function exFunction() {
// Check the function is called
console.log("200 : OK");
// grab all elements with the class, .field-summernote
var uiblocks = document.querySelectorAll('.field-summernote');
for (var i = 0; i < uiblocks.length; i++) {
var current = uiblocks[i];
if (current.className.indexOf('editoraccvar') < 0) //not found: -1
return;
// check elements in the array
console.log(current);
// control the elemets in the array.
if (document.getElementById('checkboxopt1').checked) {
uiblocks[0].style.display = 'block'; // display the element
} else {
uiblocks[0].style.display = 'none'; // hide the element
}
}
};
// Trigger the collection the check, and the control.
var x = document.getElementById("checkboxopt1");
x.addEventListener("click", function() {
console.log("Opt");
exFunction();
});
.editoraccvar1 {
width: 300px;
background: #0ff;
padding: .5em;
}
.editoropt1 {
width: 300px;
background: #ff0;
padding: .5em;
}
textarea {
display: block;
width: 95%;
resize: none;
padding: .5em;
}
<!-- I'm trying to hide & show this entire division... -->
<div class="seq-box-form-field field-summernote editoraccvar1 ">
<label for="accvar1">Ground Floor Info</label>
<div class="clearfix"></div>
<textarea id="richaccvar1" name="richaccvar1" class="summernote"></textarea>
<input type="hidden" name="accvar1" id="accvar1" value="" />
</div>
<!-- Using only what the system has supplied. -->
<div class="seq-box-form-field editoropt1 ">
<label for="opt1"><span style="padding-right: 10px; vertical-align: 1px;">Ground Floor </span>
<input type="checkbox" name="checkboxopt1" id="checkboxopt1" value="true" checked="true" />
<input type="hidden" name="opt1" id="opt1" value="true" />
</label>
</div>
Divisions <div class=""></div>
* editoraccvar,
editoraccvar1,
editoraccvar2,
editoraccvar3,
editoraccvar4,
editoraccvar5,
editoraccvar6*
Checkboxes <input id=""></input>
* checkboxopt,
checkboxopt1,
checkboxopt2,
checkboxopt3,
checkboxopt4,
checkboxopt5,
checkboxopt6,*
As far as I can see, your problem boils down to link checkboxes (that seem to have been generated in some way) to "division" parts of your html that you want to hide. Plus, you have to inject javascript code in the page (so I guess the less code the better).
One approach could be as follows:
// Wrap the code in an anonymus function, to avoid clustering the global space.
(function (domElements) {
// This is the callback that will fire when a checkbox is clicked.
function clickCallback() {
// the context of this callback is the DOM element thus we can access its attributes through this.
// extract the checkNumber of the class of the element. This number is the link to the division that we want to hide/show.
var checkNumber = ((/ editoropt(\d*) /).exec(this.className))[1],
checkBox = document.getElementById('checkboxopt' + checkNumber),
division = document.querySelectorAll('.editoraccvar' + checkNumber)[0];
// Hide/show division, update checkBox state.
toggleElements(division, checkBox, window.getComputedStyle(division).display === 'none');
}
function toggleElements(division, checkBox, isShown) {
// Toggle the division (show/hide) accordingly.
division.style.display = isShown ? 'block' : 'none';
// Due to the fact that the event listener is attached to the parent of the checkBox, we need to maintain consistency manually.
checkBox.checked = isShown;
}
// Remove from the array of DOMElements those that aren't checkboxes and add a click event listener to each of them.
domElements
.filter(function (el) {
return el.className.indexOf('editoropt') !== -1;
})
.forEach(function (el) {
el.addEventListener('click', clickCallback, false);
});
// Call the function passing the dom elements with class '.seq-box-form-field' as argument. Checkboxes are contained within them. Also, transform the nodelist
// into a proper array so that methods defined in Array.prototype can be used.
})([].slice.call(document.querySelectorAll('.seq-box-form-field')));
The code is commented and (I think) quite self-explanatory. However, if you have any doubt or want me to elaborate any point further, please, let me know.
Finally, here's the working fiddle.
UPDATE
Same function (more or less) but now it accepts an array of values that will correspond to the initial state of the checkboxes:
(function (domElements, cbState) {
function clickCallback() {
toggleElements(this.className);
}
function toggleElements(className, initialShow) {
var checkNumber = ((/ editoropt(\d*) /).exec(className))[1],
checkBox = document.getElementById('checkboxopt' + checkNumber),
division = document.querySelectorAll('.editoraccvar' + checkNumber)[0],
isShown = initialShow === undefined ? window.getComputedStyle(division).display === 'none' : initialShow;
division.style.display = isShown ? 'block' : 'none';
checkBox.checked = isShown;
}
domElements
.filter(function (el) {
return el.className.indexOf('editoropt') !== -1;
})
.forEach(function (el, index) {
el.addEventListener('click', clickCallback, false);
toggleElements(el.className, cbState[index]);
});
// Initial state of the checkboxes goes in the second parameter. The index in the array correspond to the checkbox position in the page.
})([].slice.call(document.querySelectorAll('.seq-box-form-field')), [false, false]);
Here's the Fiddle to play with. Hope it helps.
The other half of your problem, not addressed in the other answer has to do with events. Generally, adding an "onclick" attribute to the actual HTML is considered bad practice. You can attach event handlers with Javascript.
var a = document.getElementById("checkboxopt1");
a.addEventListener("click", exFunction, false);
See the manual for more info about how to use this.
Looks like that you need the elements that have the class "field-summernote", but not the class "editorbdyvar".
You can use a query selector to get elements by class name using the default tools from Javascript:
var items = document.querySelectorAll('.field-summernote');
for(var i = 0; i<items.length; i++){
var current = items[i];
if( current.className.indexOf('editoraccvar') < 0) //not found: -1
return;
//now you can manipulate the current element
console.log(current);
}
well ... you should either learn javascript, DOM, HTML and CSS or hire an somebody that can do it.
in my opinion the latter would come cheaper.
if not,
here goes something to put in your script.js file.
the checkboxes must have the id="toggleTextareas" respectively id="toggleInputs".
(function isolateScope() {
tryInit();
function tryInit() {
if(document.readyState!="complete"){
setTimeout(tryInit, 100);
}else{
createUI();
init();
}
}
function createUI(){
var div=document.createElement("div");
div.className="addon-floating-toolbar"
div.style.position="fixed";
div.style.zIndex="999999";
div.style.background="#EEE";
div.style.padding="5px";
div.innerHTML='<input type="checkbox" id="toggleTextareas">toggle Textareas<br>'
+'<input type="checkbox" id="toggleInputs">toggle Inputs';
document.body.appendChild(div);
}
function init() {
var tta=document.getElementById("toggleTextareas");
var ti=document.getElementById("toggleInputs");
var textareaVisible=true;
var inputVisible=true;
tta.onclick=toggleTextareas;
ti.onclick=toggleInputs;
function toggleTextareas() {
var elms=document.querySelectorAll("textarea");
textareaVisible=!textareaVisible;
if (textareaVisible) {
show(elms);
}else{
hide(elms);
}
}
function toggleInputs() {
var elms=document.querySelectorAll("input");
inputVisible=!inputVisible;
if (inputVisible) {
show(elms);
}else{
hide(elms);
}
}
function show(collection) {
for (var i = 0; i < collection.length; i++) {
collection[i].style.display="";
}
}
function hide(collection) {
for (var i = 0; i < collection.length; i++) {
collection[i].style.display="none";
}
}
}
})();
let me know if it works,
cheers.
You can traverse all your fields and generate a checkbox that will toggle it open/close for each of your fields. Also set the checkbox label as innerText of the corresponding field.
// Block to be run
generateCheckboxes = function() {
var button = document.getElementById("generateButton");
button.parentNode.removeChild(button);
// grab all elements with the class, .field-summernote
var uiblocks = [].slice.call(document.querySelectorAll('.field-summernote')).filter(function(x) {
return x.className.indexOf('editoraccvar') >= 0
});
if (!uiblocks.length) return;
var chcontainer = document.createElement('div');
chcontainer.style.display = "inline-block";
document.body.insertBefore(chcontainer, document.body.children[0]);
uiblocks.forEach(function(x) {
var cdiv = document.createElement('div');
var clabel = document.createElement('label');
clabel.innerHTML = x.innerText.trim();
var cinput = document.createElement('input');
cinput.type = 'checkbox';
cinput.checked = true;
cinput.onchange = function(ev) {
var checked = this.checked;
x.style.display = checked ? "" : "none";
}
cdiv.appendChild(clabel);
cdiv.appendChild(cinput);
cdiv.appendChild(document.createElement('br'));
chcontainer.appendChild(cdiv);
})
};
#container {
width: 150px;
}
input {
float: left;
}
label {
width: 120px;
display: block;
float: right;
text-align: left;
}
<button onclick="generateCheckboxes()" id="generateButton">Generate Checkboxes</button>
<div id="example" class="field-summernote editoraccvar">
<br/>
<br/>
<span>Zero</span>
<br/>
<textarea></textarea>
</div>
<div id="example1" class="field-summernote editoraccvar1">
<br/>
<br/>
<span>One</span>
<br/>
<textarea></textarea>
</div>
<div id="example2" class="field-summernote">
<br/>
<br/>
<span>Two</span>
<br/>
<textarea></textarea>
</div>
Fiddle

How to set input:focus style programatically using JavaScript

I'm building a UI library in JS that can, without relying on any CSS stylesheets, create UI components, stylised from code. So far, it's been quite easy, with exception of styling different control states (such as input:focus one).
Code that I use to create input field:
function newInput()
{
var ctr = docmuent.createElement("input");
ctr.setAttribute("type","text");
ctr.setAttribute("value", some-default-value);
ctr.style.fontFamily = "sans-serif,helvetica,verdana";
/* some font setup here, like color, bold etc... */
ctr.style.width = "256px";
ctr.style.height = "32px";
return ctr;
}
Styling it for default state is easy. However I am unsure how to set style for states such as focused, disabled or not-editable.
If I'd be having CSS stylesheets included in the project that would be easily sorted out. However I can't have any CSS files included, it must be pure JS.
Does anyone know how to set style for an input field state (eg. input:focus) straight from JS code?
No JQuery please :-) Just straight-up JS.
Thanks in advance!
You would need to add an event listener to the element in order to change the style of it. Here is a very basic example.
var input = document.getElementById("something");
input.addEventListener("focus", function () {
this.style.backgroundColor = "red";
});
<input type="text" id="something" />
Other alternative would be to build a stylesheet for the page.
Something like this:
var styles='input:focus {background-color:red}';
var styleTag=document.createElement('style');
if (styleTag.styleSheet)
styleTag.styleSheet.cssText=styles;
else
styleTag.appendChild(document.createTextNode(styles));
document.getElementsByTagName('head')[0].appendChild(styleTag);
This way you will have clean separation of css styles from the scripts and so the better maintenance.
Use CSS Variables if possible
It's 2022 and there are more simple solutions to this problem than adding event listeners all over the place that may never get cleaned up.
Instead if you have control over the CSS simply do this in your CSS:
.my-class {
--focusHeight: 32px;
--focusWidth: 256px;
}
.my-class:focus {
height: var(--focusHeight);
width: var(--focusWidth);
}
Then in your JavaScript it's as simple as using setProperty to update the variables:
const el = document.getElementById('elementId');
el.style.setProperty('--focusHeight', newFocusHeight);
el.style.setProperty('--focusWidth', newFocusWidth);
At first, create your input:
<input type="text" id="myElementID" />
Then add the javascript the following javascript:
const element = document.getElementById("myElementID");
// Add a box shadow on focus
element.addEventListener("focus", (e) => {
e.target.style.boxShadow = "0 0 0 3px #006bff40";
});
// Remove the box shadow when the user doesn't focus anymore
element.addEventListener("blur", (e) => {
e.target.style.boxShadow = "";
});
A quick oneliner, which dynamically appends a style tag to the
body.
document.body.innerHTML += '<style>#foo:focus {background-color:gold}</style>'
<input id="foo"/>
let input = document.querySelector(".input-text");
let label = document.querySelector('.fields-label');
input.addEventListener('focus', function(e){
label.classList.add('is-active');
})
input.addEventListener('blur', function(e){
if(input.value === "") {
label.classList.remove('is-active');
}
})
label.is-active{
color:red;
}
<div class="input-fields">
<label class="fields-label">Last Name</label>
<input type="text" class="input-text">
</div>

Categories

Resources