Add a customfield in the panel that changes depending on other fields

In my panel I got 3 fields for score criteria.
For example:
Taste: 50%
Color: 75%
Price: 100%

Now I want that I have a fourth field: the final score. This field should automatically have the average of the 3 criteria scores. In this example 75%.

Is this possible with Kirby?

You can easily convert the input of your fields with int() and then use php to calculate your final score. For example:

<?php echo $page->taste()->int() ?>

will echo 50 instead of 50%.

Edit: Uups, I didn’t get the fact that you would like to store it in a fourth field … Maybe you could use $page->update() to achieve this?!

Okay with the first part you already help me now :slight_smile:

In my template.php I put this now:

$zusammensetzungscore = $page->zusammensetzung()->int();
$geschmackscore = $page->geschmack()->int();
$preisleistungscore = $page->preisleistung()->int();
$gesamtwertung = round(($zusammensetzungscore + $geschmackscore + $preisleistungscore)/3);

Yeah theres probably a more elegant way, but I am a horrible programmer.
This works now, it correctly calculates the overall score.
But how can I access this variable outside the page? I got a sidebar where I want put the finalscore too.

And I still need figure out how I can do it in the panel. Don’t understand your hint with update(). Can I even use php in the blueprint?

It’s a little messy, but in your template code you could do this

try {

  $page->update(array(
    'gesamtwerung' => $gesamtwerung
  ));

} catch(Exception $e) {

  echo $e->getMessage();

}

which will add a gesamtwerung field to your page. Then you can use that field in blueprints and templates like any other field.

The catch here is that the template code updates gesamtwerung, so if you change the component scores in the panel, the overall score won’t update until the template code runs.

Maybe you should also consider to use a number field and don’t store the % within the field but add it later in the template. With a number field you have a built-in validation and maybe more consistent data.

And maybe instead of putting in a fourth field, you could write a little function that calculates the overall score, so you can access it more easily in the sidebar or other templates.

This sounds like a perfect case for a page model…

Unfortunately it’s not documented very well outside of this video:

Instead of using update to add the value to your page, you can just use a page model to dynamically calculate your score and make it available globally.

1 Like

You could also use a controller to clean up your template code.

Alright.
I changed the score fields in the blueprint to numbers.

My code in the template looks like this now:

$crit1 = $page->criteria1()->int();
$crit2 = $page->criteria2()->int();
$crit3 = $page->criteria3()->int();
$finalscore = round(($crit1 + $crit2 + $crit3)/3);

Do I still need use the ->int() ? Because now these are anyway numbers. But I tried it without and it not work.

Next question: I should put this in a controller now? Is it then a global variable that I can use on other pages? This is what I am still missing. I need access the $finalscore variable in my sidebar too. But my sidebar dont know the variable!
Is it possible to put the $finalscore in a global variable like I have for the blueprint variables? The criteria scores I can easily access with criteria1() and so on. This not works with $finalscore

Last question:
So what I wanted to do with a dynamic panel that automatically fills a fourth field with the final score, is not easy to do? The solution that I got now works, yes. But sometimes I got the situation that I want change the finalscore, this why I want have it in a panel field.

Yes, because the variable type of $page->criteriaX() etc. is always an object of the FieldAbstract class, not an integer, no matter how you define it in your blueprints because there is not way to tell from the text file what it is supposed to be.

A model makes most sense, because this way the “dynamic field” will be available from other templates referencing the page as well. The tutorial video embedded above is a good start.

The Panel sidebar or one in the frontend? If the latter, a model is the way to go.

You can create an actual field “finalscore” and decide from your model method whether to calculate the score or whether to return the fixed score depending on the value of the field (if it is empty or contains a value).

Alright I am trying it out right now.
It’s bad for me that theres no documentation, that makes it for a newbie like me super hard!

I made now a model and put this inside

<?php

class ProjectPage extends Page {
	public function scoreaverage() {
		$crit1 = $page->criteria1()->int();
		$crit2 = $page->criteria2()->int();
		$crit3 = $page->criteria3()->int();
		$finalscore = round(($crit1 + $crit2 + $crit3)/3);
		return $finalscore;
	}

}
?>

Ofcourse it’s not working, I obviously do a million mistakes.
My questions:
Is the class name important? I just took the name from the video.

I tried call the function in my template like this:

<?php echo $page->scoreaverage()->html() ?>

Is that right?

What is your template called? Is it project.php?

No its review.php. Alright this I already fixed. Yeah the name is important :slight_smile:
I named it now ReviewPage.
But it’s still not working.

I probably need use $this or something. I can’t figure it out : (

Yes, that’s definitely true. Models are a quite new feature and written documentation will very likely follow.

That’s exactly what you need to do. Simply replace $page with $this. :slight_smile:

1 Like
<?php

class ReviewPage extends Page {
	public function scoreaverage() {
		$crit1 = $this->criteria1()->int();
		$crit2 = $this->criteria2()->int();
		$crit3 = $this->criteria3()->int();
		$finalscore = round(($crit1 + $crit2 + $crit3)/3);
		return $finalscore;
	}
}
?>

Thanks.

And how can I access this now?

I tried

<?php echo $review->scoreaverage()->html() ?>

and

<?php echo $page->scoreaverage()->html() ?>

both is not working

Try page('review')->scoreaverage()

Not working. :neutral_face:

Maybe the function not working? Is there a way to test if this is even working at all?

I’m trying to find out when that features was integrated, what Kirby version are you using?

Have you tried if it works on the review page itself …