I'm using DepDrop for dependency Dropdownlist. for this, I've written follow codes:
in view form:
use kartik\depdrop\DepDrop;
$catList = ['1' => 1, '2' => 2];
echo $form->field($model, 'cat')->dropDownList($catList, ['id' => 'cat-id']);
// Child # 1
echo $form->field($model, 'subcat')->widget(DepDrop::classname(), [
'options' => ['id' => 'subcat-id'],
'pluginOptions' => [
'depends' => ['cat-id'],
'placeholder' => 'Select...',
'url' => \yii\helpers\Url::to(['/faculty/list']),
],
]);
Controller:
public function actionList()
{
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$cat_id = $parents[0];
$out = [
['id' => '<sub-cat-id-1>', 'name' => '<sub-cat-name1>'],
['id' => '<sub-cat_id_2>', 'name' => '<sub-cat-name2>'],
];
echo Json::encode(['output' => $out, 'selected' => '']);
return;
}
}
echo Json::encode(['output' => '', 'selected' => '']);
}
but it doesn't work. I found out that actionList is't called by include follow code at the first of actionList function.
file_put_contents("c:/testtest.txt", implode(',',$_POST));
and this is head of request:
Request URL: http://admin.same.ir/index.php?r=faculty/list
Request Method: POST
Status Code: 400 Bad Request
Remote Address: 127.0.0.1:80
Referrer Policy: no-referrer-when-downgrade
I don't know what is the problem!!
it was just for CSRF:
I added follow code to controller:
public $enableCsrfValidation = false;
Related
So I've got an issue with element-api in php, which is a plugin for CRAFT cms, could someone help - what am I doing wrong here? I can't print time.json - always getting :
{"error":{"code":0,"message":"Class name must be a valid object or a
string"}}
here's the code:
<?php
use Craft;
use craft\elements\Entry;
use craft\controllers\TemplatesController;
use League\Fractal\TransformerAbstract;
use craft\web\View;
use craft\elements\User;
return [
'endpoints' => [
'tooltip-modal.json' => function() {
$affiliateId = Craft::$app->request->getParam('entryId');
$siteLanguage = Craft::$app->request->getParam('siteLanguage');
$data = [
'elementType' => Entry::class,
'paginate' => false,
'transformer' => function(Entry $affiliate) {
$view = Craft::$app->getView();
// $view->setTemplateMode($view::TEMPLATE_MODE_SITE);
return [
'affiliate' => $view->renderTemplate('modals/tooltipAffModal.twig', ['affiliate' => $affiliate])
];
},
'criteria' => ['id' => $affiliateId, 'site' => $siteLanguage]
];
return $data;
},
'time.json' => function() {
// $userId = Craft::$app->request->request->getParam('userId');
$data = [
'elementType' => User::class,
'paginate' => false,
'transformer' => function(User $user) {
return [
'date' => $user->winHistory::find()->orderBy(['id' => SORT_DESC])->one()
];
},
// 'criteria' => ['id' => $affiliateId, 'site' => $siteLanguage]
];
return $data;
}
]
];
I am using Codeception and fixtures to test my API but it seems the fixtures are only available for the first test. Here is my tests:
class ActionCest extends BaseTestCase
{
public function _fixtures()
{
return [
'profiles' => [
'class' => UserFixture::className(),
// fixture data located in tests/_data/user.php
'dataFile' => codecept_data_dir() . 'user.php'
],
'actions' => [
'class' => ActionFixture::className(),
'dataFile' => codecept_data_dir() . 'action.php'
],
];
}
public function createAction(ApiTester $I)
{
$user = $I->grabFixture('profiles', 'user1');
$I->wantTo('Add action');
$I->haveHttpHeader('Authorization', 'Bearer '. $user['auth_key']);
$payload = [
'action_id' => 123,
'saved' => true,
'viewed' => false,
'complete' => false,
];
$I->sendPOST('/action/save', $payload);
$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
$I->seeResponseContainsJson($this->buildResponsePayload($payload));
}
public function getAction(ApiTester $I)
{
$user = $I->grabFixture('profiles', 'user1');
//$action = $I->grabFixture('actions', 'action1');
$I->wantTo('Retrieve action');
$I->haveHttpHeader('Authorization', 'Bearer '. $user['auth_key']);
$I->sendPOST('/action/get-by-id/1');//'. $action['action_id']);
$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
$I->seeResponseContainsJson($this->buildResponsePayload($payload));
}
}
In the example above, the first test will pass OK. However the second test will fail due the user not being authenticated. I assume that the user has been removed from the database after the first test.
How would I overcome this?
The answer was to replace the _fixtures() method with the following method:
public function _before(ApiTester $I)
{
$I->haveFixtures([
'users' => [
'class' => UserFixture::className(),
'dataFile' => codecept_data_dir() . 'user.php',
],
'actions' => [
'class' => UserActionFixture::className(),
'dataFile' => codecept_data_dir() . 'action.php',
],
]);
}
I am using krajee yii2 depdrop in my form. I follow the instruction and my data still not show on depdrop.
This is my _form.php code :
<?php echo $form->field($model, 'id_trayek')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Trayek::find()->all(), 'id_trayek', 'nama_trayek'),
'language' => 'en',
'theme' => Select2::THEME_KRAJEE,
'options' => ['id' => 'id_trayek', 'placeholder' => '-- Pilih Trayek --', 'class' => 'form-control'],
]); ?>
<?php
echo $form->field($model, 'no_bus')->widget(DepDrop::classname(), [
'type'=>DepDrop::TYPE_SELECT2,
'options' => ['id'=>'no_bus', 'class'=>'form-control'],
'pluginOptions'=>[
'depends'=>['id_trayek'],
'placeholder' => '-- Pilih Bus --',
'url' => Url::to(['/surat-jalan/bus'])
]
]);
?>
This is my controller for depdrop url :
public function actionBus() {
$out = [];
if (isset($_POST['depdrop_parents'])) {
$id_trayek = end($_POST['depdrop_parents']);
$jenis_bus = Trayek::find()->select('jenis_bus')->andWhere(['id_trayek'=>$id_trayek]);
$list = Bus::find()->andWhere(['jenis_bus'=>$jenis_bus])->asArray()->all();
$selected = null;
if ($id_trayek != null && count($list) > 0) {
$selected = '';
foreach ($list as $i => $bus) {
$out[] = ['no_bus' => $bus['no_bus'], 'no_bus' => $bus['no_bus']];
}
echo Json::encode(['output' => $out, 'selected'=>$selected]);
return;
}
}
echo Json::encode(['output' => '', 'selected'=>'']);
}
in console, I found JSON response is OK and error : TypeError: id is undefined on file dependendent-dropdown.js (line 39, col 49)
Error from console
This line is not correct:
$out[] = ['no_bus' => $bus['no_bus'], 'no_bus' => $bus['no_bus']];
Dependent dropdown requires the first array element to be id and the second one to be name. Change to this:
$out[] = ['id' => $bus['no_bus'], 'name' => $bus['no_bus']];
I am trying to implement the 2amigos SelectizeDropDownList widget in a form to add new values to a table directly within the dropdown.
I am using the model Book and the Model Author so basically want to be able to add a new author in the book form.
This is the book controller at the update function:
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['index']);
} else {
return $this->render('update', [
'model' => $model,
'categories' => BookCategory::find()->active()->all(),
'publishers' => Publisher::find()->all(),
'copirights' => Copiright::find()->all(),
'authors' => Author::find()->all(),
]);
}
}
This is the form:
<?=
$form->field($model, 'author_id')->widget(SelectizeDropDownList::className(), [
// calls an action that returns a JSON object with matched
// tags
'loadUrl' => ['author/list'],
'value' => $authors,
'items' => \yii\helpers\ArrayHelper::map(\common\models\author::find()->orderBy('name')->asArray()->all(), 'id', 'name'),
'options' => [
'class' => 'form-control',
'id' => 'id'
],
'clientOptions' => [
'valueField' => 'id',
'labelField' => 'name',
'searchField' => ['name'],
'autosearch' => ['on'],
'create' => true,
'maxItems' => 1,
],
])
?>
And this is the function author controller:
public function actionList($query) {
$models = Author::findAllByName($query);
$items = [];
foreach ($models as $model) {
$items[] = ['id' => $model->id, 'name' => $model->name];
}
Yii::$app->response->format = \Yii::$app->response->format = 'json';
return $items;
}
The form works fine to load, filter, search and add new items.
But it is not inserting the new typed attribute in the author table.
Do I need to add something in the book controller?
How can I check if it is a new value or a change of an existing author?
Thanks a lot
I made it work with the following code, not sure the most elegant because i am checking the if the author_id is a number or a string.
In my case the author won't be a number anyway.
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$x = Yii::$app->request->post('Book');
$new_author = $x['author_id'];
if (!is_numeric($new_author)) {
$author = new Author();
$author->name = $new_author;
$author->save();
$model->author_id = $author->id;
}
if ($model->save()) {
return $this->redirect(['index']);
}
} else {
return $this->render('update', [
'model' => $model,
'categories' => BookCategory::find()->active()->all(),
'publishers' => Publisher::find()->all(),
'copirights' => Copiright::find()->all(),
'authors' => Author::find()->all(),
]);
}
}
I use select2 ajax loading. I get the code from this link: http://demos.krajee.com/widget-details/select2. When I enter words into field, it display all data/value, but it can't automatic select data/value according to words that I enter into field. So, my select2 always select the first data/value and display all value. What's the problem? These are the codes:
_form.php
$url = Url::to(['/paket/jsonlist']);
$cityDesc = empty($model->no_induk) ? '' : Penerima::findOne($model->no_induk)->nama;
echo $form->field($model, 'no_induk')->widget(Select2::classname(), [
'initValueText' => $cityDesc, // set the initial display text
'options' => ['placeholder' => 'Search for a city ...'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'language' => [
'errorLoading' => new JsExpression("function () { return 'Waiting for results...'; }"),
],
'ajax' => [
'url' => $url,
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(no_induk) { return no_induk.text; }'),
'templateSelection' => new JsExpression('function (no_induk) { return no_induk.id; }'),
],
]);
my controller:
public function actionJsonlist($q = NULL, $id = NULL)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']];
if(!is_null($q))
{
$query = new \yii\db\Query;
$mainQuery = $query->select('no_induk AS id, nama AS text')
->from('penerima')
->limit(20);
$command = $mainQuery->createCommand();
$data = $command->queryAll();
$out['results'] = array_values($data);
}
elseif ($id > NULL)
{
$out['results'] = ['id' => $id, 'text' => \frontend\models\Penerima::find($id)->nama];
}
return $out;
}
Could be you use the attribute name and not the vars
echo $form->field($model, 'no_induk')->widget(Select2::classname(), [
'initValueText' =>'cityDesc', // set the initial display text
or
echo $form->field($model, 'no_induk')->widget(Select2::classname(), [
'initValueText' =>$model->cityDesc, // set the initial display text