2

I have been using array_slice and it is not working. at all.

So I have 36 checkboxes.. I first do this.

$checks =  $_POST['ck'];

Then I do this.

$newAr = array_slice($checks, 0, 8);
echo implode(',', $newAr);

The point is, I want $newAr only to show me the boxes that were checked in boxes 0 - 8 in the array.

Next one would be like this.

$newAr2 = array_slice($checks, 9, 20);
echo implode(',', $newAr2);

Where as this one would show the boxes checked in boxes 9 - 20 and so on...

Here is how the HTML is done for the boxes...

<input type="checkbox" value="Demo" name="ck[]"  id="ck1">

When I do this... and when I echo either $newAr or $newAr2.. It just shows me the value of every single checkbox 1 - 36

8
  • @Anant not what I want, My main array consist of checks 1-36... I want it to be split in 3 different ones... one array with checks 1 - 8 next one with 9 - 20 and last one 21 - 36 Commented Apr 27, 2016 at 19:05
  • @Anant because that the way I want to split. Please read the question... You can see the problem with array_slice. Commented Apr 27, 2016 at 19:11
  • I think you are confused with how checkboxes work. Try die('<pre>'.print_r($_POST['ck'], true).'</pre>'); at the start of your PHP script. On the frontend, if you only checked one checkbox then only that value would be sent to the server. Based on what you are saying, all of the checkboxes are checked on the frontend. Commented Apr 27, 2016 at 19:14
  • @MonkeyZeus Not at all what I am saying... if I only do `echo implode(',', $_POST['ck']); it only shows the boxes that were checked. I need to split my main array into 3 arrays though... So I can check specifically what boxes where checked from 1-8 then 9-20 then 21-36. Commented Apr 27, 2016 at 19:16
  • @KevinM1990112qwq Since you are doing name="ck[]" on the frontend, only the checked boxes are being sent to the backend as an auto-numbered (incremental) array. If on the frontend you check off boxes 34, 35, and 36 then PHP receives $_POST['ck'][0] = "value of 34"; $_POST['ck'][1] = "value of 35"; $_POST['ck'][2] = "value of 36"; Commented Apr 27, 2016 at 19:22

3 Answers 3

4

In order to make this work, you will need to hack the HTML a little:

<input type="hidden" name="ck[0]" value="">
<input type="checkbox" value="Demo0" name="ck[0]" id="ck1">
<input type="hidden" name="ck[1]" value="">
<input type="checkbox" value="Demo1" name="ck[1]" id="ck1">
<input type="hidden" name="ck[2]" value="">
<input type="checkbox" value="Demo2" name="ck[2]" id="ck1">
<!-- repeat until name="ck[35]" -->

Explanation:

<input type="hidden" name="ck[0]" value=""> will ensure that $_POST['ck'][0] is always set and is an empty string.

<input type="checkbox" value="Demo0" name="ck[0]" id="ck1"> ensures that if the checkbox is checked then $_POST['ck'][0] will be "Demo0"

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I didn't notice this. I've edited my own answer to reference your observation.
1

As per the comments, this isn't how array_slice works. However, it's pretty trivial to knock up a function which does what you're asking for.

As MonkeyZeus points out, you will also need to alter the HTML to receive the correct indexes in the post request.

function array_slice_by_key($array, $min, $max)
{
    return array_intersect_key($array, array_combine(range($min, $max), range($min, $max)));
}

// For example
$_POST["ck"] = array(1 => 1, 4 => 1, 9 => 1, 10 => 1, 15 => 1, 22 => 1, 26 => 1);

$checks = isset($_POST["ck"]) ? $_POST["ck"] : array();

var_dump(array_slice_by_key($checks, 1, 8));
/*
array (size=2)
  1 => int 1
  4 => int 1
*/
var_dump(array_slice_by_key($checks, 9, 20));
/*
array (size=3)
  9 => int 1
  10 => int 1
  15 => int 1
*/
var_dump(array_slice_by_key($checks, 21, 36));
/*
array (size=2)
  22 => int 1
  26 => int 1
 */

Comments

1

Website demonstration: Checkboxes - current and previous state

Sources

Explanation

The issue is with checkboxes is that the is not input for then when the user unchecks them. This class can be used to record which checkboxes are being displayed and whether they are unchecked or not.

It is useful when you want to know if the checkbox state has just changed.

It also generates to value to be assigned to the checkbox in the html.

How it works:

  • It holds a list of all the checkboxes and their state (checked or not) by position.
  • This current state vector is an array or characters that is stored in a hidden field on the form.
  • Each checkbox is assigned a value based on the position in the list.

There are various details created for each checkbox based on the key (cbxDetails):

  • The label to use in the html - (cbxLabel)
  • The value to be used in the html - (cbxValue)_

  • The key of the details - _(key)

  • whether the checkbox state has changed - (hasChanged)

  • the current state - (curChecked)
  • the previous state - (prvChecked)

These details are also available via the array iterator - (getIterator)

Processing:

Build form:

  • create a new CheckboxHistory($cbxValueList)

Generate the checkboxes using

  • The label to use in the html - (cbxLabel)
  • The value to be used in the html - (cbxValue)_

  • store the current state of all the checkboxes in a hidden field e.g. 'cbxAllStates' - (cbxStateString)

When form is input, assume $_POST is used:

  • generate a new CheckboxHistory($cbxValueList)
  • if there is $_POST['cbxInputs'] then apply it - _(fromCheckedList($POST['cbxInputs']))
  • apply the state of all the checkboxes from the hidden field - _(fromCbxStateString($POST['cbxAllStates'])

All done

Code that looks after the Checkboxes List

// look after the checkbox states
$cbxHistory = new CheckboxHistory($vars);

if (isset($_POST['allBoxes'])) {
    if (isset($_POST['allBoxes']['cbxChecked'])) {
        $cbxHistory->fromCheckedList($_POST['allBoxes']['cbxChecked']);
    }
    $cbxHistory->fromCbxStateString($_POST['allBoxes']['history']);
}

// extract arrays for testing

$extract1  = array();
$extract2  = array();
$extract3  = array();

$cbxIter = $cbxHistory->getIterator();

for ($i = 0; $i <= 8; $i++) { // extract first 9 entries
    $extract1[] = $cbxIter->current();
    $cbxIter->next();
}

for ($i = 0; $i <= 12; $i++) { // extract next 12 entries
    $extract2[] = $cbxIter->current();
    $cbxIter->next();
}

while  ($cbxIter->valid()) { // extract remaining entries
    $extract3[] = $cbxIter->current();
    $cbxIter->next();
}

The class that maintains the checkboxes state

<?php //  http://stackoverflow.com/questions/36849297/variable-to-specific-parts-of-array
/**
* Maintain a list of checkboxes and the immidiate history
* 
* Uses: array of  $key => $label
* 
*   the key can be numbers or string the class works with keys     
* 
*   e.g.  $cbxHistory = new CheckboxHistory(array('key1' => 'label 1',
*                                                 'key2' => 'label 2',
*                                                 'key3' => 'label 3',
*                                                 )) 
*  
* It uses a string to hold whether each checkbox in the list currently is checked or not
* 
*  e.g.   $cbxHistory->cbxStateString()
*  
*         This will be stored in a hidden field $_POST and will become the $prvCheckedState
*           
* 
* 
*  It generates all the details to 
*     1) use in the checkbox HTML 
*          'label' is for the html checkbox label
*          'value' is for the html checkbox value
*            note: the value is a position in the list not a key!      
* 
*     2) The state of the checkbox and whether is has just changed
*
*  e.g.  $cbxHistory->cbxDetails($key);
* 
*        returns: array('label'       => $this->cbxLabel($key),
*                       'value'       => $this->cbxValue($key),
*                       'key'         => $key,
*                        
*                       'hasChanged'  => $this->hasChanged($key),
*                       'curChecked'  => $this->curChecked($key),
*                       'prvChecked'  => $this->prvChecked($key));
*      
*  It uses a cbxStateString to know what the previous states of the checkbox
* 
*    e.g.  $cbxHistory->fronCbxCheckedState($oldCbxCheckedState);
* 
*          This will normally be from the html 'hidden' cbxState field
*   
*/

class CheckboxHistory {

   protected $valueList = null; 

   protected $curCheckedState = '';

   protected $prvCheckedState = '';

   protected $keyList = null; // needed to find the position of the key

   public function __construct(array $valueList, $prvStateStr = '') 
   {
       $this->valueList = $valueList;
       $this->curCheckedState = str_repeat('0', count($this->valueList));                                      
       $this->prvCheckedState = str_repeat('0', count($this->valueList));
       $this->keyList = array_keys($valueList);       
       if (!empty($prvStateStr)) {
           $this->fromCbxStateString($prvStateStr);
       }                      
   }

   /**
   * The label value to be used in the html
   * 
   * @param mixed $key
   * 
   * @return label text
   */
   public function cbxLabel($key)
   {
       return $this->valueList[$key];
   }

   /**
   * The value to be used for the checkbox in the html.
   * 
   * It is actually the postion of the lookup key in the list
   *  
   * @param mixed $key
   * 
   * @return integer
   */
   public function cbxValue($key)
   {
       return $this->keyToPosition($key);
   }

   /**
   * This is the current state vector of all the checkboxes
   *
   * It is stored in a 'hidden' field on the form
   * 
   * It is used in the  fromCbxStateString() method  
   * 
   * @return string
   */   
   public function cbxStateString()
   {
       return $this->curCheckedState;
   }


   /**
   * All the details (checkbox state) in one convenient list
   * 
   * @param mixed $key
   * 
   * @return array 
   */
   public function cbxDetails($key)
   {
       return array('label'       => $this->cbxLabel($key),
                    'value'       => $this->cbxValue($key),
                    'key'         => $key,
                    'hasChanged'  => $this->hasChanged($key),
                    'curChecked'  => $this->curChecked($key),
                    'prvChecked'  => $this->prvChecked($key),
               );
   }

   /**
   * All the cbxDetails as an iterator
   * 
   * @return \ArrayIterator
   */
   public function getIterator()
   {
       $details = array();
       foreach($this->keyList as $key) {
           $details[] = $this->cbxDetails($key);
       }
       return new \ArrayIterator($details);
   }


   /**
   * Set or unset a checkbox by key value 
   * 
   * @param mixed   $key
   * @param boolean $checked
   * 
   * @return void
   */
   public function setCheckbox($key, $checked = true)
   {
           $keyPos = $this->keyToPosition($key);
           $this->curCheckedState[$keyPos] = $checked ? '1' : '0';
   }

   /**
   * current state of a checkbox
   * 
   * @param mixed $key
   * 
   * @return boolean
   */
   public function curChecked($key) 
   {
       $keyPos = $this->keyToPosition($key);       
       return (bool) $this->curCheckedState[$keyPos];
   }

   /**
   * previous state of a checkbox
   * 
   * @param mixed $key
   * 
   * @return booleam
   */
   public function prvChecked($key) 
   {
       $keyPos = $this->keyToPosition($key);       
       return (bool) $this->prvCheckedState[$keyPos];
   }

   /**
   * Has the checkbox changed state (user checked or unchecked it)
   * 
   * @param mixed $key
   * 
   * @return boolean
   */
   public function hasChanged($key)
   {
       $keyPos = $this->keyToPosition($key);       
       return $this->curCheckedState[$keyPos] !== $this->prvCheckedState[$keyPos];
   }   

   /**
   * set the curCheckedState from an array of values ($positions)
   *  
   * @param array $positionList i.e. $_POST
   * 
   * @return void
   */
   public function fromCheckedList(array $checkedPos)
   {
       $this->curCheckedState = str_repeat('0', count($this->valueList));                                      
       foreach ($checkedPos as $position) {           
           $this->setCheckbox($this->keyList[$position], true);
       }
   }

   /**
   * This is the previous state of the all checkboxes
   * 
   * It is obtained from the chechboxes 'hidden' field
   * 
   * @param string $prvStateStr
   * 
   * @return void
   */
   public function fromCbxStateString($prvStateStr) 
   {
       // must be the correct lentgth
       $this->prvCheckedState = str_pad($prvStateStr, count($this->valueList), $this->prvCheckedState);
   }


   // given a key get the postion of the key in the list
   protected function keyToPosition($key)
   {
       return array_search($key, $this->keyList);
   }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.