> ## Documentation Index
> Fetch the complete documentation index at: https://help.broadstripes.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Broadstripes search language

> Broadstripes search allows you to quickly find a record or group of records using a wide variety of search criteria, including names, dates, word fragments, or even blank values. This document provides a reference list of the standard search terms available to most projects. An additional reference covers feature-specific searches that are not available in all projects.

export default function SearchOperatorsTable({section}) {
  const {useState, useEffect} = React;
  const [isDark, setIsDark] = useState(false);
  const [selectedSection, setSelectedSection] = useState(section || 'operators');
  useEffect(() => {
    const checkTheme = () => {
      const isDarkMode = document.documentElement.getAttribute('data-theme') === 'dark' || document.documentElement.classList.contains('dark') || window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
      setIsDark(isDarkMode);
    };
    checkTheme();
    const observer = new MutationObserver(checkTheme);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['data-theme', 'class']
    });
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    mediaQuery.addListener(checkTheme);
    return () => {
      observer.disconnect();
      mediaQuery.removeListener(checkTheme);
    };
  }, []);
  const handleSectionChange = newSection => {
    setSelectedSection(newSection);
    const element = document.getElementById(`section-${newSection}`);
    if (element) {
      element.scrollIntoView({
        behavior: 'smooth',
        block: 'start'
      });
    }
  };
  const colors = {
    background: isDark ? '#1f2937' : '#ffffff',
    backgroundSecondary: isDark ? '#374151' : '#f9fafb',
    backgroundTertiary: isDark ? '#d95757' : '#990000',
    textPrimary: isDark ? '#f9fafb' : '#111827',
    textSecondary: isDark ? '#d1d5db' : '#6b7280',
    textTertiary: isDark ? '#f9fafb' : '#f9fafb',
    borderColor: isDark ? '#4b5563' : '#e5e7eb'
  };
  const renderWithCode = text => {
    const parts = text.split(/(`[^`]+`)/);
    return parts.map((part, index) => {
      if (part.startsWith('`') && part.endsWith('`')) {
        const codeText = part.slice(1, -1);
        return <span key={index} className="search-code">
            {codeText}
          </span>;
      }
      return part;
    });
  };
  const searchData = {
    operators: [{
      operator: '=',
      matchingType: 'Matches whole words in any order',
      example: '`name = john` finds people named John but not Johnson'
    }, {
      operator: ':',
      matchingType: 'Matches word fragments in any order',
      example: '`name : john` finds people named John or Johnson'
    }, {
      operator: '==',
      matchingType: 'Matches word(s) exactly (but still not case sensitive)',
      example: '`name == john` finds people named john but not John'
    }, {
      operator: '!=',
      matchingType: 'Finds contacts whose records do not contain the specified words',
      example: '`name != john` excludes people named John but not Johnson'
    }, {
      operator: '!:',
      matchingType: 'Finds contacts whose records do not contain the specified word fragments',
      example: '`name !: john` excludes people named John or Johnson'
    }, {
      operator: '!==',
      matchingType: 'Finds contacts whose records do not exactly match the specified text (not case sensitive)',
      example: '`name !== john` finds people not exactly named "john"'
    }, {
      operator: '>',
      matchingType: 'Values greater-than (numbers) or after (dates)',
      example: '`CustomNumber > 50` finds contacts with a custom field over 50'
    }, {
      operator: '<',
      matchingType: 'Values less-than (numbers) or before (dates)',
      example: '`LastContact < "1 month ago"` finds people last contacted over a month ago'
    }],
    basicSearches: [{
      basic: '`carson`',
      finds: 'people or orgs with the whole word "carson" in any text field (including all contact details, notes, timeline items, and custom text fields)',
      details: ''
    }, {
      basic: '`john*`',
      finds: 'people or orgs with the word fragment "john" in any text field, e.g. "John", "Johnson", or "Johnstown"',
      details: 'The asterisk is a wildcard character (not yet supported in keyword searches)'
    }],
    generalSearches: [{
      general: '`name = parker`',
      finds: 'people and orgs with the word "parker" anywhere in their name',
      details: '',
      correlatedGroup: ''
    }, {
      general: '`first = mary`',
      finds: 'people with the word "mary" anywhere in their first name',
      details: 'first will respond to the following magic values: `any`, `none`',
      correlatedGroup: ''
    }, {
      general: '`middle : M.`',
      finds: 'people with a middle name of "M."',
      details: 'middle will respond to the following magic values: `any`, `none`',
      correlatedGroup: ''
    }, {
      general: '`last = McFly`',
      finds: 'people with the word "McFly" anywhere in their last name',
      details: 'last will respond to the following magic values: `any`, `none`',
      correlatedGroup: ''
    }, {
      general: '`id = ABC-123`',
      finds: 'people or orgs with the Broadstripes ID "ABC-123". Note: must be full ID (exact match)',
      details: '',
      correlatedGroup: ''
    }],
    contactInfo: [{
      searchTerm: '`street = "Pennsylvania Ave"`',
      finds: 'people and orgs with an address containing "Pennsylvania" and "Ave" in the Street or Street Type fields',
      details: 'Note: Addresses with the word "Avenue" spelled out would not match',
      correlatedGroup: ''
    }, {
      searchTerm: '`city = Washington`',
      finds: 'people and orgs with an address with the word "Washington" in the City field',
      details: '',
      correlatedGroup: ''
    }, {
      searchTerm: '`email = gmail.com`',
      finds: 'people and orgs with an email address which contains the text "gmail.com"',
      details: 'email will also respond to following magic values: `any`, `none`, `duplicate`, `repeated`, `error`, `home`, `other`, `personal`, `business`',
      correlatedGroup: 'Correlates with emailmod, emailopt, emailoptoutreason, emailoptinreason'
    }, {
      searchTerm: '`phone : 202`',
      finds: 'people and orgs with a phone number that contains the numbers "202"',
      details: 'Note: The ":" operator finds word or number fragments and is best for searching phone numbers. phone will also respond to following magic values: `any`, `none`, `good`, `bad`, `duplicate`, `repeated`, `error`, `home`, `other`, `personal`, `business`',
      correlatedGroup: ''
    }],
    employment: [{
      searchTerm: '`employer = none`',
      finds: 'people who have no employments',
      details: '`employer` will respond to the following magic values: `unspecified`, `any`',
      correlatedGroup: 'Correlates with `bargainingunit`, `classification`, `jobtitle`, `senioritydate`, `startdate`, `department`, `employees`, `employer`, `indirect`, `hourlyrate`, `hours`, `primary`, `tipcard`, `isprimary`, `employment`'
    }, {
      searchTerm: '`employer = "Big Shop"`',
      finds: 'people who work at "Big Shop"',
      details: '`employer` will respond to the following magic values: `unspecified`, `any`, `none`',
      correlatedGroup: 'Correlates with `bargainingunit`, `classification`, `jobtitle`, `senioritydate`, `startdate`, `department`, `employees`, `employer`, `indirect`, `hourlyrate`, `hours`, `primary`, `tipcard`, `isprimary`, `employment`'
    }, {
      searchTerm: '`employment = multiple`',
      finds: 'people who have more than one employer',
      details: '`employment` will respond to the following magic values: `none`, `any`, `multiple`, `single`',
      correlatedGroup: 'Correlates with `bargainingunit`, `classification`, `jobtitle`, `senioritydate`, `startdate`, `department`, `employees`, `employer`, `indirect`, `hourlyrate`, `hours`, `primary`, `tipcard`, `isprimary`, `employment`'
    }],
    leadership: [{
      searchTerm: '`turf = "Nell Brown"`',
      finds: 'people who are employed at any shop or department (including children of these orgs) in the turf assigned to organizer "Nell Brown"',
      details: '`turf` will respond to the following magic values: `any`, `none`, `me`',
      correlatedGroup: ''
    }, {
      searchTerm: '`leader = me`',
      finds: 'people who are led by the current user',
      details: '`leader` will respond to the following magic values: `any`, `none`, `me`',
      correlatedGroup: ''
    }, {
      searchTerm: '`covered = yes`',
      finds: 'people who are counted as covered (either they have a role with "Leaders are covered" checked, or they are led by someone whose role has "Followers are covered" checked)',
      details: '`covered` works with values: `yes`, `no`',
      correlatedGroup: ''
    }, {
      searchTerm: '`uncovered = yes`',
      finds: 'people who are not counted as covered',
      details: '`uncovered` works with values: `yes`, `no`',
      correlatedGroup: ''
    }],
    events: [{
      searchTerm: '`card = signed`',
      finds: 'people who have a check in the "Signed" step of the "Card" event',
      details: '',
      correlatedGroup: ''
    }, {
      searchTerm: '`card = any`',
      finds: 'people who have a check in either step of the "Card" event',
      details: '',
      correlatedGroup: ''
    }],
    callCenter: [{
      searchTerm: '`callpool = "Monday Grand Hotel"`',
      finds: 'people who are a part of the call pool called Monday Grand Hotel',
      details: '`callpool` will respond to the following magic values: `any`, `none`',
      correlatedGroup: 'Correlates with `callpool`, `calloutcome`, `called`, `caller`, `firstcall`, `lastcall`'
    }, {
      searchTerm: '`caller = Justin`',
      finds: 'people who have been called by a user named Justin',
      details: '`caller` will respond to the following magic values: `any`, `none`',
      correlatedGroup: 'Correlates with `callpool`, `calloutcome`, `called`, `caller`, `firstcall`, `lastcall`'
    }],
    texting: [{
      searchTerm: '`sms = delivered`',
      finds: 'people who have successfully received a text message from a user',
      details: '`sms` will respond to the following magic values: `incoming`, `outgoing`, `delivered`, `failed`',
      correlatedGroup: 'Correlates with `smsto`, `sms`, `smsfrom`, `smsdate`'
    }, {
      searchTerm: '`sms = "Howdy"`',
      finds: 'people who had a text conversation containing the word Howdy',
      details: '',
      correlatedGroup: 'Correlates with `smsto`, `sms`, `smsfrom`, `smsdate`'
    }],
    bulkEmail: [{
      searchTerm: '`emailsent = 6`',
      finds: 'people who were sent an email message using email message/template #6',
      details: '',
      correlatedGroup: ''
    }, {
      searchTerm: '`emailopened = any`',
      finds: 'people who opened any email message',
      details: '',
      correlatedGroup: ''
    }],
    communicationsPermissions: [{
      searchTerm: '`emailopt = out`',
      finds: 'people who are opted out of email contact',
      details: '`emailopt` works with the following magic values: `out`, `in`, `unspecified`',
      correlatedGroup: 'Correlates with `emailmod`, `email`, `emailoptoutreason`, `emailoptinreason`'
    }, {
      searchTerm: '`textopt = in`',
      finds: 'people opted to receive text messages',
      details: '`textopt` works with the following magic values: `out`, `in`, `unspecified`',
      correlatedGroup: 'Correlates with `textmod`, `phone`, `textoptoutreason`, `textoptinreason`'
    }]
  };
  const sectionConfig = {
    operators: {
      title: 'Search Operators',
      data: searchData.operators,
      columns: ['Operator', 'Matching type', 'Example']
    },
    basicSearches: {
      title: 'Basic Searches',
      data: searchData.basicSearches,
      columns: ['Basic', 'Finds...', 'Details']
    },
    generalSearches: {
      title: 'General Searches',
      data: searchData.generalSearches,
      columns: ['General', 'Finds...', 'Details', 'Correlated Group']
    },
    contactInfo: {
      title: 'Contact Info',
      data: searchData.contactInfo,
      columns: ['Search Term', 'Finds...', 'Details', 'Correlated Group']
    },
    employment: {
      title: 'Employment',
      data: searchData.employment,
      columns: ['Search Term', 'Finds...', 'Details', 'Correlated Group']
    },
    leadership: {
      title: 'Leadership',
      data: searchData.leadership,
      columns: ['Search Term', 'Finds...', 'Details', 'Correlated Group']
    },
    events: {
      title: 'Events',
      data: searchData.events,
      columns: ['Search Term', 'Finds...', 'Details', 'Correlated Group']
    },
    callCenter: {
      title: 'Call Center',
      data: searchData.callCenter,
      columns: ['Search Term', 'Finds...', 'Details', 'Correlated Group']
    },
    texting: {
      title: 'Texting',
      data: searchData.texting,
      columns: ['Search Term', 'Finds...', 'Details', 'Correlated Group']
    },
    bulkEmail: {
      title: 'Bulk Email',
      data: searchData.bulkEmail,
      columns: ['Search Term', 'Finds...', 'Details', 'Correlated Group']
    },
    communicationsPermissions: {
      title: 'Communications Permissions',
      data: searchData.communicationsPermissions,
      columns: ['Search Term', 'Finds...', 'Details', 'Correlated Group']
    }
  };
  const renderSection = (title, data, columns, sectionKey) => <div id={`section-${sectionKey}`} className="search-section">
      <h3 className="section-header">{title}</h3>
      <table className="search-language-table">
        <thead>
          <tr>
            {columns.map((col, index) => <th key={index}>{col}</th>)}
          </tr>
        </thead>
        <tbody>
          {data.map((item, index) => <tr key={index}>
              {Object.values(item).map((value, colIndex) => <td key={colIndex}>
                  {colIndex === 0 && title === 'Search Operators' ? <span className="operator-code">{value}</span> : renderWithCode(value)}
                </td>)}
            </tr>)}
        </tbody>
      </table>
    </div>;
  const navigationOptions = [{
    value: 'operators',
    label: 'Search Operators'
  }, {
    value: 'basicSearches',
    label: 'Basic Searches'
  }, {
    value: 'generalSearches',
    label: 'General Searches'
  }, {
    value: 'contactInfo',
    label: 'Contact Info'
  }, {
    value: 'employment',
    label: 'Employment'
  }, {
    value: 'leadership',
    label: 'Leadership'
  }, {
    value: 'events',
    label: 'Events'
  }, {
    value: 'callCenter',
    label: 'Call Center'
  }, {
    value: 'texting',
    label: 'Texting'
  }, {
    value: 'bulkEmail',
    label: 'Bulk Email'
  }, {
    value: 'communicationsPermissions',
    label: 'Communications Permissions'
  }];
  return <>
      <style jsx>{`
        .search-language-container {
          background-color: ${colors.background};
          color: ${colors.textPrimary};
          margin: auto;
          width: 100%;
          max-width: 900px;
          padding: 0;
          box-sizing: border-box;
        }

        .search-section {
          margin-bottom: 3rem;
          max-width: 100%;
          margin-left: auto;
          margin-right: auto;
          scroll-margin-top: 80px;
        }

        .section-header {
          font-size: 1.5rem;
          font-weight: 600;
          color: ${colors.textPrimary};
          margin-bottom: 1rem;
          margin-top: 0;
          padding-top: 1rem;
        }

        .search-language-table {
          width: 100%;
          border-collapse: collapse;
          font-size: 14px;
          background-color: ${colors.background};
          color: ${colors.textPrimary};
          margin-bottom: 1rem;
          table-layout: auto;
        }

        .search-language-table th,
        .search-language-table td {
          padding: 12px;
          text-align: left;
          border-bottom: 1px solid ${colors.borderColor};
          vertical-align: top;
          background-color: inherit;
          color: ${colors.textPrimary};
          white-space: normal;
          word-wrap: break-word;
        }
        
        .search-language-table th {
          background-color: ${colors.backgroundTertiary};
          font-weight: 600;
          color: ${colors.textTertiary};
          position: sticky;
          top: 0;
          z-index: 10;
          border-bottom: 2px solid #3b82f6;
          text-align: center;
          font-size: 0.9rem;
          letter-spacing: 0.5px;
        }
        
        .search-language-table tbody tr:nth-child(even) {
          background-color: ${colors.backgroundSecondary};
        }
        
        .search-language-table tbody tr:hover {
          background-color: ${colors.backgroundSecondary};
          opacity: 0.8;
        }
        
        .operator-code {
          font-family: 'Courier New', monospace;
          background-color: ${isDark ? '#4b5563' : '#e5e7eb'};
          padding: 4px 8px;
          border-radius: 4px;
          font-weight: 600;
          font-size: 14px;
        }
        
        .search-code {
          font-family: 'Courier New', monospace;
          background-color: ${isDark ? '#4b5563' : '#f3f4f6'};
          padding: 2px 4px;
          border-radius: 3px;
          font-size: 13px;
          font-weight: 600;
        }

        .section-navigation {
          margin-bottom: 1.5rem;
          display: flex;
          align-items: center;
          gap: 1rem;
        }

        .section-navigation-label {
          font-weight: 600;
          color: ${colors.textPrimary};
          font-size: 14px;
        }

        .section-dropdown {
          position: relative;
          display: inline-block;
          min-width: 250px;
        }

        .section-dropdown select {
          width: 100%;
          padding: 8px 32px 8px 12px;
          font-size: 14px;
          border: 1px solid ${colors.borderColor};
          border-radius: 6px;
          background-color: ${colors.background};
          color: ${colors.textPrimary};
          cursor: pointer;
          appearance: none;
          -webkit-appearance: none;
          -moz-appearance: none;
        }

        .section-dropdown select:hover {
          border-color: ${isDark ? '#6b7280' : '#d1d5db'};
        }

        .section-dropdown select:focus {
          outline: none;
          border-color: #3b82f6;
          box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
        }

        .section-dropdown::after {
          content: '▼';
          position: absolute;
          top: 50%;
          right: 12px;
          transform: translateY(-50%);
          pointer-events: none;
          color: ${colors.textSecondary};
          font-size: 10px;
        }
      `}</style>

      <div className="search-language-container">
        {!section && <div className="section-navigation">
            <label className="section-navigation-label" htmlFor="section-select">
              Jump to section:
            </label>
            <div className="section-dropdown">
              <select id="section-select" value={selectedSection} onChange={e => handleSectionChange(e.target.value)}>
                {navigationOptions.map(option => <option key={option.value} value={option.value}>
                    {option.label}
                  </option>)}
              </select>
            </div>
          </div>}
        {section && sectionConfig[section] ? renderSection(sectionConfig[section].title, sectionConfig[section].data, sectionConfig[section].columns, section) : Object.entries(sectionConfig).map(([key, config]) => renderSection(config.title, config.data, config.columns, key))}
      </div>
    </>;
}

<SearchOperatorsTable />
