Skip to content

Commit

Permalink
Additional relation handling and options
Browse files Browse the repository at this point in the history
  • Loading branch information
colintucker committed Sep 6, 2017
1 parent 179ee06 commit 0d21e5d
Show file tree
Hide file tree
Showing 2 changed files with 410 additions and 10 deletions.
189 changes: 179 additions & 10 deletions src/Forms/Select2AjaxField.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Core\Convert;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\Map;
use SilverStripe\ORM\Relation;
use SilverStripe\ORM\SS_List;
use SilverStripe\View\SSViewer;
use SilverStripe\View\ViewableData;
use ArrayAccess;

/**
* An extension of the Select2 field class for a Select2 Ajax field.
Expand Down Expand Up @@ -74,6 +80,13 @@ class Select2AjaxField extends Select2Field
*/
protected $ajaxConfig;

/**
* Defines whether Ajax is enabled or disabled for the field.
*
* @var boolean
*/
protected $ajaxEnabled = true;

/**
* The data class to search via Ajax.
*
Expand Down Expand Up @@ -174,6 +187,22 @@ public function Type()
return sprintf('select2ajaxfield %s', parent::Type());
}

/**
* Defines the source for the receiver.
*
* @param array|ArrayAccess
*
* @return $this
*/
public function setSource($source)
{
if ($source instanceof DataList) {
$this->setDataClass($source->dataClass());
}

return parent::setSource($source);
}

/**
* Defines either the named Ajax config value, or the Ajax config array.
*
Expand Down Expand Up @@ -209,6 +238,30 @@ public function getAjaxConfig($name = null)
return $this->ajaxConfig;
}

/**
* Defines the value of the ajaxEnabled attribute.
*
* @param boolean $ajaxEnabled
*
* @return $this
*/
public function setAjaxEnabled($ajaxEnabled)
{
$this->ajaxEnabled = (boolean) $ajaxEnabled;

return $this;
}

/**
* Answers the value of the ajaxEnabled attribute.
*
* @return boolean
*/
public function getAjaxEnabled()
{
return $this->ajaxEnabled;
}

/**
* Defines the value of the dataClass attribute.
*
Expand Down Expand Up @@ -434,13 +487,27 @@ public function getDataAttributes()
{
$attributes = parent::getDataAttributes();

foreach ($this->getFieldAjaxConfig() as $key => $value) {
$attributes[sprintf('data-ajax--%s', $key)] = $this->getDataValue($value);
if ($this->isAjaxEnabled()) {

foreach ($this->getFieldAjaxConfig() as $key => $value) {
$attributes[sprintf('data-ajax--%s', $key)] = $this->getDataValue($value);
}

}

return $attributes;
}

/**
* Answers true if Ajax is enabled for the field.
*
* @return boolean
*/
public function isAjaxEnabled()
{
return $this->ajaxEnabled;
}

/**
* Answers an HTTP response containing JSON results matching the given search parameters.
*
Expand All @@ -458,7 +525,7 @@ public function search(HTTPRequest $request)

// Initialise:

$data = [];
$data = ['results' => []];

// Create Data List:

Expand Down Expand Up @@ -524,15 +591,77 @@ public function getSearchFilterName($field)
}

/**
* Answers the record identified by the recorded field value.
* Loads the value of the field from the given relation.
*
* @return ViewableData
* @param Relation $relation
*
* @return void
*/
public function loadFromRelation(Relation $relation)
{
parent::setValue($relation->column($this->getIDField()));
}

/**
* Saves the value of the field into the given relation.
*
* @param Relation $relation
*
* @return void
*/
public function getValueRecord()
public function saveIntoRelation(Relation $relation)
{
if ($id = $this->Value()) {
return $this->getList()->byID($id);
$relation->setByIDList(
$this->getList()->filter(
$this->getIDField(),
$this->getValueArray()
)->getIDList()
);
}

/**
* Answers true if the given data value and user value match (i.e. the value is selected).
*
* @param mixed $dataValue
* @param mixed $userValue
*
* @return boolean
*/
public function isSelectedValue($dataValue, $userValue)
{
if (is_array($userValue) && in_array($dataValue, $userValue)) {
return true;
}

return parent::isSelectedValue($dataValue, $userValue);
}

/**
* Answers the source array for the field options, including the empty string, if present.
*
* @return array
*/
public function getSourceEmpty()
{
if (!$this->isAjaxEnabled()) {
return parent::getSourceEmpty();
} elseif ($this->getHasEmptyDefault()) {
return ['' => $this->getEmptyString()];
}

return [];
}

/**
* Answers the record identified by the given value.
*
* @param mixed $id
*
* @return ViewableData
*/
protected function getValueRecord($id)
{
return $this->getList()->find($this->getIDField(), $id);
}

/**
Expand Down Expand Up @@ -604,6 +733,38 @@ protected function getFormattedSelection(ViewableData $record)
}
}

/**
* Converts the given data source into an array.
*
* @param array|ArrayAccess $source
*
* @return array
*/
protected function getListMap($source)
{
// Extract Map from ID / Text Fields:

if ($source instanceof SS_List) {
$source = $source->map($this->getIDField(), $this->getTextField());
}

// Convert Map to Array:

if ($source instanceof Map) {
$source = $source->toArray();
}

// Determine Invalid Types:

if (!is_array($source) && !($source instanceof ArrayAccess)) {
user_error('$source passed in as invalid type', E_USER_ERROR);
}

// Answer Data Source:

return $source;
}

/**
* Answers the field config for the receiver.
*
Expand All @@ -613,8 +774,16 @@ protected function getFieldConfig()
{
$config = parent::getFieldConfig();

if ($value = $this->Value()) {
$config['data'] = [$this->getResultData($this->getValueRecord(), true)];
if ($values = $this->getValueArray()) {

$data = [];

foreach ($values as $value) {
$data[] = $this->getResultData($this->getValueRecord($value), true);
}

$config['data'] = $data;

}

return $config;
Expand Down
Loading

0 comments on commit 0d21e5d

Please sign in to comment.