[PHP] multiple "multiple select" en $_POST

Pagina: 1
Acties:
  • 815 views sinds 30-01-2008
  • Reageer

Onderwerpen


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
Ik heb een formgenerator gemaakt, waarmee mensen meerdere waardes uit een database op een form kunnen aanpassen, en die spuugt zoiets uit:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
  print_r($_POST);  
?>

<form method="post">
<input type="hidden" name="ID[]" value="1">
<input name="naam[]" type="text" value="Piet" />
<select name="hobbies[]" multiple="multiple">
    <option value="fietsen">fietsen</option>
    <option value="zwemmen">zwemmen</option>
    <option value="paardrijden">paardrijden</option>
</select>
</form>


In PHP werkt dit: ik heb netjes [] geplaatst achter de 'name' van de multiple select. Echter, ik wil twee entries tegelijkertijd kunnen editen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<form method="post">
<input type="hidden" name="ID[]" value="1">
<input name="naam[]" type="text" value="Piet" />
<select name="hobbies[]" multiple="multiple">
    <option value="fietsen">fietsen</option>
    <option value="zwemmen">zwemmen</option>
    <option value="paardrijden">paardrijden</option>
</select>

<input type="hidden" name="ID[]" value="2">
<input name="naam[]" type="text" value="Klaas" />
<select name="hobbies[]" multiple="multiple">
    <option value="fietsen">fietsen</option>
    <option value="zwemmen">zwemmen</option>
    <option value="paardrijden">paardrijden</option>
</select>

<input type="submit" value="Send" />
</form>


en dit werkt niet, wat alhoewel de waarden voor de "ID[]" en "naam[]" netjes in een array komen, worden de waarden van beide multiple selectboxen (met naam "hobbies[]") op een hoop gegooid.

Ofwel, als ik alle opties in beide lijsten aanvink:

code:
1
2
3
4
5
6
7
8
9
    [hobbies] => Array
        (
            [0] => fietsen
            [1] => zwemmen
            [2] => paardrijden
            [3] => fietsen
            [4] => zwemmen
            [5] => paardrijden
        )


in plaats van:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[hobbies] => Array
(
  [0]=> Array
  (
    [0] => fietsen
    [1] => zwemmen
    [2] => paardrijden
  )
  [1]=> Array
  (
    [0] => fietsen
    [1] => zwemmen
    [2] => paardrijden
  )
)


Is dit op te lossen, en zo ja, hoe? Ik kan natuurlijk alle geselecteerde waarden van alle multiple selectboxes in <input type="hidden" name="multipleselectboxes[]"> gooien, maar levert dit geen problemen op bij selectboxes met veel, zeg 1000, waarden?

[ Voor 0% gewijzigd door Rekcor op 27-09-2006 17:41 . Reden: Verdraaid, ik kan de naam niet meer aanpassen. Mods, mag er [PHP/HTML] voor? ]


Verwijderd

name="hobbies[0][]"
name="hobbies[1][]"

[ Voor 25% gewijzigd door Verwijderd op 27-09-2006 17:44 ]


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
Dank, dat had ik ook al geprobeerd (zonder succes).

  • Icelus
  • Registratie: Januari 2004
  • Niet online
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<form method="post">
  <input type="hidden" name="Data1[ID]" value="1">
  <input name="Data1[naam]" type="text" value="Piet"/>
  <select name="Data1[hobbies][]" multiple="multiple">
    <option value="fietsen">fietsen</option>
    <option value="zwemmen">zwemmen</option>
    <option value="paardrijden">paardrijden</option>
  </select>

  <input type="hidden" name="Data2[ID]" value="2">
  <input name="Data2[naam]" type="text" value="Klaas" />
  <select name="Data2[hobbies][]" multiple="multiple">
    <option value="fietsen">fietsen</option>
    <option value="zwemmen">zwemmen</option>
    <option value="paardrijden">paardrijden</option>
  </select>

  <input type="submit" value="Send" />
</form>

[ Voor 3% gewijzigd door Icelus op 27-09-2006 17:54 ]

Developer Accused Of Unreadable Code Refuses To Comment


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
@Icelus,

Bedankt, maar waarom zou ik "Data1[ID]" dan niet gewoon veranderen in "ID1"?

Dat is echter niet wat ik wil, aangezien "<name>[]" juist zo lekker flexibel is.

  • Icelus
  • Registratie: Januari 2004
  • Niet online
Rekcor schreef op woensdag 27 september 2006 @ 17:59:
@Icelus,

Bedankt, maar waarom zou ik "Data1[ID]" dan niet gewoon veranderen in "ID1"?

Dat is echter niet wat ik wil, aangezien "<name>[]" juist zo lekker flexibel is.
Je bedoelt ID1[] ?
Dat kan natuurlijk ook.

Als je ID1 bedoelt wordt het wat lastiger. Door de velden als groep – dat is de bedoeling? – te behandelen kun je ze eenvoudig verwerken.
Per groep kies je een unieke naam (bijv. ID1[]) waarna je met bijv. een for-each door de $_POST kan lopen.

$_POST bevat dan:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$_POST =>
Array
(
    [Data1] => Array
        (
            [ID] => 1
            [naam] => Piet
            [hobbies] => Array
                (
                    [0] => fietsen
                )

        )

    [Data2] => Array
        (
            [ID] => 2
            [naam] => Klaas
            [hobbies] => Array
                (
                    [0] => zwemmen
                    [1] => paardrijden
                )

        )

)

Developer Accused Of Unreadable Code Refuses To Comment


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
@Icelus,

Ik denk dat ik inderdaad jouw richting op moet gaan. Het nadeel van die methode - maar blijkbaar kan het niet anders - is dat ik iedere dataset expliciet een nummer moet geven:

Data1[ ID ]

aangezien ik m.b.v. Javascript DOM een n-aantal kopieen van de groep wil kunnen maken, met als gevolg:

Data1[ ID ]
Data1[ ID ]
Data1[ ID ]

Ik moet dan Javascript instrueren om de kopieen te hernummeren:

Data1[ ID ]
Data2[ ID ]
Data3[ ID ]

Wat natuurlijk wel kan, maar minder 'smooth' werkt (en onderhevig is aan mogelijke bugs) dan wanneer ik me helemaal niet over de nummering hoefde te bekommeren:

Data[][ ID ]
Data[][ ID ]
Data[][ ID ]

(bovenstaande werkt overigens wel voor gewone form-elementen, maar dus niet voor multiple select boxes)

He maar bedankt!

[ Voor 1% gewijzigd door Rekcor op 28-09-2006 09:19 . Reden: vergeten te bedanken ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Gewoon doen wat cheatah zegt:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<form method="post">
    <input type="hidden" name="ID[1]" value="1">
    <input name="naam[1]" type="text" value="Piet">
    <select name="hobbies[1][]" multiple="multiple">
        <option value="fietsen">fietsen</option>
        <option value="zwemmen">zwemmen</option>
        <option value="paardrijden">paardrijden</option>
    </select>
    <input type="hidden" name="ID[2]" value="2">
    <input name="naam[2]" type="text" value="Klaas">
    <select name="hobbies[2][]" multiple="multiple">
        <option value="fietsen">fietsen</option>
        <option value="zwemmen">zwemmen</option>
        <option value="paardrijden">paardrijden</option>
    </select>
    <input type="submit" value="Send">
</form>

PHP:
1
var_dump($_POST);

Mogelijk output:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
array(3) {
  ["ID"]=>
  array(2) {
    [1]=>
    string(1) "1"
    [2]=>
    string(1) "2"
  }
  ["naam"]=>
  array(2) {
    [1]=>
    string(4) "Piet"
    [2]=>
    string(5) "Klaas"
  }
  ["hobbies"]=>
  array(2) {
    [1]=>
    array(2) {
      [0]=>
      string(7) "fietsen"
      [1]=>
      string(11) "paardrijden"
    }
    [2]=>
    array(2) {
      [0]=>
      string(7) "fietsen"
      [1]=>
      string(7) "zwemmen"
    }
  }
}

Werkt dus zeker wel.

Noushka's Magnificent Dream | Unity


Verwijderd

en als je gewoon dit hard doet:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
<form method="post">
<input type="hidden" name="ID[1]" value="1">
<input name="naam[1]" type="text" value="Piet" />
<select name="hobbies[1]" multiple="multiple">
    <option value="fietsen">fietsen</option>
    <option value="zwemmen">zwemmen</option>
    <option value="paardrijden">paardrijden</option>
</select>

<input type="hidden" name="ID[2]" value="2">
<input name="naam[2]" type="text" value="Klaas" />
<select name="hobbies[2]" multiple="multiple">
    <option value="fietsen">fietsen</option>
    <option value="zwemmen">zwemmen</option>
    <option value="paardrijden">paardrijden</option>
</select>

<input type="submit" value="Send" />
</form>
?>

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
Doe het nu als volgt. Multiple selectboxes die ik wil posten krijgen een extra attribuut: putInHidden="true"
HTML:
1
2
3
4
5
6
7
8
9
<form method="post" id="theForm">
  <select putInHidden="true" name="hobbies[]" multiple="multiple">
    <option value="fietsen">fietsen</option>
    <option value="zwemmen">zwemmen</option>
    <option value="paardrijden">paardrijden</option>
  </select>

  <input type="submit" onclick="putMultipleSelectValuesInHiddenInput('theForm'); document.getElementById('theForm').submit()" value="Send" />
</form>

Voor het form wordt gesubmit, wordt de volgende Javascript-code aangeroepen:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<script type="text/javascript">
function putMultipleSelectValuesInHiddenInput(sFormId)
{
  //get form
  oForm = document.getElementById(sFormId);
  
  //get selectboxes in form
  aoSelectboxes = oForm.getElementsByTagName('select');
    
  for (i=0; i<aoSelectboxes.length; i++)
  {
    asOptionValues = new Array();
    
    //only use selectboxes with attribute putInHidden='true'
    if (aoSelectboxes[i].getAttribute('putInHidden')=='true')
    {
      //put option values in array      
      aoOptions = aoSelectboxes[i].options;
      for (j=0; j<aoOptions.length; j++)
      {        
        asOptionValues[j] = aoOptions[j].value;
      }
      
      //create hidden input element
      var oHidden = document.createElement('input');      
      oHidden.setAttribute('type', 'hidden');
      oHidden.setAttribute('name', aoSelectboxes[i].getAttribute('name'));
      
      //add option values to hidden input element 
      oHidden.setAttribute('value', asOptionValues.toString());
      
      //insert hidden input element before selectbox
      oForm.insertBefore(oHidden, aoSelectboxes[i]);
      
      //hide select box from form by clearing its name
      aoSelectboxes[i].setAttribute('name', '');      
    }  
  }
}
</script>

Dit werkt goed! Enige probleem: de option values mogen geen komma's bevatten, aangezien de toString method ook komma's gebruikt.
HTML:
1
2
<!-- dit mag dus niet -->
<option value="fiets, auto">Fiets- en autovakanties</option>

Nog een nadeel: XHTML accepteert voor zover ik weet geen 'user defined' attributen (maar wie geeft er nou om XHTML-validatie :9). Zou je per se validatie willen, dan kun je gewoon alle multiple select boxen in hidden input velden stoppen.
JavaScript:
1
if (aoSelectboxes[i].getAttribute('putInHidden')=='true')

wordt dan
JavaScript:
1
if (aoSelectboxes[i].getAttribute('multiple')=='multiple')

[ Voor 13% gewijzigd door Rekcor op 28-09-2006 10:10 . Reden: nog een nadeel ontdekt ]


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
@Cheatah, Michali,

Bedankt, maar dan moet ik nog zelf mijn form elementen nummers mee gaan geven (wat ik niet wil).

Verwijderd

Rekcor schreef op donderdag 28 september 2006 @ 10:07:
@Cheatah, Michali,

Bedankt, maar dan moet ik nog zelf mijn form elementen nummers mee gaan geven (wat ik niet wil).
Wat je niet wilt omdat?
Ik vind het best dat je zulke vragen stelt, maar ga dan niet met onzinnige eisen komen als "ik wil zelf geen nummers gaan genereren". De reden dat PHP met naam[] gewoon al werkt is omdat bij een enkelvoudige array bekend is in welke dimentie een waarde opgehoogd moet worden. Bij een multidimensionale array is dat uiteraard niet bekend. Verwacht dan ook geen magie.

  • Equator
  • Registratie: April 2001
  • Laatst online: 09-09 15:29

Equator

Crew Council

#whisky #barista

En assoc array's :?

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<form action="showpost.php" method="post">
<select multiple name="output[hobbies][]">
    <option value="test">test</option>
    <option value="test1">test1</option>
    <option value="test2">test2</option>
    <option value="test3">test3</option>
    <option value="test4">test4</option>
</select>

<select multiple name="output[wensen][]">
    <option value="2test">2test</option>
    <option value="2test1">2test1</option>
    <option value="2test2">2test2</option>
    <option value="2test3">2test3</option>
    <option value="2test4">2test4</option>
</select>
<input type="submit" value="submit">
</form>


output:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Array
(
    [output] => Array
        (
            [hobbies] => Array
                (
                    [0] => test1
                    [1] => test2
                    [2] => test3
                )

            [wensen] => Array
                (
                    [0] => 2test
                    [1] => 2test1
                    [2] => 2test2
                    [3] => 2test3
                )

        )

)


Misschien dat je dat wel fijner vindt werken :?

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
Bedankt voor je reactie Equator!

Ik heb nog een Javascriptfunctie geschreven. Door deze functie kan ik - lekker eigenwijs - mijn <select>-boxes gewoon de naam "myName[][]" geven. De functie nummert de verschillende <select>-boxes naar "myName[0][], myName[1][], enzovoort.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* function renumberMultipleSelectboxes(sFormId)
* 
* + renumbers multiple select boxes (as PHP doesn't like multiple 
*   multiple select boxes)
* 
*  @param  string  sFormId  id of the form containing the multiple select boxes
* 
*  Usage: Select boxes must be defined as:
* 
*   <select multiple="multiple" name="myName[][]">
*     <option>..</option>
*   </select>
*   <select multiple="multiple" name="myName[][]">
*     <option>..</option>
*   </select>
*   <select multiple="multiple" name="myName[][]">
*     <option>..</option>
*   </select>
* 
*   The script will rename them like this
* 
*   <select multiple="multiple" name="myName[0][]">
*     <option>..</option>
*   </select>
*   <select multiple="multiple" name="myName[1][]">
*     <option>..</option>
*   </select>
*   <select multiple="multiple" name="myName[2][]">
*     <option>..</option>
*   </select>
**/
function renumberMultipleSelectboxes(sFormId)
{
  var iMultipleCount = 0;
  
  //regular expression matching "[<optional number>][]"
  var sRegExp  = /\[((\d)*)?\]\[/;
  
  //get form
  oForm = document.getElementById(sFormId); 
  
  //get selectboxes in form
  aoSelectboxes = oForm.getElementsByTagName('select');
    
  for (i=0; i<aoSelectboxes.length; i++)
  {    
    //only alter selectboxes with multiple attribute
    if (aoSelectboxes[i].getAttribute('multiple')=='multiple')
    {       
       sName = aoSelectboxes[i].getAttribute('name');
       if (sName)
       {        
        //replace [<number>][] with [i][]       
        sName = sName.replace(sRegExp, '['+iMultipleCount+'][');       
        aoSelectboxes[i].setAttribute('name', sName);
        iMultipleCount++;   
       }     
    }
  }
}


Mijn speciale dank aan het adres van Cheatah en Michali _/-\o_

[ Voor 2% gewijzigd door Rekcor op 29-09-2006 17:59 . Reden: bug ]


  • Equator
  • Registratie: April 2001
  • Laatst online: 09-09 15:29

Equator

Crew Council

#whisky #barista

En hoe hou je nou makkelijk bij welke select je moet hebben voor de verwerking.. :? 0,1 of misschien wel 43..

* Equator ziet er het nut niet van in.. geef mij maar associatieve array's :)

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Maar als je waarden bij een bepaald ID wilt houden, dan is het wel zo handig dat ID te gebruiken als key. Puur met associatieve arrays gaat dat niet lukken. Overigens ben ik niet zo tevreden over mijn eigen voorbeeld. Veel beter is dit:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<form method="post">
    <input type="hidden" name="data[1][ID]" value="1">
    <input name="data[1][naam]" type="text" value="Piet">
    <select name="data[1][hobbies][]" multiple="multiple">
        <option value="fietsen">fietsen</option>
        <option value="zwemmen">zwemmen</option>
        <option value="paardrijden">paardrijden</option>
    </select>
    <input type="hidden" name="data[2][ID]" value="2">
    <input name="data[2][naam]" type="text" value="Klaas">
    <select name="data[2][hobbies][]" multiple="multiple">
        <option value="fietsen">fietsen</option>
        <option value="zwemmen">zwemmen</option>
        <option value="paardrijden">paardrijden</option>
    </select>
    <input type="submit" value="Send">
</form>

mogelijke $_POST:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
array(1) {
  ["data"]=>
  array(2) {
    [1]=>
    array(3) {
      ["ID"]=>
      string(1) "1"
      ["naam"]=>
      string(4) "Piet"
      ["hobbies"]=>
      array(2) {
        [0]=>
        string(7) "fietsen"
        [1]=>
        string(11) "paardrijden"
      }
    }
    [2]=>
    array(3) {
      ["ID"]=>
      string(1) "2"
      ["naam"]=>
      string(5) "Klaas"
      ["hobbies"]=>
      array(2) {
        [0]=>
        string(7) "fietsen"
        [1]=>
        string(7) "zwemmen"
      }
    }
  }
}

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
Equator schreef op donderdag 28 september 2006 @ 18:51:
En hoe hou je nou makkelijk bij welke select je moet hebben voor de verwerking.. :? 0,1 of misschien wel 43..

* Equator ziet er het nut niet van in.. geef mij maar associatieve array's :)
In mijn toepassing zit in ieder 'blokje met formelementen' een <input name="ID" value="<ID in database">

Acties:
  • 0 Henk 'm!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
Michali schreef op donderdag 28 september 2006 @ 19:26:
Maar als je waarden bij een bepaald ID wilt houden, dan is het wel zo handig dat ID te gebruiken als key. Puur met associatieve arrays gaat dat niet lukken. Overigens ben ik niet zo tevreden over mijn eigen voorbeeld. Veel beter is dit:
Code
Heb ik ook nog aan gedacht; het hidden veld zou je eventueel weg kunnen laten omdat je de ID ook als sleutel gebruikt. Als je deze ook in Javascript nodig hebt is dat natuurlijk niet mogelijk.

[ Voor 7% gewijzigd door Icelus op 29-09-2006 10:02 ]

Developer Accused Of Unreadable Code Refuses To Comment

Pagina: 1