Add "Source" property to <Switch />

Hello,

Quite recently I found out that you can hook (bind?) multiple WhileTrue and WhileFalse blocks to a single boolean source element such as a ToggleControl, Switch or WhileTrue/WhileFalse statements by using the Source property, e.g.

<Switch ux:Name="toggleAll" /> <!-- Source -->

<WhileTrue Source="toggleAll"> <!-- Listener -->
    <Change myTitle.Color="#A00" />
</WhileTrue>
<WhileFalse Source="toggleAll"> <!-- Listener -->
    <Change mySubtitle.Color="#00E" />
</WhileFalse>

… but it is not documented! However you cannot do this with Switch, it doesn’t have that Property. If this was added then it would pretty much solve the issues of having to use Javascript to create “Select All” actions and would be easy to make complex forms that have options enabled and disabled depending on what’s been filled or selected. Here’s a theorical example:

<Text>Enable All</Text>
<Switch ux:Name="EnableAllSwitch" /> <!-- Source -->

<Text>Download Images</Text>
<Switch Source="EnableAllSwitch" /> <!-- Listener -->

<Text>Play Notifications</Text>
<Switch Source="EnableAllSwitch" /> <!-- Listener -->

<Text>Download Videos Over 4G Connection</Text>
<Switch Source="EnableAllSwitch" /> <!-- Listener -->

One switch to rule them all :wink:

While a nice idea, I’m not sure this would work quite as you intended. I’d assume that users can nonetheless enabled/disable individual swtiches regardless of the “enable all” switch. Possibly it could be locked, so when “enable all” is on, all the others are on and disabled. There are several UX options here, but I think a Source parameter would simply bind them all to the same value, which isn’t really what we want.

To create a similar behaviour you should probably create a custom dependent switch. For your switch you could add a Source property and then do whatever you’d like based on that status… let me get back with an example.

I was unable to do it without any JS intermediary (there’s a rather tricky missing feature relating to bindings). The JS is just a variable though, no logic. In the code below the master switch enables all children when on, but disables interaction until turned off again.

<App Theme="Basic" ux:Class="MyApp" ClearColor="1,1,1,1">
    <ClientPanel>
        <Switch ux:Class="DependSwitch">
            <bool ux:Property="Master"/>

            <WhileTrue Value="{Property this.Master}">
                <Change Target="this.IsEnabled" Value="false"/>
                <Set Target="this.Value" Value="true"/>
            </WhileTrue>
        </Switch>

        <JavaScript>
            var Observable = require("FuseJS/Observable")
            exports.groupOne = Observable(false)
        </JavaScript>
        <Grid Columns="auto,auto" Alignment="Center" CellSpacing="10">
            <Text>All</Text>
            <Switch Value="{groupOne}"/>

            <Text>A</Text>
            <DependSwitch Master="{groupOne}"/>

            <Text>B</Text>
            <DependSwitch Master="{groupOne}"/>

            <Text>C</Text>
            <DependSwitch Master="{groupOne}"/>

            <Text>D</Text>
            <DependSwitch Master="{groupOne}"/>
        </Grid>
    </ClientPanel>
</App>

There’s no way presently either to temporarily turn the dependent switches on while the master is on (so that when you turn it off they revert to their previous state). I tried, but something goes wrong (I’ll be filing a relevant issue for this). If you were to create your own custom display this behaviour could be possible though, since you can trigger the selected display off multiple properties.

This is a custom ToggleControl that implements the visuals of the master being on and local disabled.

        <ToggleControl ux:Class="DependSwitch" Width="50" Height="50" HitTestMode="LocalBounds">
            <bool ux:Property="Master"/>
            <Rectangle CornerRadius="5">
                <Stroke Width="2" Color="0,0,0,1"/>
            </Rectangle>

            <WhileTrue>
                <Rectangle Margin="6" CornerRadius="4" Color="0,0,0,1" ux:Name="LocalOn"/>
            </WhileTrue>
            <WhileTrue Value="{Property this.Master}">
                <Change Target="this.IsEnabled" Value="false"/>
                <Rectangle Margin="6" CornerRadius="4" Color="0.9,0.7,0.8,1"/>
                <Change LocalOn.Visibility="Hidden"/>
            </WhileTrue>
            <Tapped>
                <Toggle Target="this"/>
            </Tapped>
        </ToggleControl>

Hey Mortoray, thanks for these examples; that’s exactly what I meant by binding the values. Each value is independent but one “Source” switch (which you call Master) would override their values just like a “Select All” checkbox would.