Only allow one Lightswitch to be active at a time I am working on a news section. There is a single featured news story so the lightswitch marked with ('1') displays the latest entry as the featured story. 

Below this the rest of the entries are displayed so here I then display all other latest entries with the lightswitch marked with ('0') or in this case ('not 1').

My problem is that if two or three entries are all marked as the featured story (or a user creates an entry and marks it as featured then repeats a few days later and doesn't uncheck the previous one) then they will not display in the below section. Is there anyway to only allow one lightswitch to be checked as ('1') at any one time.

Featured entry:


  {% for entry in craft.entries.section('news').featured('1').limit(1) %}


All other news entries:


  {% for entry in craft.entries.section('news').limit(4).featured('not 1') %}
You'd have to write a custom plugin that added an event listener for the  entries.saveEntry event.

Inside the event listener, you could check if the entry being saved has a true value for the featured Lightswitch field, and if so – pull all other entries with a true value for that same field (in the same section), setting their featured attribute to false before re-saving them.

Something like the below would go into your plugin's primary class:

public function init()
{
    parent::init();

    craft()-&gt;on('entries.saveEntry', function (Event $event) {

        $entry = $event-&gt;params['entry'];

        if ($entry-&gt;section-&gt;handle !== 'news' || !$entry-&gt;featured) {
            return false;
        }

        // Get all entries from the same section with a `true` value for the Lightswitch field
        $entries = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry, array(
            'section' =&gt; 'news',
            'featured' =&gt; true,
            'id' =&gt; 'not ' . $entry-&gt;id,
            'limit' =&gt; null,
        ))-&gt;findAll();

        // Update all other entries' Lightswitch field value to `false`
        foreach ($entries as $entry) {
            $entry-&gt;getContent()-&gt;setAttribute('featured', false);
            craft()-&gt;entries-&gt;saveEntry($entry);
        }

    });

}


If you're new to plugin development in Craft, I'd suggest looking at the Business Logic plugin template or the pluginfactory.io app – also it'd be a good idea to read the official docs on the subject.

If you don't want to write a plugin, you could also solve this by foregoing the featured field for the entries. If you added a featuredNewsStory Entries field to a Global Set instead (and limited the Entries field to 1 entry), you'd make sure that there was only ever one featured news story in the system. The editiorial workflow would suffer, though – publishing a new, featured news story in this manner would mean that the editor would first have to create the story, then pop into the Global Set after saving the entry to actually mark it as "featured".

Anyway, here's how you could pull the featured news story from a global, as well as the other news stories that aren't featured:

{% set featuredNewsStory = yourGlobalSetHandle.featuredNewsStory.first() %}
{% set otherNewsStories = craft.entries.section('news').id(featuredNewsStory ? 'not ' ~ featuredNewsStory.id : null) %}


Of course, there is another possible "workaround" here: continue with your current solution, but add another clause; making sure that the featured news story pulled is the newest one only:

{% set featuredNewsStory = craft.entries.section('news').featured(1).order('postDate desc').limit(1).first() %}
{% set otherNewsStories = craft.entries.section('news').id(featuredNewsStory ? 'not ' ~ featuredNewsStory.id : null) %}


With the above in place, you could just communicate to your client that "if you set more than one entry to be featured, only the newest one will actually display as featured" or the like.