yii2-ledap
the ledap encapsulation for php yii2 framework
Install
The preferred way to install this extension is through composer.
Either run:
composer require --prefer-dist ethercap/yii2-ledap "dev-master"
Or add to the require section of your composer.json
file:
"ethercap/yii2-ledap": "dev-master"
Usage
copy layout. you can edit the layout after copy.
cp vendor/ethercap/yii2-ledap/src/gii/layout.php xxx/views/layouts/main.php
Code generator
the use of code generator is similar to gii/crud, let's begin:
php yii gii/ledapCrud --controllerClass="\frontend\controllers\TestController" --modelClass="common\models\Test" --searchModelClass="\frontend\forms\TestSearch"
After run, you can access the page. the page will be follow:
xxController : yii2 Controller to process http request.
views/xx/*.php : the template file, which to rendering html.
views/xx/*.api : the api file, which to rendering api.
xx/web/xx/*.js : the js file of the view。it view be rendering in html with a hash.
the file structure as the following picture.

List View
the javascript has a dataProvider(Note. it's not the php DataProvider) which to control the page.
1.refresh on input
we can add an event on form-item to refresh on inputing. thus, when we input, the table will auto search and refresh.
<form-item :model="dp.searchModel" attr="name" @input="refresh('')"></form-item>
2. Some DataProvider api
// to get an DataProvider
this.dp = ledap.App.getWebDataProvider({
httpOptions:{
url:'/test/xxx',
params:'ddd',
}
// can be ignore. the key to removal duplicate models
primaryKey: 'id',
// can be ignore. to prevent a lot of http request, the min interval between two request
// 0 represent no interval
timeWait : 600,
});
// a dataprovider contains 4 sub object
// the search params of list page
console.log(this.dp.searchModel)
// the items show in list page
console.log(this.dp.models);
// the sort of list page
console.log(this.dp.sort);
// the pagination of list page
console.log(this.dp.pager);
//change any params and refresh
this.dp.searchModel.name = 'xxx';
this.dp.refresh();
// change params and refresh
this.dp.changeParams({name:"xxx"});
// changePage
this.dp.changePage(page)
this.dp.nextPage();
this.dp.prePage();
// we may want refresh as mobile
this.dp.refresh("header");
this.dp.refersh("footer");
// we may want sort table
this.dp.sort = "id, -name";
this.dp.refresh();
// we can also use function
this.dp.setSort("id,-name");
// we may want sort locally
this.dp.sortModels("name", asc=true);
// we can use isLoading to show loading status
this.dp.isLoading
// we can also use event to do something
this.dp.on(ledap.WebDataProvider.EVENT_BEFOREGETDATA, function(){
});
this.dp.on(ledap.WebDataProvider.EVENT_AFTERGETDATA, function(){
});
3. grid
grid is a ledap component, which render by columns and dataProvider.
columns : {
'id',
{
'attribute' : 'id',
'label' : 'ID',
//if use sort, we can click header to sort table
'userSort' : true,
},
{
'attribute' : 'name',
'value' : function() {
// vm refer to current vue component
// value,model, index, attribute and dataProvider can be use in the template
return '<a @click="vm.xxx(model)"></a>';
},
'format': 'html',
}
}
if you're not satisfied with the default content. you can change the grid content by Vue scoped slot. the component will transfer 4 args to scoped slot:
model. current model, refer to the row of grid.
column. current colomn, refer to the col of grid.
index. the index of dp.models. dp.model[index] = model
value. the result of the column calculate with the model.
<grid class="table" :data-provider="dp" :columns="columns">
<template v-slot:label="p">
<th class="xxx">{{p.value}}{{p.model}}{{p.index}}{{p.column}}</th>
</template>
<template v-slot:default="p">
<td class="xxx">{{p.value}}{{p.model}}{{p.index}}{{p.column}}</td>
</template>
</grid>
you can also use dataProvider without grid. like dataProvider with "list", or components all by self.
<input type="xxx" v-model="dp.searchModel.name" @input="dp.refresh('')" />
<div v-for="model in dp.models">
<div class="">{{model.id}}</div>
<div class="xxx">{{model.img}}</div>
</div>
<div class="pager">
<div>total:{{dp.pager.currentPage}}|{{dp.pager.totalCount}}</div>
<a @click="dp.prePage()">PrePage</a>
<a @click="dp.nextPage()">NextPage</a>
</div>
View&Update&Create
type is the switch of the page. it can be set to an item of ["view", "update", "create"].
1.model
the model corresponding to the yii2 Form Model. let's begin:
//generate a model
let model = ledap.App.getModel(data);
// change model's value
model.name = "xxx";
// get label of attribute
model.getAttributeLabel("name");
// get hint of attribute
model.getAttributeHint("name");
// get error of attribute
model.getErrors("name");
// get first error of attribute
model.getFirstError("name");
// get All error of a model
model.getErrors();
// validate the value of model.if not correct, return false.
// we can use getErrors to show the error
model.validate();
2.detail
detail is similar to grid. we can use columns to show a detail.the rule is same to the grid.
columns : {
'id',
{
'attribute' : 'id',
'label' : 'ID',
//if use sort, we can click header to sort table
'userSort' : true,
},
{
'attribute' : 'name',
'value' : function() {
// vm refer to current vue component
// value,model, index, attribute and dataProvider can be use in the template
return '<a @click="vm.xxx(model)"></a>';
},
'format': 'html',
}
}
like grid, we can also use scoped slot to change the default view.
3. form-item
when we want't to show form, the form-item is very import. the form-item contains 4 parts:
label
hint
input
error
we cant use like this:
<!--
normal input
validator: the event to validator,
default is blur.
tag: the tag, default is div
-->
<form-item :model="model" attr="name" :validator="['input', 'blur', 'focus']" :tag="div">
</form-item>
<!-- we can also use scoped slot to change the default view-->
<form-item :model="model" attr="name">
<template v-slot:label="p">
<label> {{p.model.getAttributeLabel(p.attr)}}{{p.model.isRequired(p.attr) ? '*' : ''}}</label>
</template>
<template v-slot="p">
<baseinput type="password" v-bind="p"></baseinput>
</template>
<template v-slot:error="p">
<p v-show="p.showError">{{p.showError}}</p>
</template>
</form-item>
<!-- some other input -->
<!--
groupinput need DictValidator. you should add a rule in model like this:
['name', \ethercap\common\validators\DictValidator::className(), [0 => 'xxx', 1=> 'xxx', ...]],
dropdown also need DictValidator.
ajax select you should follow next chapter
-->
<form-item :model="model" attr="name">
<template v-slot="p">
<groupinput v-bind="p"></groupinput>
</template>
</form-item>
<form-item :model="model" attr="name">
<template v-slot="p">
<dropdown v-bind="p"></dropdown>
</template>
</form-item>
Sometimes, we may want use Other's Vue Component. So I did an example in this package.
I use an vue2-datepickerr to show the code.
<?php
// or we can use register
// $this->registerJs("http://xxxx.js", ['depends' => '\ethercap\ledap\assets\VueAsset'])
\ethercap\ledap\assets\DatePickerAsset::register($this);
?>
<form-item :model="model" attr="time">
<template v-slot="p">
<date-picker v-model="p.model[p.attr]" :value-type="'format'"></date-picker>
</template>
</form-item>
we should register the Component in view.js
Vue.Comonpoent("date-picker", DatePicker.default);
Other
1.select2 & SearchAction
sometimes we want use a ajax suggestion like select2. the package offer you follows:
SearchAction: a php Action to process the request.
<?php
namespace frontend\controllers;
use Yii;
class xxController extends Controller
{
// ....
public function actions()
{
return [
'search' => [
'class' => \ethercap\ledap\actions\SearchAction::className(),
'processQuery' => function($model) {
$query = xxx::find()->select(['id', 'name as text'])->asArray();
if($model->id) {
return $query->where(['id' => $model->id]);
}
if($model->keyword){
$query->andWhere(['like', 'name', $model->keyword]);
}
return $query;
},
// you can ignore this config
$dataConfig => [
'id',
'text'
]
],
];
}
}
after all this config, we have an api "/xx/search" to search data from database.
select2 component: vue component to send http request.
<form-item :model="model" attr="search">
<template v-slot="p">
<select2 v-bind="p" :data-provider="dp"></select2>
</template>
</form-item>
{
data:{
dp: App.ledap.getWebDp({
httpOptions:{
"url" : '/xx/search'
}
});
}
}
2.upload & UploadAction
to be continued.
Tips
be aware of Vue.
do not use yii2 widget.
all component you use should register first. App.register(['xxx'], Vue);
you can use other component.
you can change the request by replace AppAsset.
Last updated
Was this helpful?