getContainer()->inflector;
			$viewName      = $inflector->singularize($view->getName());
			$altViewName   = $inflector->pluralize($view->getName());
			$componentName = $view->getContainer()->componentName;
			$keys = [
				strtoupper($componentName . '_' . $viewName . '_FIELD_' . $fieldName),
				strtoupper($componentName . '_' . $altViewName . '_FIELD_' . $fieldName),
				strtoupper($componentName . '_' . $viewName . '_' . $fieldName),
				strtoupper($componentName . '_' . $altViewName . '_' . $fieldName),
			];
			foreach ($keys as $key)
			{
				if (Text::_($key) != $key)
				{
					return $key;
				}
			}
			return $keys[0];
		}
		catch (Exception $e)
		{
			return ucfirst($fieldName);
		}
	}
	/**
	 * Returns the label for a field (translated)
	 *
	 * @param   string  $fieldName  The field name
	 *
	 * @return string
	 */
	public static function fieldLabel($fieldName)
	{
		return Text::_(self::fieldLabelKey($fieldName));
	}
	/**
	 * Return a table field header which sorts the table by that field upon clicking
	 *
	 * @param   string       $field    The name of the field
	 * @param   string|null  $langKey  (optional) The language key for the header to be displayed
	 *
	 * @return  mixed
	 */
	public static function sortgrid($field, $langKey = null)
	{
		/** @var DataViewInterface $view */
		$view = self::getViewFromBacktrace();
		if (is_null($langKey))
		{
			$langKey = self::fieldLabelKey($field);
		}
		return HTMLHelper::_('FEFHelper.browse.sort', $langKey, $field, $view->getLists()->order_Dir, $view->getLists()->order, $view->getTask());
	}
	/**
	 * Create a browse view filter from values returned by a model
	 *
	 * @param   string  $localField       Field name
	 * @param   string  $modelTitleField  Foreign model field for drop-down display values
	 * @param   null    $modelName        Foreign model name
	 * @param   string  $placeholder      Placeholder for no selection
	 * @param   array   $params           Generic select display parameters
	 *
	 * @return string
	 *
	 * @since 3.3.0
	 */
	public static function modelFilter($localField, $modelTitleField = 'title', $modelName = null, $placeholder = null, array $params = [])
	{
		/** @var DataModel $model */
		$model = self::getViewFromBacktrace()->getModel();
		if (empty($modelName))
		{
			$modelName = $model->getForeignModelNameFor($localField);
		}
		if (is_null($placeholder))
		{
			$placeholder = self::fieldLabelKey($localField);
		}
		$params = array_merge([
			'list.none'      => '— ' . Text::_($placeholder) . ' —',
			'value_field'    => $modelTitleField,
			'fof.autosubmit' => true,
		], $params);
		return self::modelSelect($localField, $modelName, $model->getState($localField), $params);
	}
	/**
	 * Display a text filter (search box)
	 *
	 * @param   string  $localField   The name of the model field. Used when getting the filter state.
	 * @param   string  $searchField  The INPUT element's name. Default: "filter_$localField".
	 * @param   string  $placeholder  The JText language key for the placeholder. Default: extrapolate from $localField.
	 * @param   array   $attributes   HTML attributes for the INPUT element.
	 *
	 * @return  string
	 *
	 * @since   3.3.0
	 */
	public static function searchFilter($localField, $searchField = null, $placeholder = null, array $attributes = [])
	{
		/** @var DataModel $model */
		$view                      = self::getViewFromBacktrace();
		$model                     = $view->getModel();
		$searchField               = empty($searchField) ? $localField : $searchField;
		$placeholder               = empty($placeholder) ? self::fieldLabelKey($localField) : $placeholder;
		$attributes['type']        = $attributes['type'] ?? 'text';
		$attributes['name']        = $searchField;
		$attributes['id']          = !isset($attributes['id']) ? "filter_$localField" : $attributes['id'];
		$attributes['onchange']    = !isset($attributes['onchange']) ? 'document.adminForm.submit()' : null;
		$attributes['placeholder'] = !isset($attributes['placeholder']) ? $view->escape(Text::_($placeholder)) : $attributes['placeholder'];
		$attributes['title']       = $attributes['title'] ?? $attributes['placeholder'];
		$attributes['value']       = $view->escape($model->getState($localField));
		// Remove null attributes and collapse into a string
		$attributes = array_filter($attributes, function ($v) {
			return !is_null($v);
		});
		$attributes = ArrayHelper::toString($attributes);
		return "";
	}
	/**
	 * Create a browse view filter with dropdown values
	 *
	 * @param   string  $localField   Field name
	 * @param   array   $options      The JHtml options list to use
	 * @param   string  $placeholder  Placeholder for no selection
	 * @param   array   $params       Generic select display parameters
	 *
	 * @return string
	 *
	 * @since 3.3.0
	 */
	public static function selectFilter($localField, array $options, $placeholder = null, array $params = [])
	{
		/** @var DataModel $model */
		$model = self::getViewFromBacktrace()->getModel();
		if (is_null($placeholder))
		{
			$placeholder = self::fieldLabelKey($localField);
		}
		$params = array_merge([
			'list.none'      => '— ' . Text::_($placeholder) . ' —',
			'fof.autosubmit' => true,
		], $params);
		return self::genericSelect($localField, $options, $model->getState($localField), $params);
	}
	/**
	 * View access dropdown filter
	 *
	 * @param   string  $localField   Field name
	 * @param   string  $placeholder  Placeholder for no selection
	 * @param   array   $params       Generic select display parameters
	 *
	 * @return string
	 *
	 * @since 3.3.0
	 */
	public static function accessFilter($localField, $placeholder = null, array $params = [])
	{
		return self::selectFilter($localField, SelectOptions::getOptions('access', $params), $placeholder, $params);
	}
	/**
	 * Published state dropdown filter
	 *
	 * @param   string  $localField   Field name
	 * @param   string  $placeholder  Placeholder for no selection
	 * @param   array   $params       Generic select display parameters
	 *
	 * @return string
	 *
	 * @since 3.3.0
	 */
	public static function publishedFilter($localField, $placeholder = null, array $params = [])
	{
		return self::selectFilter($localField, SelectOptions::getOptions('published', $params), $placeholder, $params);
	}
	/**
	 * Create a select box from the values returned by a model
	 *
	 * @param   string  $name          Field name
	 * @param   string  $modelName     The name of the model, e.g. "items" or "com_foobar.items"
	 * @param   string  $currentValue  The currently selected value
	 * @param   array   $params        Passed to optionsFromModel and genericSelect
	 * @param   array   $modelState    Optional state variables to pass to the model
	 * @param   array   $options       Any JHtml select options you want to add in front of the model's returned values
	 *
	 * @return string
	 *
	 * @see   self::getOptionsFromModel
	 * @see   self::getOptionsFromSource
	 * @see   self::genericSelect
	 *
	 * @since 3.3.0
	 */
	public static function modelSelect($name, $modelName, $currentValue, array $params = [], array $modelState = [], array $options = [])
	{
		$params = array_merge([
			'fof.autosubmit' => true,
		], $params);
		$options = self::getOptionsFromModel($modelName, $params, $modelState, $options);
		return self::genericSelect($name, $options, $currentValue, $params);
	}
	/**
	 * Get a (human readable) title from a (typically numeric, foreign key) key value using the data
	 * returned by a DataModel.
	 *
	 * @param   string  $value       The key value
	 * @param   string  $modelName   The name of the model, e.g. "items" or "com_foobar.items"
	 * @param   array   $params      Passed to getOptionsFromModel
	 * @param   array   $modelState  Optional state variables to pass to the model
	 * @param   array   $options     Any JHtml select options you want to add in front of the model's returned values
	 *
	 * @return string
	 *
	 * @see   self::getOptionsFromModel
	 * @see   self::getOptionsFromSource
	 * @see   self::genericSelect
	 *
	 * @since 3.3.0
	 */
	public static function modelOptionName($value, $modelName = null, array $params = [], array $modelState = [], array $options = [])
	{
		if (!isset($params['cache']))
		{
			$params['cache'] = true;
		}
		if (!isset($params['none_as_zero']))
		{
			$params['none_as_zero'] = true;
		}
		$options = self::getOptionsFromModel($modelName, $params, $modelState, $options);
		return self::getOptionName($value, $options);
	}
	/**
	 * Gets the active option's label given an array of JHtml options
	 *
	 * @param   mixed   $selected     The currently selected value
	 * @param   array   $data         The JHtml options to parse
	 * @param   string  $optKey       Key name, default: value
	 * @param   string  $optText      Value name, default: text
	 * @param   bool    $selectFirst  Should I automatically select the first option? Default: true
	 *
	 * @return  mixed   The label of the currently selected option
	 */
	public static function getOptionName($selected, $data, $optKey = 'value', $optText = 'text', $selectFirst = true)
	{
		$ret = null;
		foreach ($data as $elementKey => &$element)
		{
			if (is_array($element))
			{
				$key  = $optKey === null ? $elementKey : $element[$optKey];
				$text = $element[$optText];
			}
			elseif (is_object($element))
			{
				$key  = $optKey === null ? $elementKey : $element->$optKey;
				$text = $element->$optText;
			}
			else
			{
				// This is a simple associative array
				$key  = $elementKey;
				$text = $element;
			}
			if (is_null($ret) && $selectFirst && ($selected == $key))
			{
				$ret = $text;
			}
			elseif ($selected == $key)
			{
				$ret = $text;
			}
		}
		return $ret;
	}
	/**
	 * Create a generic select list based on a bunch of options. Option sources will be merged into the provided
	 * options automatically.
	 *
	 * Parameters:
	 * - format.depth The current indent depth.
	 * - format.eol The end of line string, default is linefeed.
	 * - format.indent The string to use for indentation, default is tab.
	 * - groups If set, looks for keys with the value "