Update text depending on selected values in a list * WITHOUT JAVASCRIPT *

17

At work we find an interesting problem: we have a page with a drop-down list that, when the selected option changes, updates the values of a series of elements from the values of a variable in JSON.

HTML is something like this (simplified):

<select id="paises">
  <option value="chile">Chile</option>
  <option value="colombia">Colombia</option>
  <option value="ecuador">Ecuador</option>
</select>

<div id="valores">
  Pais: <span id="pais"></span><br/>
  Teléfono: <span id="telefono"></span><br/>
  Email: <span id="email"></span>
</div>

And the JSON is something like this (simplified):

info = {
    "chile": {
        "nombre": "Chile",
        "telefono": "123456789",
        "email": "chile@email.com"
    },
    "colombia": {
        "nombre": "Colombia",
        "telefono": "192837465",
        "email": "colombia@email.com"
    },
    "ecuador": {
        "nombre": "Ecuador",
        "telefono": "987654321",
        "email": "ecuador@email.com"
    }
}

The JavaScript code is not relevant to the question, but the idea is simple: depending on the selected country, the span will be updated. For example, if you select Chile, the span with id "country" will contain "Chile", the span with id "telefono" will show "123456789", etc, etc.

Now that page has been moved to a new CMS and, for different reasons, we are limited in the components that we can use and none of them allows us to incorporate JavaScript (not even inline ), it only leaves us Enter HTML and CSS.

Then the question would be: How can you simulate the behavior described above, but exclusively using HTML + CSS without any JavaScript or JSON?

Regarding HTML and CSS we have no limitations: we can reorder / organize the elements as we want, we can add new elements / delete existing elements, we can add as much code as we want ... as long as it does not contain any script, only HTML and CSS.

For example, we finally find a solution (I'll share it in the answers below in case someone inspires it) substituting the select for a list ul , transforming the JSON to CSS (with :before and content ) and with a series of input s hidden ... but the problem is that it takes up too much space and we want to know if there would be another different method.

    
asked by Alvaro Montoro 08.06.2016 в 06:37
source

3 answers

8

Although an ingenious solution, more than a space problem, I see two problems:

  
  • Something complex to maintain: you are introducing content in the styles, so there are more sites where you have to modify the   information.
  •   
  • Little accessible: being part of the style, the data is not indexed by search engines, it is not "perceived" (eg: it can not be read by a   automatic reader) and, what's worse, you can not copy, something   fundamental for contact data.
  •   

I propose to give a return to your proposal and leave the information inside the body html. Something like this:

div#paises > div { display: none; }
#chile:checked~ div#chile { display: block; }
#colombia:checked~ div#colombia { display: block; }
#ecuador:checked~ div#ecuador { display: block; }
<ul id="dropdown">
    <li>
      Selecciona un país
      <ul>
        <li><label for="chile">Chile</label></li>
        <li><label for="colombia">Colombia</label></li>
        <li><label for="ecuador">Ecuador</label></li>
      </ul>
    </li>
</ul>

<div id="paises">
      <input type="radio" name="paises" id="chile" />
      <input type="radio" name="paises" id="colombia" />
      <input type="radio" name="paises" id="ecuador" />
      <div id="chile">
        País: Chile <br/>
        Teléfono: 123456789 <br/>
        Email: chile@email.com
      </div>
      <div id="colombia">
        País: Colombia <br/>
        Teléfono: 987654321 <br/>
        Email: colombia@email.com
      </div>
      <div id="ecuador">
        País: Ecuador <br/>
        Teléfono: 192837465 <br/>
        Email: ecuador@email.com
      </div>
</div>
    
answered by 08.06.2016 / 11:17
source
6

This is the solution we found (I leave it here in case it helps people to see what we were looking for and / or if it serves as a reference), although the problem is that it gets very complicated (the list of countries is not only 3, but 30) and ends up needing a lot of extra code.

Surely you could do something with :target instead of :checked and simplify things (you could change all label by a and avoid all checkboxes).

The idea is this:

  • In the HMTL:
    • We remove the select and simulate a drop-down list using ul ;
    • We add a input of type radio for each country, before the fields that we want to update;
    • In each of the li of ul , we add a label for each of the input that we created in the previous step;
  • In the CSS:
    • We add the different styles to simulate the dropdown ;
    • Using the pseudo-class :checked and the selector ~ , we add CSS rules that will add the content depending on the radius that is selected at each moment.

The code is like this at the end:

#dropdown, #dropdown > li > ul  { 
  width:200px; 
  overflow:visible;
  line-height:20px; 
  border:1px solid gray;
  background:white;
  list-style:none;
  padding-left:0;
  margin-left:0;
  position:relative;
}

#dropdown:after {
  content:"bc";
  position:absolute;
  font-size:0.75em;
  right:2px;
  top:0;
}

#dropdown > li { 
  margin-left:0; 
  line-height:20px;
  font-size:0.9em;
}

#dropdown > li > ul {
  display:none;
}


#dropdown > li:hover > ul {
  display:block;  
  position:absolute;
  left:-1px;
}

#dropdown > li > ul > li {
  margin-left:0; 
  line-height:20px;
  padding-left:2px;
}

#dropdown > li > ul > li:hover {
  background-color:rgba(0,0,0,0.05);
}

#dropdown > li > ul > li label {
  display:block;
}

input[name="paises"] { display:none; }


#chile:checked ~ #pais:before { content:"Chile"; }
#chile:checked ~ #telefono:before { content:"123456789"; }
#chile:checked ~ #email:before { content:"chile@email.com"; }
#colombia:checked ~ #pais:before { content:"Colombia"; }
#colombia:checked ~ #telefono:before { content:"987654321"; }
#colombia:checked ~ #email:before { content:"colombia@email.com"; }
#ecuador:checked ~ #pais:before { content:"Ecuador"; }
#ecuador:checked ~ #telefono:before { content:"192837465"; }
#ecuador:checked ~ #email:before { content:"ecuador@email.com"; }
<ul id="dropdown">
  <li>
    Selecciona un país
    <ul>
      <li><label for="chile">Chile</label></li>
      <li><label for="colombia">Colombia</label></li>
      <li><label for="ecuador">Ecuador</label></li>
    </ul>
  </li>
</ul>

<div>
  <input type="radio" name="paises" id="chile" />
  <input type="radio" name="paises" id="colombia" />
  <input type="radio" name="paises" id="ecuador" />
  País: <span id="pais"></span><br/>
  Teléfono: <span id="telefono"></span><br/>
  Email: <span id="email"></span>
</div>
    
answered by 08.06.2016 в 07:16
2

Using only the selector: target, it can be simplified a bit.

body {background: #f3f5f6;}
ul {
    margin: 0;
    list-style: none;
    padding: 0;
    width: 200px;
}
ul#dropdown {float: left;}
ul#dropdown li {
    position: relative;
    line-height:30px;
    z-index: 10;
    background: white;
    text-indent: 10px;
    border-top: 1px solid #eee;
}
ul#dropdown > li:before {
    content: "";
    border-color: #7d7d7d;
    border-style: solid;
    border-width: 0 1px 1px 0;
    width: 6px;
    height: 6px;
    position: absolute;
    right: 15px;
    top: 11px;
    transform: rotate(45deg);
    z-index: 100;
}
ul#dropdown > li:hover:before {transform: rotate(-135deg);top: 13px;}
ul#dropdown li a {display: block;}
ul#dropdown ul {display: none;}
ul#dropdown li:hover ul {display: block;}
ul#dropdown ul li:hover {background: #eee;}
div#paises {float: left;}
div#paises > div {
    background: white;
    width: 200px;
    margin-left: 10px;
    padding: 15px;
    display: none;
}
:target {display: block !important;}
<ul id="dropdown">
  <li>Selecciona un país
    <ul class="selector">
      <li><a href="#chile">Chile</a></li>
      <li><a href="#colombia">Colombia</a></li>
      <li><a href="#ecuador">Ecuador</a></li>
    </ul>
  </li>
</ul>

<div id="paises">
  <div id="chile">
    País: Chile <br/>
    Teléfono: 123456789 <br/>
    Email: chile@email.com
  </div>
  <div id="colombia">
    País: Colombia <br/>
    Teléfono: 987654321 <br/>
    Email: colombia@email.com
  </div>
  <div id="ecuador">
    País: Ecuador <br/>
    Teléfono: 192837465 <br/>
    Email: ecuador@email.com
  </div>
</div>
    
answered by 25.08.2016 в 16:26