[SOLVED] CDD and Eval options

AlainR

Member
Hi!
On the wiki page, I can read "Each option is an object and can be referenced in the eval code with the variable $opt. It has two properties $opt->value and $opt->text"

But how populate several values ?

Context : I have a first field with radiobutton to choose a date. Depending this first choice, CDD search a value (nb max places) and in Eval options I calculate the number of remaining places.
Then, I want to create the dropdown with personal values and labels, but $opt->value and $opt->text only return 1 value and 1 text (label) :(

Here the end of my code :
PHP:
...
for( $i= 0 ; $i <= 10 ; $i++ )
{$s=($i>1 ? 's' : '');$PlaCe=$i.' place'.$s;
$list[]= JHTML::_('select.option', $i, $PlaCe);
$obj[]->text=$i.' place'.$s;
$obj[]->value=$i;
$opt->text=$i.' place'.$s;$opt->value=$i;
}
dump($obj,'Obj');
dump($opt,'opt');
return implode($obj);//return implode($list);
//$opt->text=$obj[]->text;
//$opt->value=$obj[]->value;
As you see I tested different ways, but without success.

Many thanks in advance for your help.
Best regards.
 
Your code is called for each option in the dropdown (or whatever).

So if the CDD has selected 10 rows, your code gets called 10 times, with $opt set for each one, with the value and text of that option on the select.

Your eval code isn't creating the selections. That's done by the CDD, looking up the table you configured, filtered by the value of the FK. You can change the option value (not recomended) or the label, or you can return false and remove an option, but you can't build new ones.

This isn't like the radiobutton eval where you can build the entire select from scratch. This just lets you modify existing options.

-- hugh
 
OK, thanks, I understand the operation better.
So I have to completely revise my approach to the problem ...
Which is the best way to reach my goals:
  • according to the 1st choice, if there are more than 10 places, the drop-down menu must offer between 1 and 10 places.
  • If there are fewer than 10 places, e.g. 7, the drop-down menu must be between 1 and 10 places.
  • And if it's full, the drop-down menu does not offer anything.

I keep digging, thank you in advance for any advice.
 
Hmmm. You could do it with a dropdown, where the 'eval populate' allows you to build the entire select. But that only happens on form load, it won't update with changes to an "observed" element on the form.

The only solution I can think of is instead of having one row in your "max_places" table (which is presumably a table with a date and a max_places field), you have (a minimum) of ten rows per date. And instead of "max_places" you have a "place_available" ... so for a given date ...

date, available
01/01/2017, 1
01/01/2017, 2
01/01/2017, 3
01/01/2017, 4
01/01/2017, 5
01/01/2017, 6
01/01/2017, 7
01/01/2017, 0
01/01/2017, 0
01/01/2017, 0

Then the the CDD eval opts, something like ...

Code:
if ($opt->value == '0') {
   return false;
}

... which should remove the select option for anything with a 'available' of 0.

However ... note that you'll still have to use the id (PK) of that table as the 'value' in the CDD, and 'available' as the label. So the number stored in your main table is still an FK, not the number of places. It'll render as the number of places, but if you are exporting that data or expecting it to be the actual number of places ...

-- hugh
 
Primary Key and Foreign Key.

Tables have PK's, in Fabrik they are usually the 'id' element. When you have a join element (or a CDD, which is also a join), that stores the FK, which point to the PK of the other table. So if that join element is referencing row 123 (the PK of the row in the other table), that the value it stores, which is the "foreign key".

-- hugh
 
Thank you very much.
What do you think of this :
a hidden field populate a temporary table with date (or id? - PK) and numbers 1 to 10, constructed like my 1st field (radiobutton for each date), but 1 record per date up to 10 for each date. And CDD constructs from this temp. table.
And the temp. table is emptied and then populated at the form loading. Is it possible ?

I explored the calc field and discover that I cannot do anything whit it, only calculate something. Perhaps a "imple" hidden field. I try and come back with... I hope.... a fine result!

But in the meantime ... : Merry Christmas!
 
That sounds hideously complicated and not very workable. Remember the CDD rebuilds its options every time you change the "watched" element on the page, so you'd have to write you own AJAX and JS code to somehow rebuild that table before the CDD refresh runs when the watched element is changed. And I'm not quite sure what you gain by doing that, over the method I suggested.

It might even be possible to automate the creation of the "available slot" rows. Keep your existing max_places table, create another places_available table, and either create a Fabrik submission script on max_places that updates the places_available table (inserting rows as required), or even a MySQL trigger statement. So when you save a max_places row and set it to (say) 7, the plugin automatically creates (or updates) the ten rows in the available_slots table. That would simplify the process of maintaining your app, although it wouldn't be entirely trivial to implement.

-- hugh
 
Keep your existing max_places table, create another places_available table, and either create a Fabrik submission script on max_places that updates the places_available table (inserting rows as required), or even a MySQL trigger statement. So when you save a max_places row and set it to (say) 7, the plugin automatically creates (or updates) the ten rows in the available_slots table. That would simplify the process of maintaining your app, although it wouldn't be entirely trivial to implement.

-- hugh
This is partly my idea: keep the table and create another table that contains 10 times the dates. Your idea, simpler than mine, is to only update the table.

On the other hand, I do not understand how to create a submission script. Do you mean another Fabrik form?
And I do not understand what a MySQL trigger statement is, but I'll look after on the web.

Many thanks again.
 
Last edited:
It might even be possible to automate the creation of the "available slot" rows. Keep your existing max_places table, create another places_available table, and either create a Fabrik submission script on max_places that updates the places_available table (inserting rows as required), or even a MySQL trigger statement. So when you save a max_places row and set it to (say) 7, the plugin automatically creates (or updates) the ten rows in the available_slots table. That would simplify the process of maintaining your app, although it wouldn't be entirely trivial to implement.
Many thanks again.
Here is my PHP submission script, onLoad :
PHP:
$db = JFactory::getDbo();
$db->setQuery('truncate dates_repr_temp;');
$rows = $db->execute();

...

$rows = $db->loadObjectList();
foreach ($rows as $row) {
if ($row->NBreste<10 and $row->NBreste>0){
for($i=1;$i<=$row->NBreste;$i++)
{
$db->setQuery('INSERT INTO `dates_repr_temp` (`id_repr`, `places`) VALUES ('.$row->spec_repr_id.','.$i.');');
$query = $db->execute();
}} else{
for($i=1;$i<=10;$i++)
{
$db->setQuery('INSERT INTO `dates_repr_temp` (`id_repr`, `places`) VALUES ('.$row->spec_repr_id.','. $i.');');
$query = $db->execute();
}}}
(Edit : code corrected as Hugh writes below)

Best regards.
 
Last edited:
Well, like I said earlier, if you run it on form load, it'll only have the rows for whatever the "watched" element of the CDD is on page load. It won't update when you change that watched element on the form.

And that code is kinda wrong. If you want to truncate or insert, do $myDb->execute(), not loadObjectList(). Only use the loadSomething() functions if you are selecting rows (performing some query which returns a set of rows). And you only need to fetch the $myDb object once with JFactory::getDbo().


-- hugh
 
Thank you very much for correcting my code!

I read what you said earlier, but I do not understand.When the form is loaded, it executes the same query as the query to construct the first field / element - the "searched" element. So when I select a date (first item), the CDD "monitors" the ID and "fills" the drop-down menu accordingly.
After saving the form, it is reloaded, the query is executed and the 1st element and the table for the CDD are successfully filled in again.

In fact, I do not understand what means "cause you problems down the line."

Thanks again and best regards.
 
Just means "cause you problems in the future".

Maybe I'm misunderstanding what you are trying to do. But if you are populating that table based on the date radio selection, and then change the selection, the temp table won't get repopulated.

So, say you load the page and date ID 1 is selected. You populate the temp table the CDD is using according to the number of slots for date 1. Then on the page, you change it to date 2. You'll still get CDD options for date 1.

-- hugh
 
Thanks for the clarification. In fact, the temp table is constructed from all the options of the first radiobutton element. So the CDD changes according to the 1st choice. This works really well. I cannot give you access right now. Or perhaps as member, tell me if you're interested.
And if there are fewer than 10 places, e.g. 7, the CDD will offer only 1 to 7 places.
I have tested with the addition of a new event and new dates and everything works great. Thanks again Hugh !!
 


I have CDD and it works fine. But if I use the eval option for filtering it returns empty. For example;
Code:
if ($opt->value != '5') {
   return false;
}
upload_2021-10-3_23-59-26.png
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top