Reputation: 237
I am developing an internal CakePHP company application that has a despatch screen, which has three lists:
The user can drag items from the left list to the right list and vice versa. Once the click the Save button, the form is submitted with the items on the right list.
As part of the save, I need to compare (using PHP) the updated list with the saved list from the database.
With any additions, I need to update the items record with the despatch ID.
With any removals, I need to update the items record to sell the despatch ID to NULL.
This would allow users to drag and drop items in both directions, then click Save and expect the page to load with the state they left the page in.
I am able to save items to be added to the list and, separately, save items being removed. However, I cannot get them working together. When I try this, one item being added to the list completely replace all the other items on the "Packed Items" list.
function edit() {
$this->Despatch->recursive = -1;
if (!empty($this->data)) {
if($this->Despatch->save($this->data)) {
/* NEED TO RETRIEVE CURRENT REPAIR IDs ASSOCIATED
WITH THE DESPATCH ID AND COMPARE WITH FORM SUBMISSION LIST TO
REMOVE THE DIFFERENCES */
# Retrieve current repair records where despatch_id = $this->id.
$this->Despatch->Repair->recursive = -1;
$current_associated_repairs = $this->Despatch->Repair->find('all', array(
'fields' => array('id', 'despatch_date', 'despatch_id'),
'conditions' => array('Repair.despatch_id =' => $this->data['Despatch']['id'])));
# Create array with repair IDs
$repairs = explode(",", $this->data['Repair']['ids']);
$i = 0;
foreach($repairs as $repair) {
$repairupdates[$i]['Repair']['id'] = $repair;
$i++;
}
# Delete array index to prevent it interfering with form saving later
unset($this->data['Repair']['ids']);
# 2. Find unmatched IDs between current records and form submission list of repairs
$length1 = sizeof($current_associated_repairs);
$length2 = sizeof($this->data['Repair']);
for ($i = 0; $i < $length1; $i++) {
for ($j = 0; $j < $length2; $j++) {
### LOGIC NOT CORRECT HERE !!! ###
### THIS WORKS FOR REMOVING PACKED INSTRUMENTS - FROM RIGHT TO LEFT ###
### BUT ACTUALLY BEING TRIGGERED WHEN ADDING FROM LEFT TO RIGHT TOO ###
if ($current_associated_repairs[$i]['Repair']['id'] == $this->data['Repair'][$j]['id']
&& !in_array($current_associated_repairs[$i]['Repair']['id'], $this->data['Repair'][$j])) {
# if it's in current repairs and not in form submission, set to null...
# otherwise, it must be an addition if there's no matches
# 3. Set the despatch_date and despatch_id fields of those records to NULL
$this->data['Repair'][$j+1]['id'] = $current_associated_repairs[$i]['Repair']['id'];
$this->data['Repair'][$j+1]['despatch_date'] = null;
$this->data['Repair'][$j+1]['despatch_id'] = null;
}
}
}
# 4. Save the new list of repairs to the current despatch
if($this->Despatch->save($this->data) && $this->Despatch->Repair->saveAll($this->data['Repair'])) {
$this->Session->setFlash(__('The despatch has been saved.', true), 'default', array('class' => 'success-scheme message'));
} else {
$this->Session->setFlash(__('The repair could not be updated with the despatch number. Please try again.', true), 'default', array('class' => 'error-scheme message'));
}
} else {
$this->Session->setFlash(__('The despatch could not be saved. Please try again.', true), 'default', array('class' => 'error-scheme message'));
}
$this->redirect($this->referer(array('action' => 'view', $this->data['Despatch']['id'])));
}
}
I think I've included all the detail anyone should need, but just ask if you need to know more. The main problem I'm having is understanding the logic the code for achieving this.
Many thanks in advance.
// click handler for saving despatch - required to save sortable lists properly
$('#save_despatch').click(function(e) {
e.preventDefault();
// gives comma-separated array of instrument IDs, e.g. 12345, 56789...
var result = $('#sortable2').sortable('toArray');
$('#RepairIds').val(result);
$('form').submit();
});
Upvotes: 0
Views: 655
Reputation: 3460
I can not really figure out what you are doing now in your logic, but I will suggest an approach that should work without a doubt.
You have two lists, for simplicity: left and right. This code is sort of pseudocode because I do not fully understand what you need, but this way, the lists should remain updated, and it cant go wrong.
Logic before displaying the lists (in PHP):
//Retrieve records from mysql into two arrays->aLeft and aRight
//Create an MD5 hash to easily compare current en future lists.
$sCheckSum = md5(implode(",",$aLeft));
$_SESSION['checkSum'] = $sCheckSum;
//Generate your lists now
//Display output
JS:
$('#save_despatch').click(function(e) {
e.preventDefault();
// gives comma-separated array of instrument IDs, e.g. 12345, 56789...
var leftResult = $('#sortable2').sortable('toArray');
var rightResult = $('#sortableX').sortable('toArray'); //Make sure this matches your lists, as I have not seen your HTML
$('#Left').val(leftResult);
$('#Right').val(rightResult);
$('form').submit();
});
Then on the receiving end:
//Get the values of the #Left and #Right inputs in to $aLeft and $aRight
$sNewCheckSum = md5($aLeft);
if($sNewCheckSum != $_SESSION['checkSum'] ) //Left list is not the same, so the right is neither
{
foreach(explode(",",$aLeft) as $iRepairId){
//Not sure what should happen here, but thats up to you.
//Mysql update table SET ID = NULL WHERE repairdId = $iRepairId
}
foreach(explode(",",$aRight) as $iRepairId){
//Not sure what should happen here, but thats up to you.
//Mysql update table SET ID = xxx WHERE repairdId = $iRepairId
}
}
Upvotes: 2