[Yii Framework] Membuat Entry Data Many to many dengan Tabel Dinamis

Sebelumnya sudah pernah ada paparan mengenai langkah-langkah membuat entry data one to many dengan tabel dinamis disini. Nah, sekarang muncul permasalah lain dimana kita perlu membuat entry data untuk tabel yang memiliki hubungan many to many relation. Okeh, sebelumnya saya akan memberikan contoh untuk tabel “Mahasiswa” dan tabel “Dosen”. Misal saya definisikan bahwa mahasiswa bisa memiliki banyak dosen yang mengajarinya, dan dosen juga bisa memiliki banyak mahasiswa yang diajarinya. Nah, sudah kita ketahui jika ada tabel yang memiliki hubungan many to many, maka kita perlu membuat sebuah tabel penghubung antara kedua tabel tersebut. Pada kasus ini saya akan membuat sebuah tabel penghubung bernama “JunctionTab” Berikut gambaran lengkap tabel nya:

CREATE TABLE IF NOT EXISTS `dosen` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dosen` varchar(50) NOT NULL,
  `jk` enum('laki-laki','perempuan') NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

CREATE TABLE IF NOT EXISTS `junctiontab` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dosenId` int(11) NOT NULL,
  `mahasiswaId` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `dosenId` (`dosenId`),
  KEY `mahasiswaId` (`mahasiswaId`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

CREATE TABLE IF NOT EXISTS `mahasiswa` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `mahasiswa` varchar(50) NOT NULL,
  `jk` enum('laki-laki','perempuan') NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;

ALTER TABLE `junctiontab`
  ADD CONSTRAINT `junctiontab_ibfk_2` FOREIGN KEY (`mahasiswaId`) REFERENCES `mahasiswa` (`id`),
  ADD CONSTRAINT `junctiontab_ibfk_1` FOREIGN KEY (`dosenId`) REFERENCES `dosen` (`id`);

 

Okeh, setelah anda membuat tabel-tabel tersebut di database anda, silahkan anda generate model dan CRUD nya dengan menggunakan GII. Pada pembahasan tentang “Entry Data One to many” saya sudah menerangkan bahwa saya disana menggunakan sebuah extension bernama JAppendo. Saya sarankan anda pelajari terlebih dahulu postingan saya sebelumnya agar anda dapat lebih memahaminya. Sekarang silahkan anda download JAppendo tersebut, kemudian pindahkan ke dalam “project/protected/extensions/”. Setelah itu pada folder “appendo/views” buatlah sebuah file .php bernama “dosen.php”, lalu masukkan code berikut ke dalam file tersebut:

<table class="appendo-gii" id="<?php echo $id ?>">
	<thead>
		<tr>
			<th>Nama </th>
		</tr>
	</thead>
	<tbody>
    <?php if ($model->mahasiswaId == null): ?>
		<tr>
            <td>
            <?php echo CHtml::dropDownList('mahasiswaId[]',"string",
                Chtml::listData(Mahasiswa::model()->findAll(),'id','mahasiswa'),
                array('style'=>'width:200px'));
            ?>
            </td>
		</tr>
    <?php else: ?>
        <?php for($i = 0; $i < sizeof($model->mahasiswaId); ++$i): ?>
    		<tr>
                <td>
                <?php echo CHtml::dropDownList('mahasiswaId[]',$model->enum_type[$i],    
                	Chtml::listData(Mahasiswa::model()->findAll(),'id','mahasiswa'),
                	array('style'=>'width:200px'));
                ?>
                </td>
            </tr>
        <?php endfor; ?>
		<tr>
            <td>
            <?php echo CHtml::dropDownList('mahasiswaId[]',"string",
                Chtml::listData(Mahasiswa::model()->findAll(),'id','mahasiswa'),
                array('style'=>'width:200px'));
            ?>
            </td>
		</tr>
    <?php endif; ?>
	</tbody>
</table>

Penjelasan : code tersebut digunakan untuk melakukan perulangan agar kita bisa melakukan entry data dengan kondisi misal “ENTRY SEMUA MAHASISWA YANG DIBIMBING OLEH DOSEN A”.

Setelah itu, di dalam folder yang sama silahkan anda buat lagi sebuah file .php dengan nama “mahasiswa.php”. Lalu isi code berikut:

<table class="appendo-gii" id="<?php echo $id ?>">
	<thead>
		<tr>
			<th>Nama </th>
		</tr>
	</thead>
	<tbody>
    <?php if ($model->dosenId == null): ?>
		<tr>
            <td>
            <?php echo CHtml::dropDownList('dosenId[]',"string",
                Chtml::listData(Dosen::model()->findAll(),'id','dosen'),
                array('style'=>'width:200px'));
            ?>
            </td>
		</tr>
    <?php else: ?>
        <?php for($i = 0; $i < sizeof($model->dosenId); ++$i): ?>
    		<tr>
                <td>
                <?php echo CHtml::dropDownList('dosenId[]',$model->enum_type[$i],    
                	Chtml::listData(Dosen::model()->findAll(),'id','dosen'),
                	array('style'=>'width:200px'));
                ?>
                </td>
            </tr>
        <?php endfor; ?>
		<tr>
            <td>
            <?php echo CHtml::dropDownList('dosenId[]',"string",
                Chtml::listData(Dosen::model()->findAll(),'id','dosen'),
                array('style'=>'width:200px'));
            ?>
            </td>
		</tr>
    <?php endif; ?>
	</tbody>
</table>

Penjelasan : Sama seperti code sebelumnya. Hanya saja code di atas digunakan untuk melakukan perulangan. Misal untuk melakukan entry data dengan kondisi “ENTRY SEMUA NAMA DOSEN YANG MENGAJARI MAHASISWA A”.

Setelah selesai melaksanakan instruksi di atas, kini silahkan menuju “protected/controllers/junctiontabcontroller”. Lalu buatlah sebuah function baru bernama “actionDosen”, lalu masukkan code seperti berikut:

	public function actionDosen()
	{		
		$model=new JunctionTab;

		if(isset($_POST['dosen']))
		{
			$total = count($_POST['mahasiswaId']);
		    for ($i = 0; $i <= $total; $i++)
		    {
		    	if(isset($_POST['mahasiswaId'][$i]))
		    	{
		     		$jiakakak = new JunctionTab;
		     		$jiakakak->dosenId =$_POST['dosen'];
		        	$jiakakak->mahasiswaId = $_POST['mahasiswaId'][$i];
		         	$jiakakak->save();
		    	}
		    }
			$this->redirect(array('admin'));
		}

		$this->render('dosenn',array(
			'model'=>$model,
		));
	}

Penjelasan : fungsi di atas berguna untuk menjalankan proses yang akan di jalankan untuk melakukan entry data dan penyimpanan pada kondisi “ENTRY DATA NAMA MAHASISWA YANG DIAJARI OLEH DOSEN ?”.

Setelah itu buat juga fungsi untuk mengentry dengan kondisi “ENTRY DATA NAMA DOSEN YANG MENGAJARI MAHASISWA ?”. Masukkan code berikut di dalam controller:

	
	public function actionMahasiswa()
	{		
		$model=new JunctionTab;

		if(isset($_POST['mahasiswa']))
		{
			$total = count($_POST['dosenId']);
		    for ($i = 0; $i <= $total; $i++)
		    {
		    	if(isset($_POST['dosenId'][$i]))
		    	{
		     		$jiakakak = new JunctionTab;
		     		$jiakakak->dosenId =$_POST['dosenId'][$i];
		        	$jiakakak->mahasiswaId = $_POST['mahasiswa'];
		         	$jiakakak->save();
		    	}
		    }
			$this->redirect(array('admin'));
		}

		$this->render('mahasiswan',array(
			'model'=>$model,
		));
	}

Okeh, selesai sudah kita bermain-main dengan controller. Sekarang silahkan menuju folder “protected/views/junctiontab”. Lalu buat sebuah file .php dengan nama “dosenn.php” dan “mahasiswan.php”. Setelah itu pada dosenn.php, masukkan code berikut:

<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'junction-tab-form',
	'enableAjaxValidation'=>false,
)); ?>



	<div class="row">
		<?php echo 'Nama Dosen :'; ?>
        <?php echo CHtml::dropDownList('dosen',"string",
                Chtml::listData(Dosen::model()->findAll(),'id','dosen'),
                array('style'=>'width:200px'));
        ?>
	</div>

	
	<div class="row">
	    <?php $this->widget('application.extensions.appendo.JAppendo',array(
        	'id' => 'repeateEnum',
        	'model' => $model,
        	'viewName' => 'dosen',
        	'labelDel' => 'Remove Row',
    	)); ?>
    </div>

	<div class="row buttons">
		<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
	</div>

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

</div>

Penjelasan : code di atas adalah tampilan yang akan muncul jika kita memilih menu actionDosen.

Setelah itu pada mahasiswan.php sendiri, masukkan code berikut:

<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'junction-tab-form',
	'enableAjaxValidation'=>false,
)); ?>



	<div class="row">
		<?php echo 'Nama Mahasiswa :'; ?>
        <?php echo CHtml::dropDownList('mahasiswa',"string",
                Chtml::listData(Mahasiswa::model()->findAll(),'id','mahasiswa'),
                array('style'=>'width:200px'));
        ?>
	</div>

	
	<div class="row">
	    <?php $this->widget('application.extensions.appendo.JAppendo',array(
        	'id' => 'repeateEnum',
        	'model' => $model,
        	'viewName' => 'mahasiswa',
        	'labelDel' => 'Remove Row',
    	)); ?>
    </div>

	<div class="row buttons">
		<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
	</div>

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

</div>

Okeh, selesai sudah coding nya.. Jika code yang anda buat sudah benar, maka anda akan mendapati tampilan seperti ini jika memasukkan link http://localhost/mtom/index.php?r=junctiontab/dosen:

Lalu jika anda memanggil URL berikut http://localhost/mtom/index.php?r=junctiontab/mahasiswa, akan terlihat tampilan entri seperti berikut:

Nah, untuk menmpilkan hasil entry tabel nya, kita buat agar tampilannya lebih menarik. Maka masuk ke halaman “protected/views/junctiontab/admin.php” lalu edit komponen CGridView yang sebelumnya seperti ini:

<?php $this->widget('zii.widgets.grid.CGridView', array(
	'id'=>'junction-tab-grid',
	'dataProvider'=>$model->search(),
	'filter'=>$model,
	'columns'=>array(
		'id',
		'dosenId',
		'mahasiswaId',
		array(
			'class'=>'CButtonColumn',
		),
	),
)); ?>

Menjadi seperti berikut:

<?php $this->widget('zii.widgets.grid.CGridView', array(
	'id'=>'junction-tab-grid',
	'dataProvider'=>$model->search(),
	//'filter'=>$model,
	'columns'=>array(
		'id',
		array(
			'name'=>'Nama Dosen',
			'type'=>'raw',
			'value'=>'Dosen::model()->findByPk($data->dosenId)->dosen',
		),
		array(
			'name'=>'Nama Mahasiswa',
			'type'=>'raw',
			'value'=>'Mahasiswa::model()->findByPk($data->mahasiswaId)->mahasiswa',
		),
		array(
			'class'=>'CButtonColumn',
		),
	),
)); ?>

Sehingga tampilan halaman adminnya akan menjadi seperti berikut:

Yah, selesai…

Selamat mencoba…

Semoga membantu..😀

28 Responses to [Yii Framework] Membuat Entry Data Many to many dengan Tabel Dinamis

  1. Steven says:

    gan pny referensi dropdownlist dengan menggunakan kondisi.
    misal: tabel a dan tabel b. saya mau nampilkan dropdownlist dr tabel a berdasarkan kondisi tertentu. jd ntar di dropdownlist nya yg tampil berdasarkan kondisi.

  2. sabitzhabit says:

    kan kalo biasanya di dropdownlist ada “Chtml::listdata(Mahasiswa::model()->findAll())”
    nah, kalo agan mau kasih kondisi misal cuma mau nampilin mahasiswa yang punya jenis kelamin laki-laki, jadi buat ny kek gini:
    “Chtml::lisdata(Mahasiswa::model()->findByAttributes(array(“jeniskelamin”=>”laki-laki”))”

  3. Steven says:

    oh gt gan sip ^^
    tq ya

  4. Abdul Aziz says:

    gan ane udah coba semua ..
    tapi pas ane masuk ke link’a kok masuknya ke home ane ya ??

    ane masuk ke link http://localhost/bppn/index.php?r=junctiontab/dosen:,

    tapi yang muncul tampilan home ane ..

    alias sama aja seperti ane masuk ke http://localhost/bppn/index.php

  5. sabitzhabit says:

    cuma tampilanny aja apa link ny emang bener2 redirect ke halaman index gan?

  6. Fin says:

    gan, gimana cara manggil method yg ada parameternya ke dalam cgridview, sy udah coba nih gan.. tanpa param
    // controller
    public function nameMethod(){
    return “test here”;
    }
    // view/ctrl_id/admin
    array(
    ‘header’=>’name test’,
    ‘value’=>array($this,’nameMethod’),
    ),
    klo spti diatas ini bisa gan, tp klo ditambah param kye gini:
    public function nameMethod($name){
    return “test here ” . $name;
    }
    nah.. gimana cara manggilnya nih gan?, sy mau coba nampilin alamat lengkap manggil dari model laen berdasarkan id si employee, yah seperti many to many..

  7. coba :
    array(
    ‘header’=>’name test’,
    ‘value’=>’Namamodel->model()->nameMethod($this->name)’,
    ),

    gan..

  8. Fin says:

    masih ga bisa ga, Trying to get property of non-object,
    kira2 gimana gan ya? ato bisa kasi ide gimana nampilin data di cgridview dengan relasi many to many, misalkan ada bnyk document di distribusikan ke banyak departemen

    makasih sblmnya y gan..

  9. saya biasa nya tampilin dokument yang banyak itu dalam bentuk link2 aja gan..
    saya buat fungsi dulu kayak punya mbak itu yang akan mengembalikan list daftar dokumennya..

  10. Fin says:

    ok gan, sy coba lg makasih udah y gan..

  11. sarah says:

    Makasih banyak ka, artikel ini yang saya cari.
    Tapi mau tanya ka untuk bagian yang ini
    ‘value’=>’Dosen::model()->findByPk($data->dosenId)->dosen’,
    itu kan cuma relasi antar 2 tabel ya: junction dan tabel dosen, kl saya mau ambil nilai dari relasi 3 tabel, misalnya ada:
    tabel junction, tabel dosen dan tabel biodata dosen
    jadi nama dosen adanya di tabel biodata dosen, gmn ya ka?
    terima kasih ka

  12. berrti harus di tambahin lagi pake findByPk nya dari masing-masing tabel secara bertahap.
    Kalo mbak udah ngerti tentang relation di active record yii, ada caara lebih muda.. coba pelajari aja dulu tapi..

  13. ita says:

    saya sudah buat sesuai code diatas dengan menggunakan model role dan pk role_Id, namun keluar error pada bagian Chtml::listData(role::model()->findAll(),’role_id’,’role’),

    errornya :
    CException

    Property “Role.role_id” is not defined.

    ada yang bisa membantu? Thanks

  14. artinya field “role_id” ga ada di tabel/model role..

  15. repeat says:

    halo mas, saya mau bertanya donk. saya buat form pada file di “protected\views\junctiontab\dosenn” seperti ini :

    labelEx($model,’Company Name’); ?>
    textField($model,’company_name’,array(‘size’=>40,’maxlength’=>50)); ?>
    error($model,’company_name’); ?>

    tetapi selalu error “Property “Junctiontab.company_name” is not defined. “, maksudnya saya inigin membuat form penginputan file di “protected\views\junctiontab\dosenn” agar biar bisa di save di table dosen (biodata dosen) sama table junctiontab (id dosen, n id mahasiswa). tolong bantuan y mas.. terima kasih. reply tolong

  16. itu kata nya di tabel junctiontab ga ada field company_name mas..

  17. repeat says:

    iia saya mengerti mas, jadi company_name itu ngambil dari table lain mas… itu gmn cara y mas…?? kira2 bisa ga y???

  18. textField($model,’company_name’,array(‘size’=>40,’maxlength’=>50)); ?> itu $model kan definisi model junctiontab, jadi kamu pake variabel yang definisiin variabel model ssuai tabel company_name..

  19. repeat says:

    ooo… permasalahan y itu di $model y mas…??? tp kalo seandainya variabel yg ada di table company_name sama kaya junctiontabl ($model) itu gmn??

  20. repeat says:

    jadi gini mas…. ada table profile (company_name, address, number, email, dll). nah field yang ada di table profile ini saya pngn panggil di dalam codingan junctiontab. inti dari pertanyaan saya c seperti itu..? kira2 itu bisa gak y..? klo bisa itu bagaimana..??

  21. bisa mbak.. tapi di tmpilannya tetep di definisikan pake model si profile mbak..

  22. Gazali says:

    Mas Sabit, bisa dibuatin tutorial header detail nggak. Masih nggak ngeh saya, udah terbiasa konsep header detail didesktop, dimasukkin ke yii kok jadi susah ya? Apa harus pake trik sendiri ya?
    Thx ya mas, maaf klu mengganggu.

    • header detail gimana mksd nya gan?

      • Gazali says:

        Mungkin umum dikenal one to many kali ya.
        Seperti POS , Pembeli A membeli barang B1, B2, B3
        Kalau di desktop, biasanya kan masukkan data pembeli, ke save di db,
        Baru lanjut ke itemnya.
        Saya masih kesulitan menerapkannya di yii, maksudnya begitu mas Sabit.
        Thx ya….

      • oh, sebenarnya sama aja konsep nya dengan di desktop kok mas. Hanya di desktop emang ga terlalu sulit buat seperti itu ada form seperti tabel yang bisa kita input semau kita berapa jumlahnya. Sedangkan di web kita harus akali terlebih dahulu cara membuat tabel tersebut dengan javascript mas..

        atau ada kesulitan lain?

  23. Mohon Pencerahan

    Form yang saya buat kurang lebih sama, tapi tidak menggunakan JAppendo.
    Looping dilakukan menggunakan FOR looping untuk menghasilkan data array.

    Namun terjadi error saat melakukan simpan/ActionCreate bawaan Crud GII.

    Mohon pencerahannya untuk menyimpan data array menggunakan model yang ada.

    Salam.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: