سلام
در site/index کدهای زیر رو نوشتم:
if(Yii::$app->request->queryParams){
$search = new ProductSearch();
$dataProvider = $search->search(Yii::$app->request->queryParams);
$models = $dataProvider->getModels();
return $this->render('index', compact('search','models'));
}
در لیوت کد زیر را نوشتم:
<?= $form->field($search,'searching')->textInput(['placeholder' => 'جستجوی محصول']); ?>
مدل جستجو بصورت زیر هست:
class ProductSearch extends Products
{
public $searching;
/**
* @inheritdoc
*/
public function rules()
{
return [
[['searching'], 'safe'],
];
}
/**
* @inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ActiveDataProvider
*/
public function search($params)
{
$query = Products::findAll(['confirmed'=>1]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->FilterWhere(['like', 'name', $this->searching]);
return $dataProvider;
}
}
موقع اجرا خطای Undefined variable: search را نشان میدهد.
لطفا راهنمایی کنید.
متشکرم.
از خطا عکس بگیرین بگذارین.
در قسمت navbar از لیوت، یه فرم دارم که میخوام برای جستجوی محصولات ازش استفاده کنم.
بنظرم کلاً راه رو اشتباه رفتین. نیاز به SearchQuery نبود اصلاً. ضمن اینکه کد این MyTools چیه؟ شما از اکتیوفرم دارین استفاده میکنین؟ متدهای load و... چطور دارن کار میکنن؟ یه جستجوی ساده رو بیش از حد پیچیده کردین. دقیقاً بگین چه کاری میخواین انجام بشه. این موارد رو مشخص کنید تا ببینم راه بهتری میشه برای رسیدن به هدفتون پیدا کنیم یا نه؟
1- مقصد فرم جستجو کجاست؟
2- چه پارامترهایی توی جستجو دخالت دارن؟
3- بعد از جستجو نتایج قراره توی کدوم View نمایش داده بشن؟
4- برای نمایش نتایج توی ویو میخواین چکار کنید؟ از ListView یا GridView استفاده میکنید یا خودتون میخواین دستی نمایش بدین؟
برا یادگیری روش کار SearchModel این روشو انتخاب کردم.
جواب سوالایی که پرسیدین:
1- مدل Products.
2- نام محصول مشابه با رشته وارد شده در input.
3- نتایج در ویوی index از کنترلر site نشون داده میشن.
4- میخوام بصورت دستی نشون داده بشن.
اگه جستجو در کنترلری غیر از کنترلر site انجام بشه، چطوری باید به site/index هدایتش کنیم؟ چون فرم جستجو روی لیوت هست و در همه کنترلرها قابل مشاهده.
نقل قول: اگه جستجو در کنترلری غیر از کنترلر site انجام بشه، چطوری باید به site/index هدایتش کنیم؟ چون فرم جستجو روی لیوت هست و در همه کنترلرها قابل مشاهده.
جواب: AJAX
اما درمورد سؤالتون:
controllers/SiteController.php :
public function actionIndex()
{
$model = new Products;
$model->scenario = 'search';
$models = null;
if($model->load(Yii::$app->request->post()) && $model->validate()) {
$models = Products::find()->where(['like', 'name', $model->name])->all();
}
return $this->render('index', compact('model', 'compact'));
}
views/site/index.php
<?php $form = ActiveForm::begin([
'id' => 'search-form',
'options' => ['class' => 'form-inline'],
'fieldConfig' => [
'template' => "<div class="col-sm-3">{input}</div>",
'labelOptions' => ['class' => 'col-sm-1 control-label'],
],
]); ?>
<div class="form-group">
<?= $form->field($model, 'username') ?>
<div class="col-sm-2"><?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?></div>
</div>
<?php ActiveForm::end(); ?>
<?php if($models) : ?>
<div class="alert alert-info">
<h3>Search Results:</h3>
<hr />
<p>
<?php foreach($models as $m) : ?>
<?= Html::a(Html::enocde($m->name), ['products/view', 'id' => $m->id], ['class' => 'btn btn-default']) ?>
<?php endforeach; ?>
</p>
</div>
<?php endif; ?>
پ.ن. تست نکردم توی ++Notepad نوشتم ولی باید کار کنه.
منظور از نوشتن این دو دستور چیه:
$model->scenario = 'search';
$models = null;
من نمیدونم چرا از scenario استفاده میکنیم. دلیلش چیه؟
خط اول داره میگه سناریوی مدل جستجو هست. توی rules میتونید با on یا except مشخص کنید که اون قواعد برای چه سناریوی خاصی اعمال بشن یا توی کدوم سناریوها نادیده گرفته بشن. مثلاً توی search میگین همه فیلدها safe هستن و لازم نیست برای مثال فیلد mobile هم پر بشه یا ولیدیشن خاصی مثل EmailValidator روی ایمیل اعمال بشه:
[['name', 'mobile', 'email', 'confirmed'], 'required', 'except' => 'search'],
[['id', 'name', 'mobile', 'email', 'confirmed'], 'safe', 'on' => 'search'],
خط دوم هم متغیر models$ رو با مقدار null تعریف میکنه تا این متغیر تعریف نشده باقی نمونه و بتونیم برای ویو ارسال کنیم و اونطرف چک کنیم ببینیم چیزی پیدا شده یا نه.
در لیوت main یک فرم بصورت زیر تعریف کردم:
<form class="navbar-form navbar-left" role="search">
<div id="bg-input-button">
<div class="form-group">
<input id="nav-input" name="search" type="text" class="form-control" placeholder="جستجوی محصول">
</div>
<button id="nav-button" type="button" class="btn btn-sm btn-warning" onclick="navbarForm('<?= Url::to(["site/search"]) ?>')">
<span class="glyphicon glyphicon-search"></span>
</button>
</div>
</form>
با استفاده از ajax به اکشن search دسترسی پیدا کردم و جستجو رو انجام دادم:
function navbarForm(url){
var str = $.trim($('#nav-input').val());
if(str.length > 0){
$.ajax({
url: url,
type: "post",
data: { name: str },
success: function(result){
if(result){
$('#product').html(result);
}
}
});
}
}
کد اکشن search:
public function actionSearch() {
if (Yii::$app->request->post()) {
$find = Yii::$app->request->post();
$models = Products::find()
->where(['like', 'name', $find['name']])
->orderBy('name')
->all();
}
//...
return $result;
}
}
خیلی ممنون.