1

I want to be able to choose a input box and that the ones before it get triggered. I don't know how to do this with javascript.

for example if a user presses the first box only that box should be active but if the user presses the second box the first and second box should trigger.

the snippet bellow shows that I can active one box at a time but I want to be able to trigger the ones before it without having to manually do it once the second, third and last box had been choosen.

function color(campo) {
  valor_campo = document.getElementById(campo).value;
  if (valor_campo == 0) {
    document.getElementById(campo).style.background = '#000';
    document.getElementById(campo).style.color = '#000';
    document.getElementById(campo).value = 1;
  } else if (valor_campo == 1) {
    document.getElementById(campo).style.background = '#fff';
    document.getElementById(campo).style.color = '#fff';
    document.getElementById(campo).value = 0;
  }
}

function colors() {

  if (document.getElementById('cc11_a').value == 0) {
    document.getElementById('cc11_a').style.background = '#fff';
    document.getElementById('cc11_a').style.color = '#fff';
    document.getElementById('cc11_a').value = 0;
  } else if (document.getElementById('cc11_a').value == 1) {
    document.getElementById('cc11_a').style.background = '#000';
    document.getElementById('cc11_a').style.color = '#000';
    document.getElementById('cc11_a').value = 1;
  }

  if (document.getElementById('cc11_b').value == 0) {
    document.getElementById('cc11_b').style.background = '#fff';
    document.getElementById('cc11_b').style.color = '#fff';
    document.getElementById('cc11_b').value = 0;
  } else if (document.getElementById('cc11_b').value == 1) {
    document.getElementById('cc11_b').style.background = '#000';
    document.getElementById('cc11_b').style.color = '#000';
    document.getElementById('cc11_b').value = 1;
  }

  if (document.getElementById('cc11_c').value == 0) {
    document.getElementById('cc11_c').style.background = '#fff';
    document.getElementById('cc11_c').style.color = '#fff';
    document.getElementById('cc11_c').value = 0;
  } else if (document.getElementById('cc11_c').value == 1) {
    document.getElementById('cc11_c').style.background = '#000';
    document.getElementById('cc11_c').style.color = '#000';
    document.getElementById('cc11_c').value = 1;
  }

  if (document.getElementById('cc11_d').value == 0) {
    document.getElementById('cc11_d').style.background = '#fff';
    document.getElementById('cc11_d').style.color = '#fff';
    document.getElementById('cc11_').value = 0;
  } else if (document.getElementById('cc11_d').value == 1) {
    document.getElementById('cc11_d').style.background = '#000';
    document.getElementById('cc11_d').style.color = '#000';
    document.getElementById('cc11_d').value = 1;
  }

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body onload="colors();">
  <td colspan="3" style="text-align:left">

    <input name="cc11_a" type="text" class="text" id="cc11_a" onclick="color(this.id);" style="width:0.3cm;" value="" />
    <input name="cc11_b" type="text" class="text" id="cc11_b" onclick="color(this.id);" style="width:0.3cm;" value="" />
    <input name="cc11_c" type="text" class="text" id="cc11_c" onclick="color(this.id);" style="width:0.3cm;" value="" />
    <input name="cc11_d" type="text" class="text" id="cc11_d" onclick="color(this.id);" style="width:0.3cm;" value="" />

  </td>
Andrew Willems
  • 9,768
  • 8
  • 39
  • 58
learningbyexample
  • 1,459
  • 1
  • 13
  • 37

2 Answers2

1

I simplified your code and also provided a solution.

The color function first extracts the number of the element from the id, i.e.

  • 'cc11_a' becomes 0
  • 'cc11_b' becomes 1
  • etc.

It then loops from that number back down to 0, i.e. if the number is 2, then it loops through 2, 1 and 0. For each of those numbers, it calls the toggleElmt function.

The toggleElmt function first converts the number back to an id, e.g. 2 becomes 'cc11_c' and retrieves the element with that id. It then gets the value of that element, using it to change the color of its background and text. Finally, it uses a tried-and-true method of toggling a number between 0 and 1 which essentially can be simplified to someValue = 1 - someValue.

var twoColors = ['#000', '#fff'];

function color(campoId) {
  var campoNum = campoId.charCodeAt(campoId.length - 1);
  for (var num = campoNum; num >= 97; num -= 1) {
    toggleElmt(num);
  }
}

function toggleElmt(num) {
  var campoElmt = document.getElementById('cc11_' + String.fromCharCode(num));
  var valor_campo = campoElmt.value;
  campoElmt.style.background = twoColors[valor_campo];
  campoElmt.style.color = twoColors[valor_campo];
  campoElmt.value = 1 - valor_campo;
}
input {
  width: 0.3cm;
  background: white;
  color: white;
}
<input id="cc11_a" onclick="color(this.id);" value="0" />
<input id="cc11_b" onclick="color(this.id);" value="0" />
<input id="cc11_c" onclick="color(this.id);" value="0" />
<input id="cc11_d" onclick="color(this.id);" value="0" />
Andrew Willems
  • 9,768
  • 8
  • 39
  • 58
  • why 97 and num -= 1? what do these do? `for (var num = campoNum; num >= 97; num -= 1)` – learningbyexample Aug 28 '16 at 23:36
  • 97 is the character code for 'a'. ('b' is 98, 'c' is 99, etc.) Thus the for loop is doing the following: Start with `num` set to the character code of the last letter of the id of the clicked element, e.g. `'cc11_c'` --> `'c'` --> `99`. After each loop, decrement this value by 1 (i.e. 99, then 98, then 97, correlating with 'c', then 'b', then 'a'). Stop when you get to 97, i.e. stop when you get to `'a'`. When these `num`s are each fed into `toggleElmt`, they will each be re-converted back to their `id`s, i.e. `'cc11_c'`, then `'cc11_b'`, etc. The conversion to #s makes the looping easier. – Andrew Willems Aug 28 '16 at 23:54
1

One possible way to do it is to use DOM event delegation.

Example

HTML:

<div id="parentElem">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

CSS:

#parentElem {
  display: flex;
  flex-direction: row;
}

.box {
  background-color: #fff;
  border: 1px solid black;
  width: 48px;
  height: 48px;
}

Using pure Javascript:

// Grab all input boxes.
var inputBoxes = document.getElementsByClassName('box');
// Turn node list into an array so we can use array methods.
inputBoxes = Array.from(inputBoxes);
// Grab the parent element.
var parentElem = document.getElementById('parentElem');

// Attach onclick event to the parent element.
parentElem.addEventListener('click', function(event) {
  if (event.target.classList.contains('box')) {
    // Briefly reset the color of all boxes.
    inputBoxes.forEach(function(box) {
        box.style.backgroundColor = 'white';
    })
    // Grab the index of the clicked box.
    var indexOfClickedBox = inputBoxes.indexOf(event.target);
    // Turn each box red until you reach the clicked box.
    inputBoxes.forEach(function(box, i) {
        if (i <= indexOfClickedBox)
          box.style.backgroundColor = 'red';
    })
  }
});

JSFiddle: https://jsfiddle.net/9arpknhq/

Community
  • 1
  • 1
B Thuy
  • 169
  • 1
  • 5
  • I don't think the linked JSFiddle provides the functionality the question asks for. – Andrew Willems Aug 28 '16 at 21:41
  • Quoting OP: " if a user presses the first box only that box should be active but if the user presses the second box the first and second box should trigger." I believe that this is what my code snippet does. – B Thuy Aug 28 '16 at 21:48
  • I guess it depends on what the OP means by "active" and "trigger". However, if you look at the code snippet provided in the question, when a user clicks one of the boxes, the box toggles from white to black, back to white, etc., i.e. the color toggles between 2 states. Thus, I assume that the desired functionality is as follows: click the left-most box, toggle only it between black and white; click the second-most left-hand box, toggle the colors of both the left and second-left boxes, etc. I suppose only the OP can unambiguously clarify this, but that was my interpretation of the question. – Andrew Willems Aug 28 '16 at 21:53