0

I'm new to Yii2 and Web-Application-Programming at all. But I have to face the challange so I hope for little help here...

At the moment I'm working on an report-module where the user can base-configure his own report. Then in the view of the reports-grid there's an action-column with a "evaluate report"-button. I made it so far, that once the button is clicked the "evaluation"-view with the datagrid based on an array is rendered (modified the ReportModel and the ReportController).

But that is not the functionality I want: Once the button is clicked there should be first a form rendered (filter) where the user can set some further filter options. These options should be passed to the SQL-Statement after clicking a submit-button in the filter-form and the datagrid should be rendered on the same page below the filter-form. The filter-form should be editable at any time and the new datagrid should be re-rendered after clicking the submit-button.

What I need is an explanation of the professional method to implement such functionality (no code requiered)...it's more a guide like "how to" what I need. Please have in mind that I'm not a professional programmer, thanks a lot!

Chris vD
  • 73
  • 2
  • 12

3 Answers3

0

The basic idea is to reuse your form. As the user visits this page first, he accesses it by GET and you just render the empty filter form and show no data (or maybe the latest 10 records). By submitting the form, a POST request will be invoked that carries the form contents in its body. Since the submit is a new request to the webserver, you can evaluate the form values and use them twice: first, you use them to filter the data and secondly you pass the value over to your filter form again. The resulting page consists then of your form with the values you entered before and the resulting filtered data. The user can than continue using the form as it was before he submitted it.

I hope you get the idea... :)

  • I hope I understood the idea, thank you a lot! So I need to have something like a default query, which returns no value. When the POST values are submitted the "real" query would be generated and renders the result in the grid. But how do I access a page by GET or is this the normal access to a page? – Chris vD Feb 25 '15 at 22:33
  • Yes, GET is the default way. You could also skip rendering the grid view when you have no query,that might be a better strategy. – Brian Pfretzschner Feb 25 '15 at 22:36
0

Here's my Controller-code:

public function actionEvaluate($id)
 {
    $model = $this->findModel($id);
    $model->signalIds = $model->getSignalIds();
    $model->machineIds = $model->getMachineIds();
    $model->driverIds = $model->getDriverIds();
    $model->sqlarr = $model->getSqlArray();
    $model->columnarr = $model->getColumnNames();

    if ($model->load(Yii::$app->request->post())){
        $query = New Query;
        if ($model->object == 'VEHICLES'){
            $query  ->select($model->sqlarr)
                    ->from('trips')
                    ->where(['machine_id' => $model->machineIds])
                    ->groupBy('id_trip')
                    ->leftJoin('can_data', 'can_data.trip_id = id_trip')
                    ->rightJoin('machine', 'machine.id_machine = machine_id')
                    ->all();

        }else{
            $query  ->select(['trips.begin','trips.end','can_data.duration','can_data.distance'])
                    ->from('trips')
                    ->where(['driver_id' => $model->driverIds])
                    ->groupBy('machine_id')
                    ->leftJoin('can_data', 'can_data.trip_id = trips.id_trip')
                    ->all();
            $data = $query->createCommand()->queryAll();
        }

        $data = $query->createCommand()->queryAll();
        $dataProvider = new ArrayDataProvider([
                            'allModels'=>$data,]);
    }else{
        $dataProvider = new ArrayDataProvider([
                            'allModels'=>[],]);
    }
        return $this->render('evaluate', [
            'dataProvider' => $dataProvider,
            'model' => $model,]);
}

so a few more questions: at the moment I pass over and empty dataProvider if there's no post. The problem ist, when I push the Submit-Button nothing happens, but in my point of view at least the datagrid based on the query shold be rendered?

How could I realise a rendering of the grid only if theres a POST?

Chris vD
  • 73
  • 2
  • 12
0

How could I realise a rendering of the grid only if theres a POST?

Try this:

public function actionEvaluate($id)
{
    $model = $this->findModel($id);
    $model->signalIds = $model->getSignalIds();
    $model->machineIds = $model->getMachineIds();
    $model->driverIds = $model->getDriverIds();
    $model->sqlarr = $model->getSqlArray();
    $model->columnarr = $model->getColumnNames();

    if ($model->load(Yii::$app->request->post())){
        $query = New Query;
        if ($model->object == 'VEHICLES'){
            $query  ->select($model->sqlarr)
                    ->from('trips')
                    ->where(['machine_id' => $model->machineIds])
                    ->groupBy('id_trip')
                    ->leftJoin('can_data', 'can_data.trip_id = id_trip')
                    ->rightJoin('machine', 'machine.id_machine = machine_id')
                    ->all();

        }else{
            $query  ->select(['trips.begin','trips.end','can_data.duration','can_data.distance'])
                    ->from('trips')
                    ->where(['driver_id' => $model->driverIds])
                    ->groupBy('machine_id')
                    ->leftJoin('can_data', 'can_data.trip_id = trips.id_trip');
        }

        $dataProvider = new ActiveDataProvider(['query'=>$query]);
    }else{
        $dataProvider = null;
    }
        return $this->render('evaluate', [
            'dataProvider' => $dataProvider,
            'model' => $model,]);
}

The $dataprovider can be null or an instance of ActiveDataProvider. In your template you use the GridView as before, but surround it with an if:

...
<?php if ($dataProvider !== null): =>
    [ insert your GridView code here ]
<?php endif; ?>
...

The problem ist, when I push the Submit-Button nothing happens, but in my point of view at least the datagrid based on the query shold be rendered?

That difficult to say without more details. Are you sure, your webserver displays any errors (see Showing all errors and warnings)?

Community
  • 1
  • 1
  • Thank you so much Brian...the code works. The only problem that's left is the pagination of the gridview: as you can see in my controller the query and dataprovider are only set if there's a POST request. When I change the site of the gridview by pagination there's a GET request and the result is, that the gridview isn't rendered with the next page...any ideas how to solve that? – Chris vD Feb 26 '15 at 14:36
  • You have two options: either you remove the automatic pagination and add a custom one to your form or you cange your form to not transfer the values in the POST body but as URL parameters with GET request's instead. Than,you have to add the current values to the automatically generated pagination links. – Brian Pfretzschner Feb 26 '15 at 18:29
  • Hi Brian, I tried it now for 4 hours to get it to work but no way: "transfer the values in the POST body but as URL parameters with GET request's instead"...I didn't understand that, sorry. So I focused on changing the pagination method to POST but didn't figured it out (also no useful help with google). Another idea I had was to implement a trigger that changes his state with the first POST-request and implement it in the IF clause...also not succesful. So I'm a litlle bit lost right now... – Chris vD Feb 26 '15 at 21:52
  • Submit a form via GET is easy, see http://stackoverflow.com/questions/1116019/submitting-a-get-form-with-query-string-params-and-hidden-params-disappear for instance. If you achived this, you should see all the values you entered in the Url. Remember, you have to change your controller code, since it checks for POST requests but now needs to check if a get variable isset or not. When you got this, everything should work as before. Than you can figure out how to chnage the link template for the pagination links in order to include the form values in there. – Brian Pfretzschner Feb 26 '15 at 22:14
  • took me a while but you are the checker...another thousand thanks to you!!! Evereything runs perfectly! – Chris vD Feb 27 '15 at 00:36
  • No problem! Please think about marking my answer as solution ;-) – Brian Pfretzschner Feb 27 '15 at 07:26