Rick_Stinson
Rick_Stinson

Reputation: 13

Use js if/else with CSS value

I'm not really a programmer, but I have to change some html/css/js code for our needs.. and I'm struggling.

we are using a cloud software, which closed source, but with the possibility to change parts of the HTML frontend.

the software uses the CSS class "dom-admin" to hide some setting for non-admin.

<div class="dom-admin"> hidden for non-admins </div>

if a user logs in, the display property is set by the system to display:none;

.dom-admin {
    display: none;
}

these hidden fields are mostly input fields. we dont want to hide this fields for our users, we just want to set the fields readonly.

my idea is to read the display value within a javascript in a if / else query:

if (dom-admin('display') == 'none') 
{ document.write('<input type="text" id="XX">') }
else
{ document.write('<input readonly type="text" id="XX">') }

My Problem is to access the display value, i tried x examples from the net, but i never able to read the property of "dom-admin", eg:

document.getElementById('dom-admin').style.display

Chrome Javascript Console: Uncaught TypeError: Cannot read property 'style' of null

Chrome dev-tools shows me this about the "dom-admin" CSS:

image

I appreciate any help... Thanks, Patrick

Upvotes: 1

Views: 1518

Answers (2)

zer00ne
zer00ne

Reputation: 43870

Phase 1: Reveal All Hidden Field(s)


Multiple Elements with Common ClassName

The class .dom-admin is merely presentational, it is not a security measure. If you want to access multiple elements with the className of dom-admin you must collect them into a NodeList/HTMLCollection:

var DOMObjects = document.querySelectorAll('.dom-admin');

OR

var DOMObjects = document.getElementsByClassName('dom-admin');

With this list you'll have to iterate/loop through each *.dom-admin by a for loop, or array method (if the latter them the list might need to be converted to an array):

for (let i=0; i < DOMObjects.length; i++) {...

OR

DOMObjects.forEach(function(DOMObj, index) {...

To reverse the style of .dom-admin, you can set each *.dom-admin style object to:

DOMObj.style.display = "block"

OR remove .dom-admin class:

DOMObj.classList.remove('dom-admin')

Single Element with ClassName

The most direct method is to target the className via querySelector() or getElementsByClassName()[0]:

var DOMObj = document.querySelector('.dom-admin');

OR

var DOMObj = document.getElementsByClassName('dom-admin')[0];

Phase 2: Set All Revealed Fields to be Non-editable


Set/Get/Change Element Attributes

id, class, readOnly, etc. are called attributes. The attribute needed has a Boolean value (true/false). An attribute such as readonly merely needs to exist on the tag in order for it to be true. Not actually be in the tag of course makes it false.

Set an attribute More specifically, adding an attribute to an element when it didn't exist before:

DOMObj.setAttribute('readonly', true);

Get an attribute Finding an attribute and reading the value of said attribute:

DOMObj.getAttribute('readonly');

Change an attribute If the attribute already exists and the value needs to be changed:

DOMObj.removeAttribute('readonly')

Keep in mind that the attribute you are dealing with has a Boolean value so it is handled differently than an attribute with a String value.

DOMObj.setAttribute('name', 'foo'); /*OR*/ DOMObj.name = "foo"

DOMObj.getAttribute('name');

DOMObj.setAttribute('name', 'bar') /*OR*/ DOMObj.name = 'bar'

Note 1

The syntax for methods querySelector()/querySelectorAll():

document.querySelector('.dom-admin')

CSS Selector ===========^-----^[dot for class]

is different than the syntax of method getElementsByClassName():

document.getElementsByClassName('dom-admin')

DOMString====================^------^[no dot needed]

document.getElementsByClassName('dom-admin')[0]

DOMString====================^------^===^-^[no dot needed]==

[Bracket Notation with index of zero is needed if there is only one target]


Note 2

Do not use document.write unless you intend to destroy everything on your page.

If you have inputs nested within the div.dom-admin, that would mean that those inputs exist already but the user cannot see them. It isn't necessary to create them and even if you do need to create any element, never use document.write. Instead use createElement() or use innerHTML on an element that you intend to use as a container.


Demo

// Collect all .dom-admin into NodeList
var das = document.querySelectorAll('.dom-admin');

// forEach() .dom-admin, remove the class .dom-admin
das.forEach(function(da, idx) {
  da.classList.remove('dom-admin');

  // Find all inputs in the div formerly known as .dom-admin
  var inputs = da.querySelectorAll('input');

  /* forEach() input nested within the div formerly known 
  || as .dom-admin, set its attribute readonly to true
  */
  inputs.forEach(function(input, index) {
    input.setAttribute('readonly', true);
  });
});
.dom-admin {
  display: none;
}

input {
  font: inherit;
  width: 40%
}
<div class="dom-admin">
  <input type='text' value='These inputs exist already'>
  <input type='text'>
</div>

<div class="dom-admin">
  <input type='text' value='Do not use document.write'>
  <input type='text' value='it will overwite EVERYTHING'>
  <input type='text' value=''>
</div>

<div class="dom-admin">
  <input value='Fun fact:'>
  <input value='input by default is type="text"'>
  <input>
</div>

Upvotes: 2

Alex
Alex

Reputation: 2232

Here's what I used to achieve what you want.

As others mentioned, use document.querySelector('.dom-admin') to access the class and when you change display style, you can use the if statement

let admin = document.querySelector('.dom-admin');
if (admin.style.display === 'none') {
  document.write('<input type="text" id="XX">');
} else {
  document.write('<input readonly type="text" id="XX">');
}
.dom-admin {
  width: 200px;
  display: none;
}
<div class="dom-admin">
  <form action="#">
    <input type="text" id="user" />
    <input type="number" id="user_number" />
    <input type="password" id="user_password" />
    <input type="submit" id="submit" />
  </form>
</div>

Upvotes: 0

Related Questions