Get array of disabled from CheckboxList

ajda2
Member | 66
+
0
-

Hi,
can you please help me with that I need from instance \Nette\Forms\Controls\CheckboxList its disabled values as array?

It is Nette 2.4

I have the checkboxList, which is filed with items.
Some items are marked as disabled, which is done via code:

$checkboxList->setDisabled([1, 2,]);

These disabled items are properly rendered in with HTML attribute disabled and CheckboxList object has this array in private property disabled. But there is no getter for this.

But I need to get disabled values in Latte, when is checkboxList manually rendered.
This is needed for setup some HTML class of another elem and so on.

Here is the point, which I cannot figure out.
How can I get an array od all disabled values from checkboxList instance?
There is getter:

$checkboxList->isDisabled(); // TRUE | FALSE only for whole CheckboxList object

I searched documentation, API, forum, try lots of directly in code, but I cannot reach proper way to do this.

I know, that is posibility to use option attribute:

$checkboxList->setOption("disabled", [1, 2,]);

And then in Latte file get values from this attribute.
This way is pretty ugly, because when I forget to setup “option” property, code goes wrong.

Thank you very much for any help!

Last edited by ajda2 (2020-03-16 09:43)

dkorpar
Member | 135
+
0
-

This is not really nette issue, by default disabled elements in HTML are not sent as post so you can't get that…
Maybe readonly is good enough?
Otherwise some hidden inputs maybe or something like that…

ajda2
Member | 66
+
0
-

Hello dkorpar,
thank you for your answer.

I know that after form is sended, the values marked as disabled are not sent in request.

What my problem is, when I configure some items in CheckboxList or RadioList as disabled in Nette\Forms\Controls\CheckboxList object I want to access to disabled property as array in code elsewhere.

I dont want to access item values after is form sended.

Maybe it will be more clear in this example:

/** @var \Nette\Forms\Controls\CheckboxList $checkboxList */
$checkboxList->setDisabled([1, 2,]);
$disabled = $checkboxList->isDiabled();
var_dump($disabled); // returns FALSE, but I want to get my array [1,2]

dkorpar wrote:

This is not really nette issue, by default disabled elements in HTML are not sent as post so you can't get that…
Maybe readonly is good enough?
Otherwise some hidden inputs maybe or something like that…

dkorpar
Member | 135
+
+1
-

Maybe a bit ugly but you could get info with:

$checkboxList->getControlPart(1)->getAttribute('disabled'); //true
$checkboxList->getControlPart(2)->getAttribute('disabled'); //true
$checkboxList->getControlPart(3)->getAttribute('disabled'); //false

Last edited by dkorpar (2020-03-16 12:08)

ajda2
Member | 66
+
0
-

Thanks a lot @dkorpar !
This approach is working nicely.

Dont you know, if there is in Nette 3.0 “smoother” solution such as

$checkboxList->getDisabled(); // returns array?

Because internaly property disabled contains array of disabled values :D
But there is no way to get this values directly.
That is the reason, why I asked this question.
Maybe it is a time for feature request or pull request…

Anyway, thank you very much for your help!

dkorpar
Member | 135
+
+1
-

I don't see anything like that (any method that would give you that directly),
basically in nette/forms 3

public function isDisabled(): bool

there's actually typehint so this allways return boolean for sure.
I'm not involved into nette core so I can't tell you anything about that… If U have idea there's RFC section:
https://forum.nette.org/…for-comments

Last edited by dkorpar (2020-03-16 23:06)

Toanir
Member | 57
+
0
-

edit: whoops, i got lost in thought and missed the part that you need to use this in latte. Hm.

Technically you could extend the CheckboxList and override it's getControl method to adjust your rendering behavior and then add it to the form like this: $form['ingredients'] = new MySexyCheckboxList()

___
Hi. I have a quick question about whether we should while you're asking whether we can :P

Is it really a clean approach to pass this kind of information via the CheckboxList component? Typically form controls are only used to access user interaction with the website: we create the control in a form and configure it and then we let the form do its thing. We also register a success event handling callback in which we receive the values and that's about it as far as the form and its controls are concerned imho.

I believe that these disabled options, during handling, should be accessed from its source rather than from the form in a fashion something like this:

<?php
public function actionMealDiy($mealId) {
  $myAllergens = $this->allergens->getByUser($this->user->id);

  // form factory uses my allergens to disable certain meal ingredients
  $form = $this->mealDiyFormFactory->create($myAllergens);

  $form->onSuccess[] = function($form, $values) use ($myAllergens) {
    // here we have both the form values and the allergens to work with
  };

  $this['mealForm'] = $form;
}
?>

Last edited by Toanir (2020-03-17 09:46)

ajda2
Member | 66
+
0
-

Hi @Toanir ,
If I understand your post correctly, then I agree with you opinion.
After is form sended, we should not have access to disabeld input values.

But my use case was different and I want to access disabled items when it is rendered.

PHP:

<?php
$checkboxList->setDisabled([1, 2,]);
?>

And after that in Latte template or anywhere else:

{foreach $checkboxList->items as $key => $label}
	<label n:name="$name:$key" n:class="$checkboxList->getControlPart($key)->getAttribute('disabled') ? 'disabled'">
		<input n:name="$name:$key"> {$label}
	</label>
{/foreach}

But I think that this approach could be useful (Mainly for rendering, but you never know):

{if \in_array(1, $checkboxList->getDisabled())}
// Do something in template or whatever
{/if}

Toanir wrote:

Hi. I have a quick question about whether we should while you're asking whether we can :P

Is it really a clean approach to pass this kind of information via the CheckboxList component? Typically form controls are only used to access user interaction with the website: we create the control in a form and configure it and then we let the form do its thing. We also register a success event handling callback in which we receive the values and that's about it as far as the form and its controls are concerned imho.

I believe that these disabled options, during handling, should be accessed from its source rather than from the form in a fashion something like this:

<?php
public function actionMealDiy($mealId) {
  $myAllergens = $this->allergens->getByUser($this->user->id);

  // form factory uses my allergens to disable certain meal ingredients
  $form = $this->mealDiyFormFactory->create($myAllergens);

  $form->onSuccess[] = function($form, $values) use ($myAllergens) {
    // here we have both the form values and the allergens to work with
  };

  $this['mealForm'] = $form;
}
?>
ajda2
Member | 66
+
0
-

@Toanir Yes, extending class CheckboxList or RadioList will do the stuff.
But I thought, that is can be so useful, it should (and maybe is) implemented in core class.

So I asked, if there is something, what I overlooked :)

Last edited by ajda2 (2020-03-17 10:00)

Toanir
Member | 57
+
0
-

Alright, I think I understand your problem now. :P

I suppose having a corresponding getter method of setDisabled that would allow to either check for overall component disable state or its individual parts could come in handy and probably would make sense. If I were to search for it, I'd definitely try to look right next to the setDisabled.

I haven't been digging around in nette sources and I don't know them too well but if it's not in the MultiChoiceControl, I doubt it's anywhere else. I guess I'd recommend you to try out the RFC process as dkopar suggested. :)

If I was looking for the functionality, I'd welcome the most something like $checkboxList->isDisabled(1) to make its usage as pleasant as possible.

Toanir
Member | 57
+
0
-

Aside this issue, if you only want to add classes for css/js manipulations, you could probably avoid that by using the css attribute selectors such as input[type=checkbox][disabled]