1

I'm trying to update a checkbox field of an entry through a plugin service. I tried two things:

  1. Get the field values with $entry->fieldHandle->getOptions(), then manipulating the resulting array, then set the value with $entry->fieldHandle->setOptions()

    $contact = Entry::find()
        ->id(...)
        ->one();
    $newsletters = $contact->contactNewsletterSubscriptions->getOptions();
    $newsletters[$index]->selected = false;
    $contact->contactNewsletterSubscriptions->setOptions($newsletters);
    Craft::$app->elements->saveElement($contact);
    

(where $index is the array index of the setting I want to change)

-> this didn't work (no error message, changes just didn't get saved)

  1. If I make a var_dump of $contact, the field contactNewsletterSubscriptions is showed as string. I played around with json_decode and serialize to get the right formatting (it looks exactly as when doing a var_dump):

    $newsletterSubscriptions = json_decode($contact->contactNewsletterSubscriptions->serialize());
    $index = array_search($newsletterName, $newsletterSubscriptions);
    unset($newsletterSubscriptions[$index]);
    $contact->contactNewsletterSubscriptions = (string)json_encode(array_values($newsletterSubscriptions))
    

-> doesn't work either; value gets saved as string; if I later call getOptions() on the field I'm getting "Call to a member function getOptions() on string"

Any idea how I can change the status of a checkbox from selected = true to selected = false?

Best regards.

1

You need to set the field value, not the options

$entry->setFieldValue('fieldHandle' [
    'value1', 'value2'
});
Craft::$app->getElements()->saveElement($entry);

If you want to change the values, the easiest method is

$allOptions = $entry->getFieldValue('fieldHandle');
$selected = [];
foreach($allOptions as $option){
    if($option->selected){
         $selected[] = $option->value;
    }
}
// unset a value
unset($selected[1]);
// add another value
$selected[] = 'anotherValue';
$entry->setFieldValue('fieldHandle', $selected);
Craft::$app->getElements()->saveElement($entry);

edit

Another approach - a little bit less code and more general since it's the same for every single field in Craft - but more resource heavy

$field = Craft::$app->getFields()->getFieldByHandle('handle);
$selected = $field->serializeValue($entry->getFieldValue('handle'), $entry);
$selected[] = 'anotherValue';
$entry->setFieldValue('handle', $selected);
Craft::$app->getElements()->saveElement($entry);
  • Accepted solution! Works perfectly - Thanks a lot! – Mischa Sz. May 7 '18 at 8:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.