Select to view content in your preferred language

OR Query with Radio buttons

2502
3
Jump to solution
06-14-2012 11:42 AM
TanyaOwens
Frequent Contributor
Currently I have a radio button query that works for querying one field at a time. I am trying to figure out how to make the query use "OR" to query multiple fields based on the selected radio buttons. For example I would like to query to see if a service has walker and oxygen take accommodations. Below is my current code:

C#:
            if (OxygenTank.IsChecked == true)                 query.Where = "OxygenTank = 'Oxygen Tank'";              else if (ServiceAnimal.IsChecked == true)                 query.Where = "ServiceAnimal = 'Service Animal'";              else if (Walker.IsChecked == true)                 query.Where = "Walker = 'Walker'";


XAML:
                    <RadioButton                          x:Name="OxygenTank"                         Click="RadioButton_Click"                         GroupName="SpecialNeeds"                                                      Foreground="White"                           Content="Oxygen Tank">                                              </RadioButton>                      <RadioButton                         x:Name="ServiceAnimal"                         Click="RadioButton_Click"                         GroupName="SpecialNeeds"                                                      Foreground="White"                          Content="Service Animal" >                     </RadioButton>                      <RadioButton                         x:Name="Walker"                         Click="RadioButton_Click"                         GroupName="SpecialNeeds"                                                      Foreground="White"                          Content="Walker" >                     </RadioButton>


Any words of advice?
0 Kudos
1 Solution

Accepted Solutions
JoeHershman
MVP Alum
If you want them to be able to enter multiple criteria than you do not want the query run on the click event of the check box.  You want a button in there the runs the query after all the appropriate checkboxes are selected.  If it is on the chekbox click it will run before they complete all of their selections

         <StackPanel x:Name="CheckBoxPanel" Orientation="Vertical" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="3" AllowDrop="True">             <TextBlock x:Name="QueryData"                                Text="Do you have any special needs for your trip?"                                Foreground="White"                                FontSize="20" FontWeight ="ExtraBold"                                Grid.Row="0"                                                      Margin="15,5,15,1"                                HorizontalAlignment="Center" >             </TextBlock>              <CheckBox                     x:Name="OxygenTank"                     Content="Oxygen Tank"                     Tag="OxyygenTank"/>              <CheckBox                     x:Name="ServiceAnimal"                     Content="Service Animal"                     Tag="ServiceAnimal"/>              <CheckBox                     x:Name="Walker"                     Content="Walker"                     Tag="Walker"/>              <CheckBox                     x:Name="Wheelchair"                     Content="Wheelchair"                     Tag="Wheelchair"/>             <CheckBox                     x:Name="Scooter"                     Content="Scooter"                     Tag="Scooter"/>             <Button Height="30" Width="60" Content="Search" Click="Button_Click"/>         </StackPanel> 


Also in the code in the post above, the statements are all in the form of if {} else if {} else if {}.  This means that as soon as something is found to be true (a checkbox is checked) none of the other statements are evaluated, which is definitely not the goal.  (Aside: As a general rule, else if {} is not a good construct)

Just for fun I threw in a bit of a trick that could help reduce the amount of code.  I added a Tag to each button that contains the field name.  Tag is basically a property that is on every control to have some place to put some extra info if you wanted.  Also I named the StackPanel so that it can be used in the code as a parent container of all our checkboxes

To build the Where clause a variable is introduced to hold the Where string as all the checkboxes are looked at, creatively this was named where 🙂

          private void Button_Click(object sender, RoutedEventArgs e)         {            //Setup stuff from before....              string where = null;              //This uses a foreach with a little Linq, it will look at every Child of the StackPanel and if it is a CheckBox that is Checked then go into the loop             foreach (CheckBox checkBox in CheckBoxPanel.Children.OfType<CheckBox>().Where(checkBox => checkBox.IsChecked == true))             {                 AppendWhere(ref where, checkBox);             }              query.Where = where;              queryTask.ExecuteAsync(query);         }          private void AppendWhere(ref string where, CheckBox checkBox)         {             string checkBoxQuery = checkBox.Tag + " = '" + checkBox.Content + "'";              if ( where == null )             {                 where = checkBoxQuery;             }             else             {                 where += " OR " + checkBoxQuery;             }         } 


The main part is building the Where clause in AppendWhere.  The existing where is passed in (as a reference), if it is null than no query condition has been added to the query so it just starts it out with fieldname = fieldvalue.  If the value of where is not null, that means a condition has been added and so an OR needs to be added before the next condition.

Also using the little trick with the Tag and Content properties the entire string does not need to be written out.  I am a terrible typer so believe that reducing the amount of code that needs to be written to accomplish a task is good

Good luck
Thanks,
-Joe

View solution in original post

0 Kudos
3 Replies
JoeHershman
MVP Alum
Without knowing the data model it is pretty much impossible to give specific advice on setting up queries.  The way you have things written below it seems you have an individual fields in your table called OxygenTank, ServiceAnimal, Walker.  I would think you would have one FeatureClass for your points (hospitals I am guessing) and a related table for facilities or accessibility.  But that is a data modeling exercise.

If I where setting up queries in the manner you are describing I would more likely use CheckBoxes not RadioButtons.  CheckBoxes would allow the user to choose multiple things and then query based on all those criteria, RadioButtons are choose only on of these which does not seem to be what you want.

Also make sure you are using the correct SQL clause either AND or OR.  It seems like you might want to be using AND (the facility both has oxygen tanks and allows access to service animals) as opposed to OR (the facility either has oxygen tanks, allows service animals, or both)

One way would be to setup a form with Checkboxes for the user to choose the criteria they desire and then respond to a button click and build the query based on what has been selected.

Hope that helps
-Joe
Thanks,
-Joe
0 Kudos
TanyaOwens
Frequent Contributor
I changed my code over to check box but I am still stuck with how to get the query to query more that one check box at a time. The query is for a transportation service that will find transportation in a service area that has accommodations for special needs equipment. So I am querying a polygon feature. My problem is that my code has the where separated out by if the check box is checked then it queries for that text within a separate field.  Here is some additional code:

C#:
        private void CheckBoxClick(object sender, RoutedEventArgs e)
        {
            // Query task initialization.
            QueryTask queryTask = new QueryTask("MapServer Web Address");
            queryTask.ExecuteCompleted += QueryTask_ExecuteCompleted;
            queryTask.Failed += QueryTask_Failed;

            // Query task parameters. Return geometry, state
            Query query = new Query();
            query.ReturnGeometry = true;
            query.OutFields.AddRange(new string[] { "OxygenTank", "ServiceAnimal", "Walker", "Wheelchair", "Scooter"});

            if (OxygenTank.IsChecked == true)
                query.Where = "OxygenTank = 'Oxygen Tank'";

            else if (ServiceAnimal.IsChecked == true)
                query.Where = "ServiceAnimal = 'Service Animal'";

            else if (Walker.IsChecked == true)
                query.Where = "Walker = 'Walker'";

            else if (Wheelchair.IsChecked == true)
                query.Where = "Wheelchair = 'Wheelchair'";

            else if (Scooter.IsChecked == true)
                query.Where = "Scooter = 'Scooter'";


            queryTask.ExecuteAsync(query);
        }


Xaml:
                <StackPanel Orientation="Vertical" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3" AllowDrop="True">
                    <TextBlock x:Name="QueryData" 
                               Text="Do you have any special needs for your trip?" 
                               Foreground="White" 
                               FontSize="20" FontWeight ="ExtraBold"
                               Grid.Row="0"                      
                               Margin="15,5,15,1" 
                               HorizontalAlignment="Center" >
                    </TextBlock>

                    <CheckBox 
                    x:Name="OxygenTank"
                    Click="CheckBoxClick"
                    Content="Oxygen Tank"/>

                    <CheckBox 
                    x:Name="ServiceAnimal"
                    Click="CheckBoxClick"
                    Content="Service Animal"/>

                    <CheckBox 
                    x:Name="Walker"
                    Click="CheckBoxClick"
                    Content="Walker"/>

                    <CheckBox 
                    x:Name="Wheelchair"
                    Click="CheckBoxClick"
                    Content="Wheelchair"/>

                    <CheckBox 
                    x:Name="Scooter"
                    Click="CheckBoxClick"
                    Content="Scooter"/>

                </StackPanel>
0 Kudos
JoeHershman
MVP Alum
If you want them to be able to enter multiple criteria than you do not want the query run on the click event of the check box.  You want a button in there the runs the query after all the appropriate checkboxes are selected.  If it is on the chekbox click it will run before they complete all of their selections

         <StackPanel x:Name="CheckBoxPanel" Orientation="Vertical" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="3" AllowDrop="True">             <TextBlock x:Name="QueryData"                                Text="Do you have any special needs for your trip?"                                Foreground="White"                                FontSize="20" FontWeight ="ExtraBold"                                Grid.Row="0"                                                      Margin="15,5,15,1"                                HorizontalAlignment="Center" >             </TextBlock>              <CheckBox                     x:Name="OxygenTank"                     Content="Oxygen Tank"                     Tag="OxyygenTank"/>              <CheckBox                     x:Name="ServiceAnimal"                     Content="Service Animal"                     Tag="ServiceAnimal"/>              <CheckBox                     x:Name="Walker"                     Content="Walker"                     Tag="Walker"/>              <CheckBox                     x:Name="Wheelchair"                     Content="Wheelchair"                     Tag="Wheelchair"/>             <CheckBox                     x:Name="Scooter"                     Content="Scooter"                     Tag="Scooter"/>             <Button Height="30" Width="60" Content="Search" Click="Button_Click"/>         </StackPanel> 


Also in the code in the post above, the statements are all in the form of if {} else if {} else if {}.  This means that as soon as something is found to be true (a checkbox is checked) none of the other statements are evaluated, which is definitely not the goal.  (Aside: As a general rule, else if {} is not a good construct)

Just for fun I threw in a bit of a trick that could help reduce the amount of code.  I added a Tag to each button that contains the field name.  Tag is basically a property that is on every control to have some place to put some extra info if you wanted.  Also I named the StackPanel so that it can be used in the code as a parent container of all our checkboxes

To build the Where clause a variable is introduced to hold the Where string as all the checkboxes are looked at, creatively this was named where 🙂

          private void Button_Click(object sender, RoutedEventArgs e)         {            //Setup stuff from before....              string where = null;              //This uses a foreach with a little Linq, it will look at every Child of the StackPanel and if it is a CheckBox that is Checked then go into the loop             foreach (CheckBox checkBox in CheckBoxPanel.Children.OfType<CheckBox>().Where(checkBox => checkBox.IsChecked == true))             {                 AppendWhere(ref where, checkBox);             }              query.Where = where;              queryTask.ExecuteAsync(query);         }          private void AppendWhere(ref string where, CheckBox checkBox)         {             string checkBoxQuery = checkBox.Tag + " = '" + checkBox.Content + "'";              if ( where == null )             {                 where = checkBoxQuery;             }             else             {                 where += " OR " + checkBoxQuery;             }         } 


The main part is building the Where clause in AppendWhere.  The existing where is passed in (as a reference), if it is null than no query condition has been added to the query so it just starts it out with fieldname = fieldvalue.  If the value of where is not null, that means a condition has been added and so an OR needs to be added before the next condition.

Also using the little trick with the Tag and Content properties the entire string does not need to be written out.  I am a terrible typer so believe that reducing the amount of code that needs to be written to accomplish a task is good

Good luck
Thanks,
-Joe
0 Kudos