Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Monen checkboxin aktivointi kerralla?

Sivun loppuun

kasparov [22.02.2016 19:19:39]

#

Hei, onko mahdollista & miten tehdä php html toteutettuun lomakkeeseen "pikavalintoja", niin että yhdellä painikkeella valitsee useamman checkboxin kerralla?

Esim. jos minulla on pitkä lista maista ja haluaisin painikkeita kuten "Pohjoismaat" niin se rastittaisi automaattisesti fin, swe, nor tai vastaavasti "Amerikka" painike rastittaisi usa ja can.

<input type="checkbox" name="fin" value="0">Finland<br/>
<input type="checkbox" name="swe" value="0">Sweden<br/>
<input type="checkbox" name="nor" value="0">Norway<br/>
<input type="checkbox" name="ger" value="0">Germany<br/>
<input type="checkbox" name="usa" value="0">USA<br/>
<input type="checkbox" name="can" value="0">Canada<br/>

Grez [22.02.2016 19:33:58]

#

<button onclick="checkmany('usa,can')">Amerikka</button>
<button onclick="checkmany('fin,swe,nor')">Pohjoimaat</button>
<script>
function checkmany(list) {
  var l = list.split(',')
  var cbs = document.getElementsByTagName('input')
  for (var i=0; i<cbs.length; i++) {
    if (cbs[i].type=='checkbox') {
      for (var j=0; j<l.length;j++) {
        if (cbs[i].name==l[j]) {
          cbs[i].checked = true
          break
        }
      }
    }
  }
}</script>

Metabolix [22.02.2016 20:00:11]

#

Jos on hyväksyttävää luetella vaihtoehdot, voi tehdä Grezin esityksen mukaan eli laittaa painikkeen onclick-käsittelijään listan muutettavista.

Toinen vaihtoehto on ryhmitellä elementit valmiiksi attribuuteilla (luokilla tai data-attribuuteilla) ja käyttää painikkeessa tätä nimettyä ryhmää. Sopivalla toteutuksella tähän on helppo liittää myös yksittäisten maiden valinta nimen perusteella. Seuraavassa esimerkissä on mallin vuoksi sekoitettu monia tapoja; oikeasti tietenkin kannattaa valita yksi tapa, jota käyttää.

<!DOCTYPE html>
<meta charset="UTF-8" />
<title>HOWTO: Set checkbox state by attributes</title>
<style>
fieldset#countries label {
  display: block;
}
</style>
<script>
function setCheckboxState(selector, checked) {
  var l = document.getElementById("countries").querySelectorAll(selector)
  for (var i = 0; i < l.length; i++) {
    l[i].checked = checked
  }
}
</script>

<fieldset id="countries">
<label><input type="checkbox" name="FI" data-scandinavia class="europe" value="1">Finland</label>
<label><input type="checkbox" name="SE" data-scandinavia class="europe" value="1">Sweden</label>
<label><input type="checkbox" name="NO" data-scandinavia class="europe" value="1">Norway</label>
<label><input type="checkbox" name="DE" class="europe" value="1">Germany</label>
<label><input type="checkbox" name="US" value="1">USA</label>
<label><input type="checkbox" name="CA" value="1">Canada</label>
</fieldset>

<fieldset>
<button onclick="setCheckboxState('input[name=US], input[name=CA]', true)">
  Amerikka
</button>

<button onclick="setCheckboxState('input[data-scandinavia]', true)">
  Pohjoimaat
</button>

<button onclick="setCheckboxState('input.europe', true)">
  Eurooppa
</button>

<button onclick="setCheckboxState('input', false), setCheckboxState('input[name=FI]', true)">
  Vain Suomi
</button>

<button onclick="setCheckboxState('input', false)">
  Tyhjennä
</button>
</fieldset>

Maiden nimille kannattaa käyttää vakiintuneita lyhenteitä eikä kehitellä omia.

Laatikon arvona 1 on loogisempi kuin 0, koska arvo lähetetään kuitenkin vain, kun laatikko on valittuna, ja 0 on silloin mielestäni harhaanjohtava.

The Alchemist [22.02.2016 23:14:36]

#

Minua häiritsee lähtökohtaisesti jo se, että koodista on tehty kaikilla osa-alueilla sellaista, että asioiden automatisointi on mahdollisimman vaikeaa, ja se taas on huonoa ohjelmointia.

Kentät voi ryhmitellä javascriptissä kahdella eri kriteerillä: joko data-attribuutilla tai jopa käärimällä ryhmään kuuluvat valintalaatikot ryhmittelevän elementin sisään (esimerkissäni fieldset.input-region).

Sisällytin esimerkkiini myös toiminnon valinnan kumoamiseen klikkaamalla nappia toisen kerran.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8"/>
  <title>Chekpoxes</title>
</head>
<body>
  <form id="the-form">
    <fieldset class="field-countries">
      <legend>Countries</legend>
      <fieldset class="input-region region-scandinavia">
        <legend>Scandinavia</legend>
        <label>
          <input type="checkbox" name="country[]" value="fi" data-region="scandinavia"/>
          <span>Finland</span>
        </label>
        <label>
          <input type="checkbox" name="country[]" value="no" data-region="scandinavia"/>
          <span>Norway</span>
        </label>
        <label>
          <input type="checkbox" name="country[]" value="sv" data-region="scandinavia"/>
          <span>Sweden</span>
        </label>
      </fieldset>
      <fieldset class="input-region region-north-america">
        <legend>North America</legend>
        <label>
          <input type="checkbox" name="country[]" value="us" data-region="north-america"/>
          <span>USA</span>
        </label>
        <label>
          <input type="checkbox" name="country[]" value="ca" data-region="north-america"/>
          <span>Canada</span>
        </label>
      </fieldset>
    </fieldset>
    <fieldset>
      <legend>Select whole region</legend>
      <button type="button" class="select-region" value="scandinavia" data-mode="select">Pohjoismaat</button>
      <button type="button" class="select-region" value="north-america" data-mode="select">Pohjois-Amerikka</button>
    </fieldset>
    <div>
      <button>Submit</button>
    </div>
  </form>

  <script>
    var buttons = Array.prototype.slice.call(document.querySelectorAll("button.select-region"));
    buttons.forEach(function(button) {
      button.addEventListener("click", function() {
        var select = button.dataset.mode == "select";
        var region = button.value;
        var countries = document.querySelectorAll("input[data-region='" + region + "']");
        button.dataset.mode = select ? "unselect" : "select";
        Array.prototype.slice.call(countries).forEach(function(country) {
          country.checked = select;
        });
      });
    });
  </script>
</body>
</html>

Metabolix kirjoitti:

Maiden nimille kannattaa käyttää vakiintuneita lyhenteitä eikä kehitellä omia.

Kolmimerkkiset koodit ovat yhtälailla yleinen standardi kuin kaksimerkkisetkin. Lokalisointia ajatellen kaksi merkkiä pitkät koodit ovat kuitenkin kätevämpiä.

Grez [22.02.2016 23:35:53]

#

Minua häiritsee tuossa Alchemistin esimerkissä että kenttien nimissä on []. Toki ymmärrän että se on PHP:n rajoitteiden vuoksi kätevää, mutta mielestäni rumaa tuossa HTML:ssä.

Sinänsä olen kyllä Alchemistin kanssa samaa mieltä että noillakin lähtökohdilla koodista voi tehdä parempaa, kuten Alchemistin esimerkissä.

The Alchemist [22.02.2016 23:42:09]

#

Grez kirjoitti:

(22.02.2016 23:35:53): Minua häiritsee tuossa Alchemistin esimer­kis­sä...

Ei se minusta ole rajoite vaan ainoa järjellinen tapa parsia arvot. Ilman hakasulkuja yksiarvoisesta joukosta ei voi suoraan erottaa, pitäisikö se parsia skalaariksi vai listaksi skalaareja. Vaikka php:n vakiototeutus ei tue useamman arvon lukemista $_POST- ja $_GET-taulukoista (samasta indeksistä) ilman hakasulkujen käyttöä, niin koodarihan voi halutessaan parsia arvot suoraan http-pyynnön datasta parhaaksi näkemällään tavalla.

Grez [23.02.2016 00:01:54]

#

Ainoa järjellinen tapa? :D

Minulle tulee montakin muuta järjellistä tapaa mieleen, eikä ne kaikki vaadi että parserin toimintalogiikkaa pitää ohjata HTML:n kautta. Tiedostan kyllä että tuo on PHP-mäinen tapa tehdä asia. Eli ensin hutkitaan (parsitaan mitä tahansa selaimelta sattuu tulemaan) ja sitten vasta tutkitaan (aletaan katsoa tuliko mitä haluttiin). Kommentoin vain sitä, että siitä tulee rumannäköistä HTML:ää. Mielestäni tuo "concern" ei kuulu HTML-lomakkeelle.

Laitetaan nyt yksi esimerkki, jossa lomakekäsittelijä määriteltäisiin funktiona

Result TheForm(string[] country) {
   //Täällä varsinaisen käsittelyn koodi
}

Tässä esimerkissä siis syöte parseroitaisiin vasta kun koodin puolella on kerrottu että POST-lähetyksestä halutaan ainoastaan country -nimiset arvot merkkijonotaulukkoon. Ja HTML-lomakkeella olisi sitten vastaavasti name="country"

Metabolix [23.02.2016 16:46:22]

#

The Alchemist kirjoitti:

Metabolix kirjoitti:

Maiden nimille kannattaa käyttää vakiintuneita lyhenteitä eikä kehitellä omia.

Kolmimerkkiset koodit ovat yhtälailla yleinen standardi kuin kaksimerkkisetkin.

Ovat varmasti, mutta sielläkin esim. ISO 3166-1 alpha-3 -standardissa Saksa olisi DEU eikä ger, kuten aloittajalla.

kasparov [23.02.2016 18:54:16]

#

Wau, iso kiitos kaikille, paljon enemmän vastauksia ja vinkkejä, vieläpä huomattavasti nopeammin kuin uskalsin edes toivoa. Nyt sain liiankin hienoja ja valmiita koodeja testattavaksi. Varsinainen lomakkeeni ei valitettavasti liity maihin mitenkään, vaan ajattelin että tuolla olisi helppo demota mitä yritän toteuttaa. Paljon kiitoksia, yritän soveltaa vaihtoehtoja jos saisin lomakkeen valmiiksi tällä viikolla.

kasparov [23.02.2016 21:19:24]

#

Pienen pähkäilyn jälkeen sain muokattua lomakkeen toimimaan haluamallani tavalla (pahoittelen ettei koodi ole yhtä ammattimaista kun hienoissa ohjeissanne), muutenkin tarkoitus vielä muokata ulkoasu ym. mutta pääasia että logiikka toimii alkuvaiheessa. Saisikohan saman otsakkeen alla vielä kysyä vinkkiä miten tehdä painike joka arpoo aktiiviseksi vaikka 5 valintaa (tai vielä parempi jos määrän voisi kirjoittaa johonkin kenttään). Loppuun linkki nykyiseen versioon: http://teamkn.net/tkn/lures/formf.php


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta