0

I am trying to reduce the opacity of a table (with class="test") whenever a checkbox that is within the table is checked. For some reason, only the checkbox itself fades. I don't understand what I'm doing wrong. My code is below. Thanks for the help.

table.test input[name="delete_record[]"]:checked {
  opacity: 0.5;
}
<table class="test" cellpadding="10" cellspacing="0" align="center" bgcolor="#9CDEEC" border="0" style="margin-bottom: 16px;border-radius: 4px;border: 1px solid #555555;">
  <!-- Transactions table -->
  <tbody>
    <tr>

      <td>
        <input style="width: 90px;" type="text" class="datepicker" name="date[]" required="" value="01/09/1970">
      </td>

      <td>
        <input type="text" name="payee[]" required="" value="Hateful!">
      </td>


      <td rowspan="2" align="left" valign="top">
        <a title="Memo: They're customer service is astounding.">
          <textarea rows="3" style="text-align: left; border: 1px solid #AAAAAA; width: 200px; background-color: #FFFFFF; padding: 3px;" name="memo[]">They're customer service is astounding.</textarea>
        </a>
      </td>
      <td>
        <select name="reconciled[]">
          <option value="R" selected="selected">R</option>
          <option value=""></option>
          <option value="C">C</option>
          <option value="R">R</option>
        </select>
      </td>

      <td>
        <input style="width: 100px; text-align: right;" type="number" step="0.01" name="deposit[]" size="4" min="0" max="100000000" value="">
      </td>
      <td>
        <input style="width: 100px; text-align: right;" type="number" step="0.01" name="withdrawal[]" size="4" min="0" max="100000000" value="37.00">
      </td>
      <input type="hidden" name="record_id[]" value="95">
      <td rowspan="2" align="center" valign="middle">
        <input type="checkbox" name="delete_record[]" value="95">
      </td>
    </tr>

    <tr>
      <td>
        <input style="width: 60px;" placeholder="Check #" type="number" step="1" min="0" max="1000000000" name="check_number[]" value="110">
      </td>
      <td>
        <select name="category[]" style="width: 200px;">
          <option value="1" selected="selected">Business: Advertising</option>
          <option value="42">Business</option>
          <option value="1">Business: Advertising</option>
          <option value="2">Business: Assets</option>
          <option value="24">Business: Automotive: Auto Insurance</option>
          <option value="25">Business: Automotive: Auto Loan</option>
          <option value="26">Business: Automotive: Repairs</option>
          <option value="27">Business: Automotive: Fuel</option>
          <option value="28">Business: Automotive: Parking and Tolls</option>
          <option value="29">Business: Automotive: Registration</option>
          <option value="30">Business: Automotive: Vehicle Leasing</option>
          <option value="31">Business: Automotive: Wash and Road Services</option>
          <option value="3">Business: Commissions and Fees</option>
          <option value="4">Business: Contract Labor</option>
          <option value="23">Business: H.S.A. Contrbutions</option>
          <option value="22">Business: Health Insurance Premiums</option>
          <option value="10">Business: Home Office Other Expenses</option>
          <option value="12">Business: Home Office Rent and Lease</option>
          <option value="37">Business: Home Office Repairs and Maintenence</option>
          <option value="5">Business: Insurance</option>
          <option value="32">Business: Interest Paid: Business Loan</option>
          <option value="33">Business: Interest Paid: Business Mortgage</option>
          <option value="34">Business: Interest Paid: Credit Card</option>
          <option value="35">Business: Interest Paid: Home Office Mortgage</option>
          <option value="6">Business: Legal and Professional Services</option>
          <option value="7">Business: Materials and Supplies</option>
          <option value="8">Business: Meals and Entertainment</option>
          <option value="9">Business: Office Expenses</option>
          <option value="11">Business: Rent and Lease</option>
          <option value="36">Business: Repairs and Maintenence</option>
          <option value="13">Business: Taxes and Licenses: Licenses</option>
          <option value="14">Business: Taxes and Licenses: Property Tax</option>
          <option value="15">Business: Taxes and Licenses: Estimated Taxes</option>
          <option value="16">Business: Taxes and Licenses: Federal Tax</option>
          <option value="17">Business: Taxes and Licenses: Home Office Property Tax</option>
          <option value="18">Business: Taxes and Licenses: State Tax</option>
          <option value="19">Business: Travel</option>
          <option value="20">Business: Utilities: Utilities</option>
          <option value="21">Business: Utilities: Home Office Utilities</option>
          <option value="43">Personal</option>
          <option value="51">Personal: Automotive</option>
          <option value="52">Personal: Charity and Donations</option>
          <option value="53">Personal: Child Care</option>
          <option value="54">Personal: Clothing</option>
          <option value="55">Personal: Education</option>
          <option value="56">Personal: Entertainment</option>
          <option value="48">Personal: Furnishings</option>
          <option value="63">Personal: Gift</option>
          <option value="44">Personal: Groceries</option>
          <option value="47">Personal: Health and Fitness</option>
          <option value="57">Personal: Home Maintenance and Repairs</option>
          <option value="50">Personal: Insurance</option>
          <option value="58">Personal: Medical</option>
          <option value="59">Personal: Mortgage</option>
          <option value="49">Personal: Pets</option>
          <option value="60">Personal: Property Tax</option>
          <option value="61">Personal: Rent</option>
          <option value="46">Personal: Resturants</option>
          <option value="62">Personal: Travel and Vacation</option>
          <option value="45">Personal: Utilities</option>
          <option value="38">Transfer: Bank to Bank</option>
          <option value="39">Transfer: Credit Card Payment</option>
          <option value="40">Transfer: Owner's Deposit</option>
          <option value="41">Transfer: Owner's Withdrawal</option>
        </select>
      </td>
      <td colspan="3" align="right" valign="middle" style="padding-right: 20px;">
        <!--  Accounts Selector -->
        <select name="bank_account[]">
          <option value="19">Chroot Checking</option>
          <option value="10">Main Checking</option>
          <option value="19">Chroot Checking</option>
        </select>
      </td>
    </tr>
  </tbody>
</table>
0xdw
  • 3,755
  • 2
  • 25
  • 40
Sarah C. Corriher
  • 55
  • 1
  • 1
  • 12
  • 2
    inputs shouldn't be used as containers. Also, when you give something an opacity, only the children are affected not the parents or siblings. You should probably use javascript for this. – im_benton May 05 '16 at 17:16
  • as to why only the checkbox fades - that's because your css rule applies to the checkbox only. You need to add a class to the parent and then make opacity: 0.5 for that parent with that class. – Mohit Bhardwaj May 05 '16 at 17:18
  • Alright. I was hoping that I could accomplish this more simply. Perhaps not. Mike: The css specifies table.test, which is the parent and its class. – Sarah C. Corriher May 05 '16 at 17:18
  • that's simple. Can you use jQuery or you need to work with javascript only? with jQuery, it's a piece of cake. – Mohit Bhardwaj May 05 '16 at 17:19
  • 1
    Sounds like you need a parent selector. Sadly, that's not currently a thing without resorting to js. You can read more on it over here, along with a wild ride of the parent selector's design process over here: http://stackoverflow.com/a/1014958/5116879 – abluejelly May 05 '16 at 17:19
  • @Mike it's trivial in regular js, too >.> `onclick="this.parentNode.classList.toggle('faded');"` (assuming you call the class you're using `faded` and don't mind not having the effect on LTE IE 9 without a polyfill for classList like the one on MDN: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList – abluejelly May 05 '16 at 17:23
  • @abluejelly Thanks. actually, if I had to write the answer, I would have to search for JS traversing properties/methods ;) – Mohit Bhardwaj May 05 '16 at 17:24

7 Answers7

2

As you can't change the parent's opacity using CSS, you would need to use JavaScript.

document.querySelector('input[name="delete_record[]').addEventListener('click', function() {
    var d = document.querySelector('table.test');
    if(this.checked) {
        d.style.opacity = 0.5;
    } else {
        d.style.opacity = 1;
    }
});

This toggles the opacity as well.

Example here.

To only affect the parent table, and using a class to toggle as suggested by @abluejelly, you could do:

document.querySelector('input[name="delete_record[]').addEventListener('click', function() {
    var d = this.parentNode.parentNode.parentNode; // the table
    d.classList.toggle('halfOpacity', this.checked);
});

You would need a CSS class:

.halfOpacity {
    opacity: 0.5;
}

for that to work.

Example here.

If you have multiple tables though you would need to try something like:

var tables = document.querySelectorAll('input[name="delete_record[]');
for(var i = 0, l = tables.length; i < l; i++) {
    tables[i].addEventListener('click', function() {
        var d = this.parentNode.parentNode.parentNode; // the table
        d.classList.toggle('halfOpacity', this.checked);
    });
}

which loops through all your tables and assigns the click event listener to the checkboxes.

Example here.

spaceman
  • 1,147
  • 8
  • 15
  • I'd suggest switching to a class rather than style directly, and if possible migrating off of `.querySelector`. Also a note, this as-written will run into an issue when there's more than one of those checkboxes (the `[]` indicates to a PHP POST that it's an array, so that's likely). Easy fix would be to use QSA instead and walk the array attaching a specific function rather than an inlined one. Regardless, +1 for native, you give me hope for the future. – abluejelly May 05 '16 at 17:34
  • Thanks. This works beautifully. Is there a simply way to make it apply only the table that is the parent of that particular checkbox? If so, this would enable me to have multiple of these tables, each changing opacity when a checkbox within it is checked. – Sarah C. Corriher May 05 '16 at 17:41
2

This will reduce the table opacity whenever a checkbox that is within the table is checked.

var checkboxes = document.querySelectorAll('input[type="checkbox"]');
var table = document.querySelector('table.test');
var oneIsChecked = false;
for(var i=0; i<checkboxes.length; i++){
    checkboxes[i].addEventListener("click", function(e) {
      oneIsChecked = false;
      for(var j=0; j<checkboxes.length; j++){
        if(checkboxes[j].checked) {
          oneIsChecked = true;
          break;
        }
      }
      if(oneIsChecked){
        table.style.opacity = 0.5;
      }else{
        table.style.opacity = 1;
      }
    });
}
1
table.test input[name="delete_record[]"]:checked

This selector says: match a checked input element with its name attribute set to "delete_record[]", that is a descendant of a table element with class test. Put simply, this CSS selector refers to your input element, not your table element (which is one of its parents instead).

For a pure CSS-based solution you would need a "has-descendant" or "has-child" operator, which is unfortunately not supported in CSS3. You will therefore need to resort to JavaScript and watch for when your input changes, then progammatically set opacity (or whatever you need):

document.querySelector('input[name="delete_record[]"]')[0].addEventListener('change', function () {
    var tableElement = document.querySelector('table.test')[0];

    if (this.checked) {
        tableElement.style.opacity = 0.5;
    } else {
        tableElement.style.opacity = 1;
    }
});

You will of course also need to match the initial table opacity to the initial checked state of your input.

Note however, that opacity is effectively inherited from a visual perspective.

John Weisz
  • 30,137
  • 13
  • 89
  • 132
  • But it's trivial to do in vanilla JS, why would you force jQuery D= – abluejelly May 05 '16 at 17:35
  • @abluejelly I dislike it myself as well, but these tasks collectively is _exactly_ where it has its place, IMO. There are several caveats when you approach this with vanilla JS. – John Weisz May 05 '16 at 17:37
  • I know I'm right lol you can polyfill classList down to IE 8, which is the first version of IE to support opacity, and then a checkbox inside the element can just `onclick="this.parentNode.classList.toggle('faded');"` (as I said in the comments on the question itself`. Only issue then is IE's onclick spamming, which can be fixed with a fairly simple change to that code. – abluejelly May 05 '16 at 17:42
  • In regards to the CSS, you're right. I tried to use the '>' selector, but it didn't make any difference. Apparently this is a limitation of CSS at the moment, and that's a real shame. It _could_ have been so simple. – Sarah C. Corriher May 05 '16 at 17:46
  • 1
    @SarahC.Corriher FYI, `>` is the direct descendant (child) selector. – John Weisz May 05 '16 at 17:48
  • Actually... I derped there's two issues, the other is keyboard support. Attaching it to `onkeypress` as well will fix that issue, bonus if you just say `this.onclick.call(this);`, haha – abluejelly May 05 '16 at 17:50
  • @abluejelly Also, to be honest, I didn't check the question well enough. Since everyone started throwing in jQuery code, I automatically assumed it was tagged in the question. People are strange... – John Weisz May 05 '16 at 17:52
  • SO just has a weird lust for jQ, regardless of the tags. You get used to it. I once had an answer of mine that went trivially native downvoted because it *wasn't* jQ. Surprised you haven't noticed this since you've been here longer than I haha – abluejelly May 05 '16 at 17:54
  • 1
    You sir have just made my day, wow, you've earned the downvote being removed from that alone hahahaha – abluejelly May 05 '16 at 17:56
0

Your checkbox is only fading because that is what your CSS selector is targeting.

Unfortunately, CSS cannot do what you're asking. You can only target elements that are preceded by others, not followed by.

You can use other methods to conditionally apply a class to your table and style it accordingly. jQuery is a simple solution, but the best option depends on what languages you're using.

Flignats
  • 1,234
  • 10
  • 21
0

You can do it simply using CSS as well, follow the below instructions:

step #1: copy and paste the below code in a separate file to see the result, then use it for your own purpose.

body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: #001925;
}

.list {
    padding: 30px 75px 10px 30px;
    position: relative;
    background: #042b3e;
    border-top: 50px solid #03a9f4;

}

.list h2 {
    color: #fff;
    font-size: 30px;
    padding: 10px 0;
    margin-left: 10px;
    display: inline-block;
    border-bottom: 4px solid #fff;

}

.list label {
    position: relative;
    display: block;
    margin: 40px 0;
    color: #fff;
    font-size: 24px;
    cursor: pointer;

}

.list input[type="checkbox"] {
    -webkit-appearance: none;
}

.list i {
    position: absolute;
    top: 0;
    display: inline-block;
    width: 25px;
    height: 25px;
    border: 2px solid #fff;
    left: 0;
}

.list input[type="checkbox"]:checked ~ i {
    top: 1px;
    border-top: none;
    border-right: none;
    height: 15px;
    width: 25px;
    transform: rotate(-45deg);

}

.list span {
    position: relative;
    left: 40px;
    transition: 0.5s;
}

.list span:before {
    content: '';
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    height: 1px;
    background: #fff;
    transform: translateY(-50%) scaleX(0);
    transform-origin: right;
    transition: transform 0.5s;

}

.list input[type="checkbox"]:checked ~ span:before {

    transform: translateY(-50%) scaleX(1);
    transform-origin: left;
    transition: transform 0.5s;
}

.list input[type="checkbox"]:checked + span {
    opacity: 0.2;
    transform: translateY(-50%) scaleX(1);
    transform-origin: left;
    transition: transform 0.5s;
}

input[type=checkbox] + label {
    color: #ccc;
    font-style: italic;
}

input[type=checkbox]:checked + label {
    color: #f00;
    font-style: normal;
    opacity: 0.2;
}
<DOCTYPE HTML>
    <html>

    <head>
        <meta charset="utf-8">
        <title>Check List</title>
    </head>

    <body>
        <div class="list">
            <h2>Check list in HTML & CSS</h2>

            <label>
                <input type="checkbox" name="">
                <span>HTML stand for Hyper text markup language</span>
                <i></i>
            </label>
        </div>
    </body>
    </html>
Baseer Ebadi
  • 113
  • 3
-1

In jQuery you can do something like

if ($('input[name="delete_record[]"]').is(':checked')) {
    $('table.test').css('opacity', 0.5);
}
-3
$('input[name="delete_record[]"]').click(function(){
    $(this).is(':checked')) {
        $('table.test').css('opacity', 0.5);
    }
});
im_benton
  • 2,541
  • 4
  • 21
  • 30