[Yii Framework] Membuat CGridView Sort dan Filter dari Model yang Berelasi
February 14, 2012 60 Comments
Pada Yii Framework, mungkin bukan hal yang sulit untuk membuat sebuah tabel yang menampilkan data dari suatu tabel yang sudah dilengkapi fasilitas “sort” dan “search”. Yah, anda cukup menggunakan fasilitas generate code dari Gii dan itu akan langsung dibuat secara otomatis oleh gii. Bagaimana jika anda ingin membaut sebuah data yang diambil dari lebih dari 1 tabel kemudian menampilkannya dengan fasilitas “sort” dan “search” ?? Untuk kasus ini, kita harus bekerja lebih keras.. kita dapat melakukannya dengan menggunakan cdbcriteria yang sedikit kita manipulasi.. Mari kita bahas…
Misal saya ingin menampilkan data dari tabel “A” dan tabel “B”. Oh iya, perlu anda ketahui tutorial ini menampilkan data untuk tabel yang berelasi. Untuk itu, pastikan pada model tersebut sudah terdapat relasi antara tabel A dan tabel B, sehingga pada model akan ada code seperti berikut :
public function relations() { return array( 'namaRelasi' => array(self::BELONGS_TO, 'B', 'id_B'), ); }
Setelah itu, definisikan attribute-attribute yang ingin kita ambil dari tabel B pada model A
misal :
public $attribute1,$attribbute2;
Nah, sekarang kita buat sebuah fungsi untuk menampilkan semua data pada tabel A dan tabel B yang sudah disertai fungsi untuk memfilter saat “search” dan mengurutkan saat “sort” :
Buatlah sebuah fungsi seperti berikut :
public function search2() { $criteria=new CDbCriteria; $criteria->select=' t.id, t.attribute0, namarelasi.attribute1, namarelasi.attribute2'; $criteria->with=array('namarelasi'); $criteria->compare('id',$this->id); $criteria->compare('attribute0',$this->attribute0,true); $criteria->compare('namarelasi.attribute1',$this->attribute1,true); $criteria->compare('namarelasi.attribute2',$this->attribute2,true); return new CActiveDataProvider(get_class($this), array( 'criteria'=>$criteria, 'sort'=>array( 'attributes'=>array( 'attribute1'=>array( 'asc'=>'namarelasi.attribute1', 'desc'=>'namarelasi.attribute1 DESC', ), 'attribute2'=>array( 'asc'=>'namarelasi.attribute2', 'desc'=>'namarelasi.attribute2 DESC', ), '*', ), ), )); }
Penjelasan : Pada code di atas, pertama-tama kita mendefinisikan nama fungsi. Lalu kita definisikan attribute apa saja yang dapat kita tampilkan. Lalu kita definisikan tabel apa yang kita ambil, tetapi ingat kita mendefinisikan tabel apa yang akan kita ambil bukan dari nama tabel nya.. tetapi dari nama relasinya. Karena itu lah sebelumnya saya sudah mewajibkan untuk mendefinisikan relasi pada pada model yang akan di relasikan..
Setelah mendefinisikan relasi, barulah saya mendefiniskan attribute untuk melakukan filter, lalu definisikan juga attribute-attribute untuk mendefinisikan variabel yang akan di “sort”…
Nah, setelah itu jangan lupa definsikan pada function rules model tersebut seperti berikut :
public function rules() { return array( array('id, attribute0, attribute1, attribute2', 'safe', 'on'=>'search2'), ); }
Rules di atas dimaksudkan agar attribute yang di filter/sort pada CGRidView dapat tertangkap oleh action..
Setelah itu anda dapat menampilkan isi dari tabel anda dengan memanggil fungsi tersebut pada controller anda :
public function actionAdmin() { $model=new A('search2'); $model->unsetAttributes(); if(isset($_GET['A'])) $model->attributes=$_GET['A']; $this->render('admin',array( 'model'=>$model, )); }
Nah, kemudian pada CGridView jangan lupa arahkan data nya kepada nilai fungsi tsb :
$this->widget('zii.widgets.grid.CGridView', array( 'id'=>'user-grid', 'dataProvider'=>$model->search2(), 'filter'=>$model, 'columns'=>array( 'id', 'attribute0', 'attribute1', 'attribute2', ), ));
Selesai..
Selamat mencoba..
Semoga membantu.. 🙂
Teman2 Yii-ers mohon pencerahannya yach.. kasusnya seperti berikut :
saya punya 2 tabel
table pertama adalah Barang
* kode_barang (PK)
* status
* tanggal_masuk
table kedua adalah Kondisi
* kode_barang (PK)
* kondisi_barang (hanya diisi dengan BAGUS dan RUSAK)
Di tampilan Form ADMIN hanya akan tampil data field2 table pertama saja,
| kode_barang | status | tanggal_masuk |
tetapi dengan persyaratan/kondisi
* kondisi 1 : jika usernya LEVEL 1,data yang tampil adalah semua data barang dengan kondisi_barang (table kedua) BAGUS ataupun RUSAK.
* kondisi 2 : jika usernya LEVEL 2, data yang tampil adalah data barang dengan kondisi_barang (table kedua) BAGUS
* kondisi 3 : jika usernya LEVEL 3, data yang tampil adalah data barang dengan kondisi_barang (table kedua) RUSAK
Mohon teman2 Yii-ers beri masukan utk kasus saya diatas. Terima Kasih.
Satu lagi yang kelupaan. Dari kasus tersebut tidak hanya tampil di cGridView saja, tapi tetap ada ‘class’=>’CButtonColumn’, sehingga operasi CRUD (Create Read Update Delete), Search dan Filter bisa dilakukan dari form ADMIN tersebut. Saya sudah mencoba menggunakan CArrayDataProvider, tetapi belum berhasil membuat yang seperti CActiveDataProvider. Mohon bantuan Para Master Yii. Terima Kasih.
@ardy:
pertama-tama buatlah sebuah query dengan kondisi tersebut, misal:
if(level==1)
query = select k.kodebarang, from barang b, kondisi k where b.kodebarang=k.kodebarang;
else if(level==2)
query = select k.kodebarang, from barang b, kondisi k where b.kodebarang=k.kodebarang AND k.kondisibarang=”bagus”;
else if(level==2)
query = select k.kodebarang, from barang b, kondisi k where b.kodebarang=k.kodebarang AND k.kondisibarang=”rusak”;
setelah itu tinggal agan masukin ke query..
oh iya, yg di atas pake SQL, kalo mau pake criteria seperti contoh di atas, mending masukin langsung ke controller seperti berikut:
public function actionAdmin()
{
$model=new A(‘search2’);
$model->unsetAttributes();
if(level==2)
$model->kondisibarang=”BAGUS”;
else if(level==3)
$model->kondisibarang=”RUSAK”;
if(isset($_GET[‘A’]))
$model->attributes=$_GET[‘A’];
$this->render(‘admin’,array(
‘model’=>$model,
));
}
Msalah membuat tombol update dan delete nya, agan harus definisikan sendiri actionnya seperti berikut:
silahkan dipelajari link tsb gan..
Pak.. Oke banget.. Bisa saya mengerti jalurnya nih. Perlahan sudah mulai terbuka otaknya.. Hhahahaahaaa.. Thx u buanyakkkkkk..
okeh pak..
bang sabit saya minta bantuan,,, sya masih newbea bgt yii,, sya mau tanya klo kita bkin suatu kasus,, misal kyk turotial bang sabit yg register,,,,
nah ko bisa tau harus d edit anu lah ini lah,,nah saya bingung,, gmn sih cara mengetahuinya??,, ketika membuat kasus baru misal post,, nah file apa saja yg harus saya edit,, mhon pnjelasannya,, trimakasih
mksd ny gimana gan? saya belum nangkep mksd pertanyaannya..
jadi gini gan,,, klo kita mau membuat aplikasi memakai yii itu,,,apa saja yang harus kita edit setelah di generate,,
misal ada folder view,controller,models,, nah yang saya bingung itu,,, file apa saja yang harus di edit gan,,
saya blom ngerti konsep MVC,,,
mnta pencerahan gan
Permisi mau bertanya pak,
saya dapat error seperti ini :
Active record “Score” is trying to select an invalid column “user.nama”. Note, the column must exist in the table or be an expression with alias.
kira-kira kenapa ya pak ?
saya sudah mengikuti semua langkah dengan sama persis.
Terima kasih untuk balasannya.
itu artinya ada nama field/table/relation yang salah maas..
tapi dari pesan error maas, itu berrarti ada field yang ga ada yang mas definisiin disana..
Yang terjadi sebagai berikut mas :
$criteria=new CDbCriteria;
$criteria->select=’
t.id_user,
t.level,
t.score,
user.nama
‘;
$criteria->with=array(‘user’);
ini error, ketika saya ganti jadi begini :
$criteria=new CDbCriteria;
$criteria->select=’
t.id_user,
t.level,
t.score
‘;
$criteria->with=array(‘user’, array(‘select’=>’nama AS nama’));
error hilang, search terhadap table relasi bisa dilakukan, tapi value-nya yang keluar di table kosong.. ada clue mengenai masalah ini mas ?
kosong ga ada data atau gimana mas? relasi yang dibuat udah di pastikan benar atau belum? coba lakukan query join pada database nya langsung data nya ada ga hasilnya?
@boedz : saya bener ga tau kalau ada komentar agan disini. Agan pelajari aja ebook saya dulu gan, pahami konsepnya.. setelah itu kalo ada yang bingung tanya aja langsung..
Sori, masalahnya sudah ketemu,
Di bagian view saya tambahkan field value, dan semuanya berjalan normal.. terima kasih mas 😀
updated view :
array(
‘name’=>’nama’,
‘value’=>’$data->user->nama’,
),
masalah yang sama dengan agan brayen, relasinya sudah benar, tapi pas bagian
$criteria->select=’
t.id,
t.attribute0,
namarelasi.attribute1,
namarelasi.attribute2′;
ketemu error
Active record “A” is trying to select an invalid column “namarelasi.attribute1”. Note, the column must exist in the table or be an expression with alias.
mungkin itu salah karena di tabel A g ad kolom “namarelasi.attribute1”, gtw pastinya
terima kasih agan brayen ma agan sabit 😀
masalahnya sama persis gan,itu naro sintaksnya dimana ya?
okeh..
assalam, mas cara buat form search di yii yang bisa diakses langsung oleh pengunjung gimana mas? sudah sy utak atik kok malah tambah bingung
trus mau hilangkan tombol view,delete,update di CGridview juga gimana caranya mas, maklum masih newbi. trima kasih
coba search aja di blog ini tentang user level access.. agan pelajari dulu gimana cara ngasih hak akses untuk jenis2 user..
misalnya di tabel B ad field tgl_lahir, terus pada CGridView model A ingin ditampilkan umur yang didapat dari perhitungan tgl_lahir model B, itu gimana y gan???
ada gan query untuk ngdapetin umur berdasarkan tgl lahir.. coba di googling aja gan..
mau tnya nih,kondisinya saya punya 2 tabel
tabel profil dengan atribut nama,alamat
tabel barang dengan atribut barang beli, barang jual
nah kasusnya relasi one to many jadi misal nama adi alamat jakarta tapi barang beli:kopi,teh,gula barang jual:ikan,daging (1 profil punya banyak barang)
saya maunya di halaman admin cuma ada atribut nama, alamat biar ga ada redudansi baru pas di klik view kluar lg hlaman baru isinya atribut barang jual,barang beli punyanya profil yang di view tadi misal td search nama:adi,trus ketemutrus di klik view(gmbar kca pmbsar sblah knan hsil crud gii) bru kluar tabel crud gii lg yg isinya barang beli, barang jual punyanya profil dengan nama adi
mohon pencerahannya ya
kalo dari kasus itu ga perlu pake yg dari tutor saya gan. Kan di cgridview nya cuma nampilin identitas user aja. Setelah identitas user itu di klik, tinggal di panggil aja semua barang yang dia miliki select barang where id_orang=$idorangnya.
sintaks select barang where id_orang=$idorangnya tulisnya dimana?
punya link tutorial yg mirip sama kasus ini ga gan?
thanks ya sblumnya
coba cari aja di blog ini ada tutor utk 2 model 1 view.. itu kurang lebih kayak kasus ini..
Bang, mau tanya dong, saya koding di model, seperti ini:
================================================
public function getLate($tgl=”){
$sql = “select a.id,a.nip,a.tanggal,a.jam_masuk,a.jam_pulang,a.idshift,a.mesin_id ” .
“,c.nama,TIME_TO_SEC(TIMEDIFF(a.jam_masuk, b.jam_masuk)) as telat from absensi a LEFT JOIN karyawan c ON a.nip=c.nip ” .
” inner join shift b on a.idshift=b.id “;
if(!empty($tgl))
$sql = $sql .” WHERE TIME_TO_SEC(TIMEDIFF(a.jam_masuk, b.jam_masuk)) > 0 AND DATE(a.tanggal)=’$tgl'”;
else
$sql = $sql .” WHERE TIME_TO_SEC(TIMEDIFF(a.jam_masuk, b.jam_masuk)) > 0 AND DATE(a.tanggal)=DATE(NOW())”;
$rawData=Yii::app()->db->createCommand($sql)->queryAll();
$dataProvider=new CArrayDataProvider($rawData, array(
‘id’=>’telat’,
‘sort’=>array(
‘attributes’=>array(
‘id’, ‘nip’, ‘tanggal’,’jam_masuk’,’jam_pulang’,’idshift’,’mesin_id’,’nama’,
),
),
‘pagination’=>array(
‘pageSize’=>20,
),
));
return $dataProvider;
}
===============================================
Nah, ceritanya saya mau nanti datanya ituh bisa di advance search bang, gimana yah bang?? saya bikin file search baru di view, namanya _search4.php, nah ketika saya klik tombol search, dia g mau flter data di gridviewnya bang..
Mohon pencerahannya bang..
Trimss bang..
^^
kalo mau bisa dari fungsi itu di search, di fungsi nya di kasih aja parameter getLate($param1, param2, param3) dimana nanti parameter nya tinggal di sisipin di WHERE query nya..
mau tanya mas masalah saya sama kyk brayen,jd yg searchnya bisa tapi value yg keluar di tabel kosong, itu solusinya gmana ya biar tampil?saya kurang paham yg solusi dari brayen di atas,terima kasih mas
coba yg ini :
$criteria->select=’a
t.id,
t.attribute0,
namarelasi.attribute1,
namarelasi.attribute2′;
hapus aja dari code ny mas.
g bisa mas,
malah error pas nge search
ada solusi lain g mas untuk kasus yg kaya bryan?
tambahan prtanyaan mas, jd selain yg atribut yg valuenya ga tampil tp bsa di search itu, atribut yg jd pembanding antara tabel a dan tabel b malah tampil valuenya tapi ga bsa di search, tolong solusinya
error nya apa gan?
itu udah tampil valuenya semua tapi yg jd pembanding antar tabel,misal tabel a id_siswa dicocokin sama id_siswa di tabel b, nah yg id_siswa itu di halaman admin.php jd ga bisa di search,klo atribut yg lainnya bisa,knapa ya mas?erornya muncul window baru namanya localhost says: didalemnya pesan erornya byk
sory mas mslah yg di atas udah beres,tp ada msalah baru,jd klo misalnya pas di cocokin id_siswa antara 2 tabel itu klo ada cocok ga msalah,tp klo ga ada misal di tabel a ada id_siswa 101 tapi di tabel b ga ada,pas di halaman admin.php muncul pesan eror ‘Trying to get property of non-object’ itu solusinya gmana ya mas biar msalnya kondisi kyk gtu ga eror tp nampilin atributnya kosong aja/not set
itu di database nya harus dibuat dulu relasi nya mas. kalo udah ada, ntar dia di model juga di definisiin relasinya.. dengan gitu dia otomatis hanya akan nampilin yang cocok aja mas..
misalnya gmana mas buat relasinya di database sama di modelnya?
di kasih primary key dan foreign key gan. Kalo di model, bisa coba liat di function relations. Agan harus pelajari itu dulu gan klo mau lancar buat cgridview relasi.. soalnya disana intinya dia kerja gan..
itu saya pkenya relasi di model belong to karena tabel a ke tabel b relasinya banyak ke satu,klo saya kasih forign key di table a ga eror tp data yang id_siswanya ga ada di id_siswa table b ga tampil di admin.php,klo ga ada foreign key masalahnya jd kyk yg di atas,gmana ya solusinya biar tetep tampil tp atributnya kosong aja gtu,apa masalah di admin.phpnya?
mas ini udah saya coba datanya masuk,cuma masalah tampilanya aja yd di admin.php,saya kan manggil atribut yg di tabel lain pake yang array(‘name’=’nama’, ‘value’=’$data->namarelasi->nama’) nah masalahnya klo value dari nama kosong dia eror,mau saya klo kosong tampilin aja atribut namanya kosong,gmana ya mas? terima kasih mas
mas Sabit Huraira saya mau tanya gimana caranya membuat rule agar data yang ditampilkan cgridview sesuai data user yang login contohnya misalnya kita ingin tampilkan user 1 berasal dari jakarta maka data jakarta aja yang tampil.
trus tolong buat contohnya ya mas. biar lebih mudah dipelajari.
mas, saya udah coba tutorial di atas, problemnya data yang tampil hanya 3 row. Padahal saya sudah setting pagesizenya 10 di model. mohon bantuannya.
kemungkinan query nya ada yang salah mas..
mas bisa bantu saya tentang masalah query relasi tp dengan join, please mas sabit…
http://stackoverflow.com/questions/19421586/how-to-convert-my-query-to-cdbcriteria-with-and-condition, query agak aneh emg..
uda saya jawab mas.
Mas, sabit enaknya pake csqldataprovider apa CDbCriteria?? karena query saya ini to mas agak aneh. jadi saya tidak ingin membawa where setelah join. pengen bawa “and” saja setelah di join.
1.Jika menggunakan csqldataprovider, saya bingung filter dan sortnya.
2.jika menggunakan CDbCriteria, bisa filter bisa sort, tp convert ke CDbCriteria-nya yg agak menyusahkan ternyata.. tp kalo pengalaman mas Sabit. lbh oke pakai yg mana?? mksh mas
untuk query yang kompleks lebih baik gunakan csqldataprov, kalo yang sederhana pake yang biasa. Cdbdriteria mungkin karena agan belum terbiasa aja menggunakannya..
mas sabit maaf tanya, saya br belajar yii untuk membuat aplikasi pencatatan poin(untuk skripsi) gini mas, kalo mau buat query untuk menampilkan data poin yang lebih dari 30 gmana mas?saya jg binggung letak file nya dimana yang mau dibuat apa dikontroler saja?atau di model dan view juga mas?nuhun mas
mohon bantuannya ya mas,,
buat query nya di model, agan pake sql biasa misal “select * from point where total_point>30”
Maaf mas sabit, saya mau tanya, saya punya table
Karyawan
-id_karyawan
-kode_divisi
gaji
-id_gaji
-id_karyawan
-gaji
komudian saya pengen tampilan view/gaji/admin (cgridview) di gaji itu sesuai dengan kode_divisi. caranya bagaimana?
coba search di blog ini cara make cgridview dengan data yang berelasi..
gan,mohon koreksinya yaa,, punya saya error “Active record “Anggota” is trying to select an invalid column “kabupaten.kabupaten”. Note, the column must exist in the table or be an expression with alias.”
code nya disini gan
http://pastebin.com/AcyK68mf
ga ada field kabupaten.kabupaten di dalem tabel anggota. Definisiin dulu sebuah relation dengan nama kabupaten di fungsi relations gan.
Mas tannya, ini kan saya punya tabel pembayaran yang isinya ada kolom id_penempatan ngambil dari tabel penempatan. Nah di tabel penempatan ini ada nim.
Saya nyoba buat nampilin nim biar bisa di search juga di pembayaran/admin. Script diatas sudah saya coba tapi error “Active record “Pembayaran” is trying to select an invalid column “idPenempatan.nim”. Note, the column must exist in the table or be an expression with alias. ” ini kenapa ya mas?
Mantap gan…
sabitlabcode menjawab semua masalah-masalah saya di Yii Framework..
Nice gan.. lanjut terus gan buat tutorialnya 😀
kalau mau sorting nama secara abjad gimana ya
koding nya yg ini..
public function actionSelectprodi()
{
$criteria = new CDbCriteria(array(‘order’=>’row_id asc’));
$id_kota3 = $_POST[‘Tbsiswa’][‘id_kota’];
$list = Tbsekolah::model()->findAll(‘kode_kota = :id_kota’, array(‘:id_kota’=>$id_kota3),($criteria));
$list = CHtml::listData($list,’kode_sekolah’,’nama’=> SORT_ASC);
echo CHtml::tag(‘option’,array(‘value’=>”),’– Pilih sekolah –‘, true);
foreach($list as $value=>$asal_sekolah){
echo CHtml::tag(‘option’,array(‘value’=>$value),CHtml::encode($asal_sekolah), true);
}
}
gan cara untuk tetap nampilin nama barang walaupun stocknya uda 0 gimana ya???
mas kalo error kayak gini apa ya mas?
” include(nama.php): failed to open stream: No such file or directory “