[Ask] Master Detail

Dear All, saya seorang pemula yang sedang belajar Php dengan Yii framework. Saya punya table sbb

MsBarang (KdBarang, NmBarang, Harga)

TransHeader (KdTrans, TglTrans)

TransDetail (KdTrans, KdBarang, Jumlah)

bagaimana caranya supaya saya bisa punya form transaksi kaya di minimarket?

saya sudah baca ini http://www.yiiframework.com/forum/index.php/topic/19591-master-detail-form-example/

tapi saya bingung.

Mohon pencerahannya.

Terim kasih.

Kalo formnya, cobalah dari yg paling sederhana dulu.

  1. buat field untuk inputan TransHeader



Kode Transaksi [_____________]

Tgl Transakasi [_____________]



viewnya kurang lebih seperti ini:




<?php $form = $this->beginWidget('CActiveForm', array('id'=>'trans-form')); ?>


<?php echo $form->errorSummary($model); ?>


<div class="row">

    <?php echo $form->labelEx($model,'KdTrans'); ?>

    <?php echo $form->textField($model,'KdTrans'); ?>

</div>

<div class="row">

    <?php echo $form->labelEx($model,'TglTrans'); ?>

    <?php echo $form->textField($model,'TglTrans'); ?>

</div>


<?php $this->endWidget(); ?>



  1. kemudian dikembangkan untuk menerima detailnya



Kode Transaksi [_____________]

Tgl Transakasi [_____________]


Detil Transaksi

------------------------------------------------------------------

Kode Barang [______________] Quantity [________] [+]

------------------------------------------------------------------

1. Kode ABC                  10                  [x]

2. Kode BBB                  20                  [x]

3. Kode CCC                  30                  [x]

------------------------------------------------------------------



Form entri detil transaksi hanya 1 macam, saat kode dan quantity dimasukkan lalu ditekan tombol plus, maka data barang akan masuk sebagai baris pada tabel. Baris di tabel detil transaksi masing-masing dilengkapi tombol silang, jika diklik maka detil barang akan dihapus. Viewnya ketambahan:




...

    <?php echo $form->textField($model,'TglTrans'); ?>

</div>

<hr>

<div class="inline-row">

    <?php echo CHtml::activeLabelEx($modelDetail,'KdBarang'); ?>

    <?php echo CHtml::activeTextField($modelDetail,'KdBarang'); ?>

</div>

<div class="inline-row">

    <?php echo CHtml::activeLabelEx($modelDetail,'Jumlah'); ?>

    <?php echo CHtml::activeTextField($modelDetail,'Jumlah'); ?>

</div>

<div class="inline-row">

    <?php echo CHtml::button('+', array('id'=>'add-detail')); ?>

</div>

<table id="tabel-detail">

 <thead>

  <tr><td>Kode</td><td>Quantity</td></tr>

 </thead>

 <tbody>

 </tbody>

</table>

<?php $this->endWidget(); ?>

...

<?php Yii::app()->clientScript->registerScript('tambah-detail-transaksi', '

 var i = 0;


 $("#add-detail").click(function() {

  var kode = $("#txt-kode-barang").val();

  var jumlah = $("#txt-jumlah").val();


  var hiddenInput = "<input type=\"hidden\" name=\"TransDetail[" + i + "][KdBarang]\" value=\" + kode + \">";

  hiddenInput += "<input type=\"hidden\" name=\"TransDetail[" + i + "][Jumlah]\" value=\" + jumlah + \">";


  $("#tabel-detail > body").append("<tr><td>" + kode + "</td><td>" + jumlah + hiddenInput + "</td></tr>");

  i++;

 });

'); ?>



  1. untuk simpannya, terdiri dari 2 bagian, persiapan data yg mo disimpan di kontroller, lalu proses simpanya di model.

Jadi Kontrollernya kurang lebih begini:


$theader = new TransHeader;

$tHeader->attributes = $_POST['TransHeader'];


$listDetail = array();

foreach ($_POST['TransDetail'] as $index=>$detail) {

 $tdetail = new TransDetail;

 $tdetail->attributes = $detail;

 array_push($listDetail, $tdetail);

}


$theader->details = $listDetail;

if ($theader->saveAll()) {

  //berhasil

} else {

  //gagal simpan, perlu repopulate form, silahkan jadikan latihan

}

lalu model TransHeader perlu ditambahi method saveAll() untuk simpan seluruh data (header+detail), karena proses simpan TransHeader dan TransDetail kan atomic (harus berhasil semua atau gagal semua jika gagal salah satu).

contoh:




 public function saveAll() {

  $transact = $this->dbConnection->beginTransaction();

  $green = $this->save(); //simpan header


  if ($green) {

    foreach ($this->details as $tdetail) { //simpan detail satu persatu

      $tdetail->KdTrans = $this->KdTrans;

      $green = $green && $tdetail->save();

    }

  } 


  if ($green) {

    $transact->commit();

    return true;

  } else {

    $transact->rollback();

    return false;

  }

 }



ya kurang lebih begitu lah.

Catatan kode2 di atas hanya konsep, bukan untuk dijiplak mentah2, tolong pahami alurnya dulu, lalu kembangkan sesuai kebutuhan (tambahan datepicker untuk tanggal, try catch exception saat saveAll, autocomplete kode + nama barang, dsb).

Pak, maaf, mau tanya nih, pada proses ke dua, datanya di simpan ke temp table atau ke list of array object?

terima kasih sebelumnya.

Pada tahap kedua datanya masih ada di client, belum berangkat ke server.

Jika diklik tombol tambah -> maka datanya akan masuk ke tabel (untuk presentasi) sekaligus dibuatkan hidden field (untuk submit nanti setelah memilih semua).

Pak, maaf nih tanya lagi, gimana caranya mendeklarasikan si variabel modeldetail ? dan dimana lokasinya. maaf ya pak jika banyak bertanya.

Terima kasih pak.

gpp, pak. Gak-paham itu penyakit, obatnya bertanya :)

deklarasi dan load semua variabel yg ada view selalu melalui controllernya. Misalnya nama viewnya view/trans/master_detail.php, maka di controllernya ditambahin kode untuk inisialisasi variabel jika halaman dipanggil menggunakan GET, contoh modifikasi:




  $theader = new TransHeader;

  $tdetail = new TransDetail;


  if (Yii::app()->request->isPost()) {

  //bagian proses submit

    $tHeader->attributes = $_POST['TransHeader'];


    $listDetail = array();

    foreach ($_POST['TransDetail'] as $index=>$detail) {

     $tdetail = new TransDetail;

     $tdetail->attributes = $detail;

     array_push($listDetail, $tdetail);

    }

  //dst

  }


  $this->render('trans/master_detail', array(

    'model'=>$trans,

    'modeldetail'=>$transDetail,

  ));



Pak Daud,sebelumnya salam kenal dan senang sekali sy bisa mengenal bapak.

Pak, sy sudah terapkan konsepnya. Mau tanya, gimana konsep populate form sama error nya pak? karena

kalo error di header nya inputan di detailnya jadi hilang.

Terus gimana konsep untuk edit nya pak??

Makasih sebelumnya…