Yajra DataTable search bar is not working - laravel-5.4

I have used Left Join Query in file called "directoryDataTable.php. Now the problem is that Yajra DataTable search bar is not working. Its neither giving any error nor the search result.
My DataTable query function is al follows.
public function query()
{
$id = \Illuminate\Support\Facades\Auth::user()->id;
$directories = DB::table('directories')
->leftjoin('claimed', 'directories.id', '=','claimed.dir_id')
->select('directories.*')
->where('directories.user_id',$id)
->where('paymentStatus','1')
->whereNull('directories.deleted_at')
->orWhere('claimed.claimed_by',$id);
return $this->applyScopes($directories);
}
Please Help

Changed the query to,
public function query()
{
$id = \Illuminate\Support\Facades\Auth::user()->id;
$directories = DB::table('directories')
->leftjoin('claimed', 'directories.id', '=','claimed.dir_id')
->select('directories.*')
->where(function ($query) {
$query->where('directories.user_id',\Illuminate\Support\Facades\Auth::user()->id)
->orWhere('claimed.claimed_by',\Illuminate\Support\Facades\Auth::user()->id);
})
->where('paymentStatus','1')
->whereNull('directories.deleted_at')
;
return $this->applyScopes($directories);
}
and in get columns function, replace ['name' => 'YourTableName.ColumnName','data' => 'YourColumnName'] Like this.
private function getColumns()
{
return [
'dir_name' => ['name' => 'directories.dir_name', 'data' => 'dir_name'],
'phone_number' => ['name' => 'directories.phone_number', 'data' => 'phone_number'],
'address' => ['name' => 'directories.address', 'data' => 'address'],
'features' => ['name' => 'directories.features', 'data' => 'features', ],
'Status' => ['name' => 'directories.Status', 'data' => 'Status','searchable'=>false ],
'Subscription' => ['name' => 'directories.Subscription', 'data' => 'Subscription','searchable'=>false ]
];
}

Related

loop logic for storing multi record in laravel?

public function store(Request $request)
{
$productId = $request->id;
$request->validate([
'name' => 'required',
'quantity' => 'required|integer|gt:0',
'fmcode',
'fmcodes',
'area',
'naoffm','glno'
]);
for ($i = 0; $i<=$request->GLNO; $i++){
$product = Product::updateOrCreate(
[
'id' => $productId
],
[
'id'=>$productId,
'name' => $request->name,
'quantity' => $request->quantity,
'fmcode' => $request->FMCODE,
'fmcodes' => $request->FMCODES,
'area' => $request->AREA,
'naoffm' => $request->NAOFFM,
'id'=>$request->GLNO[$i],
'glno'=>$request->GLNO[$i],
]
);
}
return Response()->json($product);
}
selected dropdown of glno values have to store multiple records with glno dropdownlist
and required loop logic to store request data so required solutions for this
You can do multiple insertions using Query Builder. Sample;
DB:table('table_name')->insert(
[
'id' => 1,
'name' => 'mkeremcansev'
],
[
'id' => 2,
'name' => 'John Doe'
]
);

Yii2- How to restrict a user from viewing others data in index page

I am working on yii2 in my project, I have users and their roles. Each role is given access to a Module and a Sub Menu. There is a sub-menu named SIM List in which all the SIM records can be viewed. There is a field named issued_to which tells us that which SIM has been issued to which user.
Unless a SIM is issued to any user, the issued_to field will remain empty. Once issued the name of the user will appear on the SIM List.
Now I want to manage it in such a way that only a specific user can see the list. For example 5 Sims have been issued to a user named U. Now the user U should only see that SIM records which are issued to him, otherwise the list should be empty.
In my Index controller I am getting issued_to field name which is empty by default.
public function actionIndex()
{
$searchModel = new SimsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
By doing like below I can get issued_to user id
$model = $dataProvider->getModels()[0];
$user_id = $model['issued_to'];
var_dump($user_id);
exit();
Now in this controller, I want to add a check of user_id which gives me only the records which are of that specific user.
Index View
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'id',
'imsi',
'sim_number',
'operator_name',
'data_details',
'sms_details',
'monthly_bill',
//'created_by',
[
'label' => 'Created By',
'value' => function ($data) {
if (is_object($data))
return $data->created->name;
return ' - ';
},
//'filter' => Html::activeDropDownList($searchModel, 'created_by', \app\models\User::toArrayList(), ['prompt' => "Created By", 'class' => 'form-control']),
],
'created_at',
// 'updated_at',
'status',
// 'updated_by',
//'sim_stauts',
[
'label'=>'SIM Status',
'value'=>function($a){
return $a->getStatusvalue();
}
],
//'issued_to',
[
'label' => 'Issued To',
'value' => function ($d) {
if(is_object($d->user))
//return $d->user->name;
return $d->issued_to == '' ? '' : $d->user->username;
return ' - ';
// return $d->user->name;
},
'filter' => Html::activeDropDownList($searchModel, 'issued_to', \app\models\User::toArrayList(), ['prompt' => "Users", 'class' => 'form-control']),
],
//'returned_by',
[
'label' => 'Returned By',
'value' => function ($d) {
if(is_object($d->user2))
//return $d->user->name;
return $d->returned_by == '' ? '' : $d->user->username;
return ' - ';
// return $d->user->name;
},
'filter' => Html::activeDropDownList($searchModel, 'returned_by', \app\models\User::toArrayList(), ['prompt' => "Users", 'class' => 'form-control']),
],
'historic',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
Update 1
My search model is below
public function search($params)
{
$query = Sims::find();
// add conditions that should always apply here
$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;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'created_by' => $this->created_by,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'updated_by' => $this->updated_by,
'sim_stauts' => $this->sim_stauts,
'issued_to' => $this->issued_to,
'returned_by' => $this->returned_by,
'historic' => $this->historic,
]);
$query->andFilterWhere(['like', 'imsi', $this->imsi])
->andFilterWhere(['like', 'sim_number', $this->sim_number])
->andFilterWhere(['like', 'operator_name', $this->operator_name])
->andFilterWhere(['like', 'data_details', $this->data_details])
->andFilterWhere(['like', 'sms_details', $this->sms_details])
->andFilterWhere(['like', 'monthly_bill', $this->monthly_bill])
->andFilterWhere(['like', 'status', $this->status]);
return $dataProvider;
}
How can I achieve it? Any help would be highly appreciated.
As per your description, you have the user_id saved inside the issued_to field and you need to only fetch the results that have the current logged in user_id saved in the field issued_to.
I assume that your search in the grid view is visible to only logged-in users.
You should set the issued_to param manually by first getting the queryParams array from the request object Yii::$app->request->queryParams; which has the array in the same format as the POST has i.e ['ModelName']['field_name'] so you need to infact set the issued_to as
$arrayParams['SimSearch']['issued_to']=Yii:$app->user->id;
Your actionIndex should look like below
public function actionIndex()
{
$searchModel = new SimsSearch();
$queryParams=Yii::$app->request->queryParams;
//check if user or one of the managers
$isAdmin=in_array(Yii::$app->user->identity->user_role,[1,6]);
//set params if normal user
if(!$isAdmin){
$queryParams['SimsSearch']['issued_to']=Yii::$app->user->id;
}
$dataProvider = $searchModel->search($queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Hope this helps you out.

Yii2: my new action is not found - 404

I am trying to call a custom action by ajax, but the response returned is 404, I am pretty sure its a routing issue, but I can't figure how to solve it.
here is my code:
action
public function actionGetOne($id){
$model = Driver::findOne($id);
if(!empty($model)){
$data = [];
$row = [
'id'=>$model->id,
'full_name'=>$model->full_name,
'email'=>$model->email,
'nationality_id'=>$model->nationality_id,
'current_location'=>$model->current_location,
'medical_check_id'=>$model->medical_check_id,
'img'=>$model->img,
'current_fleet_id'=>$model->current_fleet_id,
'availability'=>$model->availability
];
$data[] = $row;
echo json_encode(['driver-getOne'=>'success','data'=>$data]);
} else{
echo json_encode(['driver-getOne'=>'failure']);
}
}
ajax
$.ajax({
url:'<?= urldecode(Url::toRoute(['driver/get-one'])); ?>?id=<?= $id; ?>',
method:'post',
dataType:'json',
success:function(response){}
error:function(){
alert('target action is not found!');
}
}
backend/config/params.php
<?php
return [
'adminEmail' => 'admin#example.com',
'urlRules' => [
'' => 'site/index',
'login/' => 'site/login',
'signup/' => 'site/signup',
'<controller:[\w-]+>/<action:\w+>' => '<controller>/<action>',
'<controller:[\w-]+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:[\w-]+>/<id:\d+>' => '<controller>/view',
'<controller:[\w-]+>/create' => '<controller>/create',
'<controller:[\w-]+>/update/<id:\d+>' => '<controller>/update',
'<controller:[\w-]+>/delete/<id:\d+>' => '<controller>/delete',
'<controller:[\w-]+>/get-all' => '<controller>/get-all',
'<controller:[\w-]+>/get-one' => '<controller>/get-one',
'<controller:[\w-]+>/update-status' => '<controller>/update-status',
]
];
Change few things and try again.
Action:
public function actionGetOne($id)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$model = Driver::findOne($id);
if (empty($model)) {
return ['driver-getOne' => 'failure'];
}
return [
'driver-getOne' => 'success',
'data' => [[
'id' => $model->id,
'full_name' => $model->full_name,
'email' => $model->email,
'nationality_id' => $model->nationality_id,
'current_location' => $model->current_location,
'medical_check_id' => $model->medical_check_id,
'img' => $model->img,
'current_fleet_id' => $model->current_fleet_id,
'availability' => $model->availability
]],
];
}
Action should return something to properly finish response sequence otherwise unwanted things can happen. By setting response format you can get JSON encoded array automatically.
AJAX:
$.ajax({
url:'<?= Url::to(['driver/get-one', 'id' => $id]) ?>',
method:'post',
dataType:'json',
success:function(response){}
error:function(){
alert('target action is not found!');
}
}
Get your URL using proper syntax.
Params:
'urlRules' => [
'' => 'site/index',
'login' => 'site/login',
'signup' => 'site/signup',
'<controller:[\w-]+>/<id:\d+>' => '<controller>/view',
'<controller:[\w-]+>/<action:[\w-]+>/<id:\d+>' => '<controller>/<action>',
'<controller:[\w-]+>/<action:[\w-]+>' => '<controller>/<action>',
]
I'm assuming you are passing urlRules to components > urlManager > rules otherwise URL rules won't work.
I removed redundant rules. In general add general rules last and specific rules first.

yii2: get relation data in kartik editable widget

I am using kartik yii2 editable extension to edit inline in gridview.
The extension is working fine.
Please refer this screen-shot link [http://awesomescreenshot.com/00753dvb73][1]
In this screen-shot the source field is a dropdown and I want the value of source instead id its id
My View
use kartik\editable\Editable;
[
'attribute'=>'source',
'format'=>'raw',
'value'=> function($data){
//$s = $data->getBacklog_source();//var_dump($s);exit;
return Editable::widget([
'name'=>'source',
'model'=>$data,
'value'=>$data->source,
'header' => 'Source',
'type'=>'primary',
'size'=> 'sm',
'format' => Editable::FORMAT_BUTTON,
'inputType' => Editable::INPUT_DROPDOWN_LIST,
'data'=>$data->getSource(), // any list of values
'options' => ['class'=>'form-control', 'prompt'=>'Select Source'],
'editableValueOptions'=>['class'=>'text-danger'],
'afterInput' => Html::hiddenInput('id',$data->id),
]);
}
],
The relation I made is:
public function getSource()
{
$source = BacklogSource::find()->all();
return ArrayHelper::map($source, 'id', 'Source');
}
public function getBacklog_complexity()
{
return $this->hasOne(BacklogComplexity::className(), [
'id' => 'complexity'
]);
}
Thanks for help in advance
I got the solution something like this:
[
'attribute'=>'status',
'format'=>'raw',
'value'=> function($data){
$s = BacklogStatus::findOne($data->status);
return Editable::widget([
'name'=>'status',
'model'=>$data,
'value'=>$s->Status,
'header' => 'Status',
'type'=>'primary',
'size'=> 'sm',
'format' => Editable::FORMAT_BUTTON,
'inputType' => Editable::INPUT_DROPDOWN_LIST,
'data'=>$data->getStatus(), // any list of values
'options' => ['class'=>'form-control', 'prompt'=>'Select Source'],
'editableValueOptions'=>['class'=>'text-danger'],
'afterInput' => Html::hiddenInput('id',$data->id),
]);
}
],

How to connect 3 tables in yii2 and display in Gridview then make sorting work correctly

I have used the gii tool to create crud application. I have 3 tables the tbl_targetcities, lib_cities, and lib_provinces. I was able to connect lib_cities to tbl_targetciteis but not the lib_provinces. And also the sorting of city / Municipality does not work. It seems that it sorts according ti the ID.
tbl_target_cities
lib_cities
lib_provinces
sample View
So far here is my relation in the model.
public function getCityName()
{
return $this->hasOne(LibCities::className(),['city_code'=>'city_code']);
}
in my view file...
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'attribute'=>'city_code',
'value'=>'cityName.city_name'
],
[
'attribute'=>'prov code',
'value'=>'cityName.city_name'
],
'kc_classification',
'cluster',
'grouping',
'priority',
'launch_year',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
How to display the prov_name from lib_provinces???
EDIT to answer user2839376 question in the comment box
IN THE SEARCH MODEL CLASS
$query = TblSpBub::find();
$query->joinWith('brgyCode')->joinWith(['cityCode'])->joinWith(['cityCode.provCode']);
$covered= LibAreas::find()->where(['user_id'=>yii::$app->user->identity->id])->all();
$query->all();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort'=> ['defaultOrder' => ['id'=>SORT_DESC]],
]);
$dataProvider->sort->attributes['city'] = [
'asc' => ['lib_Cities.city_name' => SORT_ASC],
'desc' => ['lib_Cities.city_name' => SORT_DESC],
];
$dataProvider->sort->attributes['province'] = [
'asc' => ['lib_provinces.prov_name' => SORT_ASC],
'desc' => ['lib_provinces.prov_name' => SORT_DESC],
];
In LibCities model add new relation:
public function getProvince()
{
return $this->hasOne(LibProvince::className(),['prov_code'=>'prov_code']);
}
And change getCityName relation. You should add with() for relation:
public function getCityName()
{
return $this->hasOne(LibCities::className(),['city_code'=>'city_code'])->with(['province']);
}
And in view correct your columnto this:
[
'attribute'=>'prov code',
'value'=>'cityName.province.prov_name'
],
You have to use the function relations() in models.
In tbl_target_cities model:
public function relations()
{
return array(
'city' => array(self::HAS_ONE, 'LibCities', 'city_code'),
);
}
In LibCities model :
public function relations()
{
return array(
'province' => array(self::HAS_ONE, 'LibProvinces', 'prov_code'),
'targets' => array(self::HAS_MANY, 'TargetCity', 'city_code',
);
}
This will allowed you to jump throw the LibCities model,
now you can simply acces to prov name like this :
$model->city->province->prov name;
Note : You need to have the 3 models defined.
EDIT
array(
'name' => 'province name',
'value' => $data->city->province->prov_name;
),
Done it, Heres how.
in addition to the above code (original post)
// in Model I added an additional function
public function getTaskowner()
{
return $this->hasOne(Tasks::className(), ['id' => 'task_id'])
->with(
['location','taskowner']
);
}
and in view i did this
....
'columns' => [
....
[
'class' => 'kartik\grid\DataColumn',
'value'=> 'tasks.location.taskowner.name',
.....
],
.....
and it worked
key points. used an array with the 'with->(..)' to include both then in the view added 'tasks.location.taskowner.name', to join them all