Change backgroundcolour of input after onblur automatically across page - javascript

I would like an input field to have the background colour changed after onblur. Automatically for all fields on every page. So I am hoping for a script in the header that will automatically affect all input fields.
Can this be done?
Thanks!

window.onload = function(){
Array.prototype.slice.call(document.getElementsByTagName('input')).forEach(function(element){
element.addEventListener('blur',function(){
//anything here. Notice that both this and element refer to each input element.
})
});
}
document.querySelectorAll or any function returning a NodeList object can be used.

since you start up in an "onblur" state, you should listen to the focus/click event, not the blur event
add css
input{ /*Blurred state*/
background-color: red;
}
.onFocus input{ /*clicked state*/
background-color: green;
}
add some javascript
$(input).
click(function(e){
body.className="onFocus";
}).
blur(function(){
body.className="";
});

It can certainly be done. Because you've demonstrated no attempt, I'm choosing to assume you're willing to support the latest/up-to-date browsers (rather than all legacy browsers):
function colorOnBlur(){
this.style.backgroundColor = '#f00';
}
var inputs = document.querySelectorAll('input');
for (var i = 0, len = inputs.length; i < len; i++){
inputs[i].addEventListener('blur', colorOnBlur);
}
JS Fiddle demo.
Or you can add a new class-name to the elements (rather than changing the style object yourself:
function colorOnBlur(){
this.classList.add('blurred');
}
var inputs = document.querySelectorAll('input');
for (var i = 0, len = inputs.length; i < len; i++){
inputs[i].addEventListener('blur', colorOnBlur);
}
Coupled with the CSS:
input.blurred {
background-color: #f00;
}
JS Fiddle demo.
Obviously, adjust the relevant colours to your own tastes/requirements.
References:
addEventListener().
classList.
document.querySelectorAll().

Related

Vanilla Javascript: Remove toggle class from X element if I click on Y element with the same toggle class

I'm currently working on a sidebar menu where I toggle the "selected" class on a category, which has the classname "sidebar-category".
With jQuery I can easily achieve my desired goal: after toggling the "selected" class (if I click on another category) the previous category gets the class removed and is then applied to the currently clicked category:
$('.sidebar-category').click(function() {
$(".sidebar-category").not(this).removeClass("selected");
$(this).toggleClass('selected');
});
My problem is that for this project I cannot use jQuery and must use vanilla Javascript.
So far I can achieve the toggling easily, but I'm not sure how I can remove the class when clicking on another category using vanilla Javascript. This is my current code:
var selectCategory = document.getElementsByClassName('sidebar-category');
for (var i = 0, l = selectCategory.length; i < l; i++) {
selectCategory[i].onclick = function() {
this.classList.toggle('selected');
}
}
The jQuery code that removes the selected class is equivalent to a loop. So just write that loop in your event listener.
var selectCategory = document.getElementsByClassName('sidebar-category');
for (var i = 0, l = selectCategory.length; i < l; i++) {
selectCategory[i].onclick = function() {
for (var j = 0; j < l; j++) {
if (selectCategory[j] != this) {
selectCategory[j].classList.remove("selected");
}
}
this.classList.toggle('selected');
}
}
Assuming your target environment supports ES2015 (or you transpile your code to support such an environment), a declarative approach using Array.from, filter and forEach can be achieved with the following code:
function toggleSelectedClass(event) {
Array.from(document.getElementsByClassName('sidebar-category'))
.filter(element => element !== event.target)
.forEach(element => {
element.classList.remove('selected')
element.setAttribute('aria-pressed', false);
});
event.target.classList.toggle('selected');
const pressed = event.target.getAttribute('aria-pressed') === 'true';
event.target.setAttribute('aria-pressed', String(!pressed));
}
.sidebar-category {
padding: 5px;
}
.selected {
background: blue;
color: white;
}
<div onclick="toggleSelectedClass(event)">
<button type="button" class="sidebar-category selected" aria-pressed="true">Click</button>
<button type="button" class="sidebar-category" aria-pressed="false">Click</button>
<button type="button" class="sidebar-category" aria-pressed="false">Click</button>
<button type="button" class="sidebar-category" aria-pressed="false">Click</button>
</div>
Note: getElementsByClassName returns an HTMLCollection, not an array, so Array.from is required to use the array methods filter and forEach.
Note 2: Keep accessibility in mind when designing such a menu. A good reference for this is https://inclusive-components.design/toggle-button/.
This can be achieved with the Events API in JavaScript.
Using the onClick="" property of an HTML element we can construct a toggling system.
Create a function to handle the click action of the user and pass in the element that has been clicked as the parameter. function toggle(element){...}
Inside that element first fire off an event to clear the selected element(s) using the event named clearselected that will iterate through the elements and set the selected property to false. Thus, semantically deselecting the elements.
Change the selected property of the element passed in the onclick handler to true.
Update the user interface (UI) using an event called updateui that changed the selected element to its desired appearance, and all non-selected elements to their desired appearance using a for loop that iterates through all elements and looks at the selected property.
Down below I have a code snippet that uses vanilla JavaScript to create a toggle system on the UI. It has a very basic HTML that uses the same class names and adds very little CSS to make the demo easier to understand. I hope this is the thing you were looking for!
// Set up the HTML elements in JavaScript
var sidebar = document.getElementsByClassName("sidebar")[0];
var sidebarCategories = document.getElementsByClassName("sidebar-category");
// Add an event listener for clearing the selected elements
sidebar.addEventListener("clearselected", function(e) {
for(var i = 0; i < sidebarCategories.length; i++){
sidebarCategories[i].selected = false;
}
}, false);
// Add an event listener updating the UI to reflect changes
sidebar.addEventListener("updateui", function(e) {
for(var i = 0; i < sidebarCategories.length; i++){
var current = sidebarCategories[i];
if(current.selected){
current.textContent = "selected";
}else{
current.textContent = "";
}
}
}, false);
// Write a on click handler to handle the toggle
function toggle(element){
var event = document.createEvent("Event");
event.initEvent("clearselected", true, true);
element.dispatchEvent(event);
element.selected = true;
var event = document.createEvent("Event");
event.initEvent("updateui", true, true);
element.dispatchEvent(event);
}
.sidebar-category {
width: 100px;
height: 100px;
border: 3px solid black;
margin-bottom: 10px;
line-height: 100px;
text-align: center;
}
<div class="sidebar">
<p>Click the boxes to see the toggle in action</p>
<div class="sidebar-category" onclick="toggle(this)"></div>
<div class="sidebar-category" onclick="toggle(this)"></div>
<div class="sidebar-category" onclick="toggle(this)"></div>
</div>

Updating Inline Styling with removeAttribute() and setAttribute() not updating

Updated inline styling of a certain paragraph tag is not displaying new updates.
I am using the following example that I found on Stack overflow:
var para = document.getElementsByTagName('div');
var len = para.length;
for (var i = 0; i < len; ++i) {
if(para[i].innerHTML.indexOf("SOME TEST") !== -1) {
para[i].removeAttribute('style');
para[i].setAttribute('style', 'FONT-SIZE: 100px !important; FONT-FAMILY: Arial !important; color:red;');
}
}
When I look at the inspector tool, I am able to see the styling I implemented. However, the styling is not taking place.
What am I doing wrong? I am trying to make this work for IE8 and below
You need to use an alternative for old versions of IE, which neither support using setAttribute() to set styles nor event handlers. This also works in other browsers too:
var para = document.getElementsByTagName('div');
var len = para.length;
for (var i = 0; i < len; ++i) {
if(para[i].innerHTML.indexOf("SOME TEST") !== -1) {
para[i].style.cssText = 'FONT-SIZE: 100px !important; FONT-FAMILY: Arial !important; color:red;';
}
}
On the other hand, I agree with the suggestion others have made that class switching is better when you're not using JS to calculate a value dynamically.
A better approach for styling an element using attributes, would be using custom element attributes and specific CSS rules for those attributes.
Note : If you want to pass HTML validations, your attribute names must be prefixed with 'data-'. They should also not contain any uppercase letters.
In the following example, you will see how the styles declared with the [data-myAttribute] CSS selector are applied when the attribute is set to the element :
var myElement = document.getElementById('myElement');
// click event handler compatible with IE8
myElement.onclick = function clickHandler(e){
// toggle the 'data-myAttribute' attribute
if( myElement.hasAttribute('data-myAttribute') ){
myElement.removeAttribute('data-myAttribute');
}else{
myElement.setAttribute('data-myAttribute', true);
}
}
[data-myAttribute]{
text-decoration : underline;
color : red;
}
<div id="myElement">click me</div>

How to clear input with :after element

Take a look at this website. There are 2 search bars and after each search bar there is an :after element. When you click that element the text box is cleared. How can I do this with Javascript ? (no jquery)
You can't add event listeners to pseudo-elements. But here the element has no contents except the pseudo-element, so you can just add the event listener to the element.
var input = document.getElementById('input');
document.getElementById('clear').addEventListener('click', function() {
input.value = '';
});
#clear::after {
content: '\00d7';
cursor: pointer;
}
<input id="input" value="Hello" />
<span id="clear" title="Clear"></span>
The click event is actually not on the :after pseudo-element, but on the span itself (as you can see here) The pseudo-element just provides the icon, nothing fancy going on here. Then it's just a matter of doing something like this;
element.addEventListener('click', function() {
document.getElementById('startInput').value = '';
}, false);
I don't think it's anything special.
Something like this:
var elementList = document.getElementsByClassName('something');
for (var i = 0; i < elementList.length; i++) {
elementList[i].addEventListener("click", delFn);
}
function delFn(){
console.log("delete it");
}
https://jsfiddle.net/5w4obgzu/1/

CSS style to inline style via JavaScript

I want to add all CSS styles of a specific element to its inline style attribute. For example:
I have:
<div id="d"></div>
and:
#d { background: #444444; width: 50px; height: 20px; display: inline-block; }
Now I want a JavaScript function that turns my div into this:
<div id="d" style="background: #444444; width: 50px; height: 20px; display: inline-block;"></div>
Please help me. And, by the way, I don't want any CSS styles to re-write any existing inline style.
You can do something like this:
function applyStyle(el) {
s = getComputedStyle(el);
for (let key in s) {
let prop = key.replace(/\-([a-z])/g, v => v[1].toUpperCase());
el.style[prop] = s[key];
}
}
let x = document.getElementById('my-id');
applyStyle(x);
Where x is the element you want to apply the style to.
Basically this function gets the computed style of the element and then copies each property (like padding, background, color, etc.) to the inline style of the element.
I don't know why you need to do this, but it's a really dirty approach in my opinion. I would personally advise against it.
It appears this library will do what you're looking for: https://github.com/lukehorvat/computed-style-to-inline-style
Convert a HTML element's computed CSS to inline CSS.
Uses Window.getComputedStyle internally.
This one?
function transferComputedStyle(node) {
var cs = getComputedStyle(node, null);
var i;
for (i = 0; i < cs.length; i++) {
var s = cs[i] + "";
node.style[s] = cs[s];
}
}
function transferAll() {
var all = document.getElementsByTagName("*");
var i;
for (i = 0; i < all.length; i++) {
transferComputedStyle(all[i]);
}
}
Simply call transferAll onload, or whereever.
I think the issue with the accepted answer (thank you for that!) is that one of the properties it tries to transfer on the element style from the Computed Style is the cssText.
If we exclude from the transfer cssText and also other properties that are actually methods, it works!
So building on the accepted answer and this answer, I've got:
var el = document.querySelector("#answer-25097808 > div > div.answercell.post-layout--right > div.s-prose.js-post-body > pre"); // change yourId to id of your element, or you can write “body” and it will convert all document
var els = el.getElementsByTagName("*");
for(var i = -1, l = els.length; ++i < l;){
el = els[i]
s = getComputedStyle(el)
for (let styleKey in el.style) {
for (let computedStyleKey in s) {
let computedStyleKeyCamelCase = computedStyleKey.replace(/\-([a-z])/g, v => v[1].toUpperCase());
if ((typeof el.style[styleKey] != "function") && (styleKey != 'cssText')){
if(styleKey == computedStyleKeyCamelCase) {
el.style[styleKey] = s[computedStyleKey];
}
}
}
}
}
P.S.: the above code should run in the Developer Tools console (tried it in Chrome)
Using jQuery it can be done easily. Here is the sample code:
If you are new in jQuery and you don't know how to add and work then follow this link
$(document).ready(function(){
$("#d").css('background-color', '#444444').css('width', '50px').css('height', '20px').css('display', 'inline-block');
});
For javascript code I am not confident but for jQuery I am sure that it will work.
Correct me if I am wrong.

Which HTML/JS widget to display this balsamiq control?

I did mockups in balsamiq & they have this nice widget, which
Allowed to select a value, out of two values. Works really nicely on touchscreens
Can be used to Display two values & highlighting the selected one
Example:
What the options to implement a widget similar to shown in picture via HTML/CSS & JS?
The approach I present below iterates through all fieldset elements, and if all the inputs therein are of type="radio", hides them and appends span elements (of class="buttonRadio") in their place, using the text from their relevant label elements. It also binds click events to the appended span elements, and triggers the change event on the original inputs and also adds the 'checked' class-name to the clicked/touched element, while removing that class it from its siblings:
$('fieldset').each(
function() {
var legend = $(this).find('legend').text();
if ($(this).find('input').length == $(this).find('input[type="radio"]').length) {
var that = $(this),
len = that.find('input[type="radio"]').length;
for (var i = 0; i < len; i++) {
$('<span />')
.text($('label')
.eq(i).text())
.addClass('buttonRadio')
.attr('data-fromID',that.find('input:eq(' + i + ')').attr('id'))
.appendTo(that);
}
}
}).on('click','.buttonRadio',function(){
var id = $(this).attr('data-fromID');
$(this).addClass('checked').siblings().removeClass('checked');
$('#' + id).click().trigger('change');
}).find('label, input[type="radio"]').css('display','none');​
This uses the following CSS to style those elements:
.buttonRadio {
background-color: #fff;
padding: 0.5em 1em;
border: 1px solid #000;
margin: 0.5em 0 0 0;
}
.buttonRadio.checked {
background-color: #ffa;
}​
JS Fiddle demo.
Edited to amend the jQuery a little:
cached the $(this) object a little earlier in this version,
remembered to use the legend variable that I assigned in the first incarnation but forgot to actually use...sigh.
also hid the actual <legend></legend> element:
$('fieldset').each(
function() {
var that = $(this),
legend = that.find('legend').text();
$('<span />').text(legend).addClass('legend').appendTo(that);
if (that.find('input').length == that.find('input[type="radio"]').length) {
var len = that.find('input[type="radio"]').length;
for (var i = 0; i < len; i++) {
$('<span />')
.text($('label')
.eq(i).text())
.addClass('buttonRadio')
.attr('data-fromID',that.find('input:eq(' + i + ')').attr('id'))
.appendTo(that);
}
}
}).on('click','.buttonRadio',function(){
var id = $(this).attr('data-fromID');
$(this).addClass('checked').siblings().removeClass('checked');
$('#' + id).click().trigger('change');
}).find('label, input[type="radio"], legend').css('display','none');​
JS Fiddle demo.
References:
addClass().
attr().
click().
css().
each().
eq().
find().
on().
removeClass().
siblings().
text().
trigger().

Categories

Resources