Display Logic Module for SilverStripe 3
28 Jan
Hello, SilverStripers!
Have you ever had a page type or DataObject that has fields that should only be displayed if other form fields are set a certain way? Imagine an object that can take either an internal link (TreeDropdownField) or an external link (TextField). If one is filled out, the other should not display.
The Display Logic module allows you to create a very verbose set of logic that, when evaluated, determines whether the field should show or hide. And it $looks->absolutely(“Beautiful”)->thanksTo(“chainable methods”)!
Best of all, it works with Bootstrap Forms!
Example Usage
$products->displayIf("HasProducts")->isChecked();
$sizes->hideUnless("ProductType")->isEqualTo("t-shirt")
->andIf("Price")->isGreaterThan(10);
$payment->hideIf("Price")->isEqualTo(0);
$shipping->displayIf("ProductType")->isEqualTo("furniture")
->andIf()
->group()
->orIf("RushShipping")->isChecked()
->orIf("ShippingAddress")->isNotEmpty();
->end();
More Information
Please checkout the Github page for more information, including documentation.




Are you using Entwine here to trigger things?
Also, is there a specific reason for using the Field::create() method?
I like the new FieldType(); method more, personally. It might not be the best method, but the create-method is cluttery to me.
Field::create() hooks into the new Dependency injection framework in 3.0 allowing greater customization of those fields.
Yup. What he said. Also it hooks into Object::useCustomClass(), and if you’re in PHP < 5.4, it makes the instantiation chainable.
Also nice work Aaron! Liking the fluent api use. So this supports front end forms as well as CMS forms?
Thanks, Will. Yes. It’s controller agnostic.
Ah, ok, then it definitely makes sense. I’m going to rewrite some of my backend I guess.
Hadn’t realized/read that.
I guess cluttery looking functionality over preferred cleanliness
Aaron, wonderful work! You’re a crack.
Another very useful module. Thanks!
I am trying out the following code in conjunction with your Bootstrap Forms module:
OptionsetField::create(‘Options’,_t(‘Content.Options’, ‘option?’))
->setSource(array(‘Option1′, ‘Option2′)),
EmailField::create(‘Option1′,_t(‘Content.Option1′, ‘Option1′))
->displayIf(‘Options’)->isEqualTo(‘Option1′)->end(),
TextField::create(‘Option2′,_t(‘Content.Option2′, ‘Option2′))
->displayIf(‘Options’)->isEqualTo(‘Option2′)->end(),
This then produces the following code:
…
– All my regular scripts then appear here, followed by bootstrap_forms.js, jquery.entwine-dist.js and display_logic.js
– Then this comes next: ($(“#Options”).evaluateEqualTo(“Option1″))
….
That seems to have stripped my code. Should be:
…
[div id="Option1" etc.]
[label etc.]
[div class="controls"]
[input name="Option1" etc.]
[/div]
– All my regular scripts then appear here, followed by bootstrap_forms.js, jquery.entwine-dist.js and display_logic.js
– Then this comes next: [script type="text/template" class="display-logic-eval"]($(“#Options”).evaluateEqualTo(“Option1″))[/script]
[/div]
[div id="Option2" etc.]
….
Yeah, that’s a really annoying feature of the Requirements system. If you have Requirements::$write_js_to_body enabled, it looks for the first script tag in the body and appends everything after that, rather than just putting everything before the closing body tag. One fix is to set Requirements::set_write_js_to_body(false);, but not everyone likes to do that.
In a perfect world, it makes the most sense for the parseable logic string to be in a script tag, because it’s naturally hidden, and it is, well, script. But I suppose we could change that to a div and apply a display none to it with CSS. I’m not crazy about it, but I do see the limitation, and I’d much rather a practical solution than a conceptually perfect one.
Thanks, it makes sense now, I’ve had these issues with requirements before, I wish it was more flexible.
Can you try changing the script tag to a div (and removing the type attribute) from all the templates that come with the module and let me know if that works?
Requirements is a can of worms. There needs to be a much more strict dependency management system in place, but there are many ways to do it, and none of them perfect. One of the biggest flaws I see in Requirements right now (for which I don’t have a fix) is that dependencies are called by path, not by name. It’s easy to end up with three or four different jQuery sources in your document!
I‘m not sure if this is exactly what you asked for but I changed to:
This shows all options. Clicking any of the linked radio buttons then toggles all options.
Sorry, forgot about tags. [div class="display-logic-eval"][/div]
Hi, Matthew,
You haven’t set the source of your OptionsetField properly. Be sure to pass key/value pairs rather than a list, because as you have it, the value you should be checking for is “0″ or “1″..
So much cleaner then the hacked up logic I’ve used in the past. Can’t wait to try this!
Is there a way to listen for if a has_one image has been added? My first attempt was $photooption->displayIf(“Photo”)->isNotEmpty();
No support for upload fields. They don’t fire change events. Maybe we can get Zauberfisch to add one
Wow, that looks really cool.
The rules remind me of our netefx validator.
But with this chaining they are much smarter.
So maybe you can reuse this to build a validator of it.
Regards
Lx
Miodzio
love it.
do i hear silversmith addon???
Can anyone verify that their default “Insert Link” popup works with this module?
Cos when I installed this, the js that handles the default “Insert Link” popup doesn’t seem to fire and everything just displays.
Is there a clash somewhere?
Yeah, I just confirmed it. It’s not a JS issue as far as I can tell. If you delete /display_logic/templates/Includes/FormField_holder.ss it works. (But you lose the display logic features).
This one’s a bit of a mystery right now.
This bug is fixed.
Thanks unclecheese!