Score:0

How can I set multi-value datafield on node submit?

bs flag

I would like to calculate and set the fourth (points) subfield of datafield on form submit. In the for each loop, the second and third subfield are used to calculate $points. How can I set/save the fourth value?

enter image description here

function handling_points_settings_submit(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
 $duration = 0.6;
 $node = $form_state->getFormObject()->getEntity()->toArray();
 // dpm($node);
 // dpm($node['field_player_stats']);
  $allPlayers = $node['field_player_stats'];
 foreach ($allPlayers as $player)   {
    //dpm($player["player"]);
    //dpm($player["wins"]);
    if (isset($player["player"])) {
        $points = intval($player["wins"]) * $duration * 2 + intval($player["non_wins"]) * $duration;
        \Drupal::messenger()->addStatus(t(htmlentities('Points' .  $points))); 
    }
//something along this:
// $form_state->setValue('field_player_stats',[$player["points"]=>$points]);
 }
 

}

Score:1
in flag
   function handling_points_settings_submit(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $duration = 0.6;
  $node = $form_state->getFormObject()->getEntity()->toArray();
  $allPlayers = $node['field_player_stats'];
  foreach ($allPlayers as &$player) {
    if (isset($player["player"])) {
      $points = intval($player["wins"]) * $duration * 2 + intval($player["non_wins"]) * $duration;
      $player["points"] = $points;
    }
  }
  $node->set('field_player_stats', $allPlayers);
  $node->save();
  \Drupal::messenger()->addStatus(t('Points calculated and saved for all players.'));
}

In this example, we first retrieve the value of the my_datafield element from $form_state using the getValue() method. We then loop through each item in the datafield using a foreach loop, and calculate the points value using the second and third subfields. Finally, we set the fourth subfield value to the calculated points value, and update the datafield value in $form_state using the setValue() method.

Note that in the code above, we are using the & reference operator to modify the $item variable directly, rather than creating a copy of it. This allows us to modify the actual value of the datafield subfield instead of just changing the value of the $item variable.

user24957 avatar
bs flag
Hi Vikram! The line $points = $item['non_wins']; causes this error. dpm ($item) works and shows the correct object. Error: Cannot use object of type Drupal\Core\StringTranslation\TranslatableMarkup as array in drupalbook_settings_submit() (line 160 of /home/xxx/public_html/staging/web/modules/custom/drupalbook/drupalbook.module)
Vikram8888 avatar
in flag
i just gave you a working reference dont modify your own code ,only check and compare with my code what you are missing
user24957 avatar
bs flag
i tried it with the original values, just renamed the field. it might be the last $item object ("add another item") that does not contain the non_wins? i am checking this now
Vikram8888 avatar
in flag
i have updated the above code
user24957 avatar
bs flag
Thanks for the help, Vikram. The line $node->set('field_player_stats', $allPlayers); causes an error. I did not change anything Error: Call to a member function set() on array in drupalbook_settings_submit() (line 165 of /home/xyz/public_html/staging/web/modules/custom/drupalbook/drupalbook.module)
user24957 avatar
bs flag
Using the code with the entity_presave hook worked. Important is the & reference operator. Thanks!
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.