KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

Widget update from Dropdown input #3187

Closed John opened this topic on on Nov 14, 2023 - 19 comments

John commented on Nov 14, 2023

I can not find a way to update a Dashboard Widget from a Dropdown input i use in my board class like the code below describes. I don't want to create a new file for the Dropdown, is this allowed?

MyBoard.php

class MyBoard extends Dashboard
{		
    protected function content()
    {
        return [
            Row::create([
                Panel::create()->width(1/2)->sub([
					Dropdown::create("ddinfooutline")
					->title("View by")->items([
						"Day"=>MenuItem::create()->icon("fas fa-info-circle")->onClick(function(){
			//				return Client::dashboard("CustomerBoard")->load(); 
							return 'mydate'; 
							$this->sibling("myWidget")->update(); 
						}),

myWidget.php

class myWidget extends ComboChart
{
    protected function dataSource()
    {
//		$range = $this->sibling("MyBoard")->value();
		$range = $this->sibling("ddinfooutline")->value();
KoolReport commented on Nov 15, 2023

The onClick is the client-event, you should use the server-side action submit of dropdown:

Dropdown::create("ddinfooutline")
    ->title("View by")
    ->items([
        "Day"=>MenuItem::create()->icon("fas fa-info-circle")
    ])
    ->action("submit",function(){
        $this->sibling("myWidget")->update();
    })

Let us know if you need further assistance.

John commented on Nov 15, 2023

Day item should return a value 'mydate' and other items below - that i didn't include in the code - should return their values. How is this could be done with the way you suggest? I don't think the problem is there... It shows me this error (now and before your suggestion): "Call undefined value() method" I think the problem is on the way myWidget gets the value from the input (that is included in the Dashboard and not to its class/file).

KoolReport commented on Nov 16, 2023

The Dropdown does not have value like other, so what you can do is like this:

    ->action("submit",function($request){
        $this->sibling("myWidget")->setRange($request->params("selectedText"))->update();
    })

Now in your MyWidget, you add setRange function and also the way to get the range in datasource of your widget.

public function setRange($range)
{
    $this->state("range",$range);
}

protected function dataSource()
{
    $range = $this->state("range")?$this->state("range"):"Day"; //Default value is "Day"
    ...
}

Hope that helps.

John commented on Nov 16, 2023

Thank you for the answer, i think we are on the right way now. I couldn't though manage to pass the values from the dropdown menu items to the widget... I tried different things and it keeps showing 'Call to a member function update() on null'...

I have this on Dropdown:

->items([
    "Day"=>MenuItem::create(),
    "Week"=>MenuItem::create(),
    "Month"=>MenuItem::create(),

and i want to pass: 'mydate' for Day, 'week(mydate)' for Week and 'month(mydate)' for Month

Can you help?

KoolReport commented on Nov 17, 2023

It seems that it could not find the "myWidget" instance. May I see the code when you initiate the myWidget in your dashboard?

John commented on Nov 17, 2023

Thanks for response. You can see code from myWidget.php below:

use \koolreport\dashboard\widgets\apexcharts\ComboChart;

use \koolreport\dashboard\fields\Text;

use \koolreport\dashboard\fields\Currency;

use \koolreport\dashboard\ColorList;

class myWidget extends ComboChart
{
    protected function onInit()
    {
        $this
        ->colorScheme(ColorList::random())
        ->settings([
			"stacked" => true,
            "columns" => array(
                "Period" => [
                    "categoryType" => "datetime"
                ],
                "Amount" => [
                    "chartType" => "column",
					"label"=>"Income",
                ],
..
            ),
            'strokeWidth' => [
                0,
                2,
                5
            ],
            'fillOpacity' => [
                0.85,
                0.25,
                1
            ],
			'colors' => ['#FF4560', '#775DD0', '#00D9E9', '#FF66C3', '#008FFB', '#00E396', '#FEB019'],
			"options" => [
                'dataLabels | enabledOnSeries' => [0,1,2,3,4],
                'yaxis | 0 | title | text' => 'Value in Euros',
				'stroke | width' => 3,
                "legend | position" => "bottom",
            ],
            "showLabel" => true,
            "maxWidth" => "800px",
        ])
        ;
    }
	
	public function setRange($range)
	{
		$this->state("range",$range);
	}

    protected function dataSource()
    {
		$range = $this->state("range")?$this->state("range"):"month(mydate)"; 
		if (empty($range)) { $range = "month(mydate)"; };
		$source = mydb::rawSQL("
SELECT ...
		")
	   ->run() ;

    }

    protected function fields()
    {
        return [
            Text::create('Period'),
            Text::create('Amount'),
..
        ];
    }
}
John commented on Nov 23, 2023

Is there any news for this?

KoolReport commented on Nov 24, 2023

Sorry for late reply, I mean the code inside the MyBoard class where you create the myWidget because it seems to me that "myWidget" is not yet correct name, that why the ->sibling("myWidget") return null.

John commented on Nov 24, 2023

Ok, here it is:

MyBoard.php

<?php

use \koolreport\dashboard\Dashboard; use \koolreport\dashboard\containers\Row; use \koolreport\dashboard\containers\Panel; use \koolreport\dashboard\widgets\Text; use \koolreport\dashboard\containers\Html; use \koolreport\dashboard\menu\MenuItem; use \koolreport\dashboard\inputs\Dropdown; use \koolreport\dashboard\Client;

class MyBoard extends Dashboard {

protected function content()
{
    return [
        Row::create([
            Panel::create()->width(1/2)->sub([
				Dropdown::create("ddinfooutline")
				->title("View by")->items([
					"Day"=>MenuItem::create()->icon("fas fa-info-circle"),
					"Week"=>MenuItem::create(),
				])
				    ->action("submit",function($request){
						$this->sibling("myWidget")->setRange($request->params("selectedText"))->update();
					}),
                myWidget::create()
            ]),
            Panel::create()...
KoolReport commented on Nov 25, 2023

I see the issue now, instead of this

    $this->sibling("myWidget")->setRange($request->params("selectedText"))->update();

you do this:

    $this->sibling("myWidget")->setRange($request->params("selectedText"));
    $this->sibling("myWidget")->update();

or in this setRange, you need to return $this

	public function setRange($range)
	{
		$this->state("range",$range);
                return $this; //->this is important
	}

Also in the dataSource function, you need a map like this:

protected function dataSource()
{
    $rangeText = $this->state("range")?$this->state("range"):"Day";
    $map = [
        "Year"=>"year(mydate)",
        "Month"=>"month(mydate)",
        ...
    ];

    $range = $map[$rangeText];
    ...
    //now you can use the $range inside SQL.
}
John commented on Nov 25, 2023

Thank you!

John commented on Mar 3

Hi again. Is there a way to add a second (and maybe a third later) dropdown (pls see image)? I replicated the code for the second but it doesn't work. It seems that the 'state' is somewhere mixed... E.g. when i select a value from 1st dropdown error says 'Undefined array key..' from 2nd dropdown value.

John commented on Mar 6

Do we have to use only one dropdown per widget?

Sebastian Morales commented on Mar 7

What do you want the 2nd dropdown to act relatively to the 1st one and MyWidget?

John commented on Mar 7

I mainly use it like this: I want to see "Open" tasks (1st dropdown) which are of "High" priority (2nd dropdown). Or i want to see all "Open" tasks...

Sebastian Morales commented on Mar 14

Sorry for the late reply. So basically you want to update the 1st dropdown's list of tasks when the 2nd one changes, dont' you? In any case, pls post your code for the 2 dropdowns.

John commented on Mar 14

Hi and thanks. Below you can see my code.

First my dashboard has this code:

class myBoard extends Dashboard

            Row::create([
				Panel::create()//->header("<b>Tasks</b>")
				->sub([
					Inline::create([
					Dropdown::create("ddinfooutline")
					->title("View by Status")->items([
						"Open"=>MenuItem::create(),
						"Completed"=>MenuItem::create(),
						"Canceled"=>MenuItem::create(),
					])
					->action("submit",function($request){
						$this->sibling("myTasksWidget")->setByStatus($request->params("selectedText"));
						$this->sibling("myTasksWidget")->update();
					}),
					
					Dropdown::create("ddinfooutline")
					->title("View by Priority")->items([
						"Low"=>MenuItem::create(),
						"Normal"=>MenuItem::create(),
						"High"=>MenuItem::create(),
					])
					->action("submit",function($request){
						$this->sibling("myTasksWidget")->setByPriority($request->params("selectedText"));
						$this->sibling("myTasksWidget")->update();
					}),
			]),		
				myTasksWidget::create()
			]) 
				]),

And my widget has:

class myTasksWidget extends TimeLineChart

public function setByStatus($viewbystatus)
{
	$this->state("viewbystatus",$viewbystatus);
	return $this;
}	

public function setByPriority($viewbypriority)
{
	$this->state("viewbypriority",$viewbypriority);
	return $this;
}

protected function dataSource()
{
	$viewbystatusText = $this->state("viewbystatus");//?$this->state("viewbystatus"):"Open";
$map = [
	"Open"=>"taskstatus = 'Open'",  
	"Completed"=>"taskstatus = 'Completed'",  
	"Canceled"=>"taskstatus = 'Canceled'", 
];	
	$viewbypriorityText = $this->state("viewbypriority");
$map2 = [
	"Low"=>"taskpriority = 'low'", 
	"Normal"=>"taskpriority = 'normal'", 
	"High"=>"taskpriority = 'high'",
];
	$viewbypriority = $map2[$viewbypriorityText];
	$viewbystatus = $map[$viewbystatusText];
Sebastian Morales commented on Mar 20

I saw that you had two dropdowns with the same name "ddinfooutline". It would probably be a good practice to use two different unique names for the two dropdowns so that you can access them by name correctly.

John commented on Mar 20

It was so simple, thanks!

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
help needed

Dashboard