Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Numbers field, various improvements #8

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions src/Units.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@

namespace nystudio107\units;

use nystudio107\units\fields\Units as UnitsField;
use nystudio107\units\helpers\ClassHelper;
use nystudio107\units\models\Settings;
use nystudio107\units\variables\UnitsVariable;

use Craft;
use craft\base\Plugin;
use craft\events\PluginEvent;
use craft\events\RegisterComponentTypesEvent;

use craft\services\Fields;
use craft\services\Plugins;
use craft\web\twig\variables\CraftVariable;

use yii\base\Event;
use nystudio107\units\fields\Units as UnitsField;
use nystudio107\units\helpers\ClassHelper;
use nystudio107\units\models\Settings;
use nystudio107\units\variables\UnitsVariable;

use PhpUnitsOfMeasure\PhysicalQuantity\Length;

use yii\base\Event;

/**
* Class Units
*
Expand Down Expand Up @@ -103,7 +103,7 @@ function ($event) {
$field = $event->sender;

if (!$field instanceof UnitsField) {
return;
return;
}

$object = $event->schema->createObjectType(ucfirst($field->handle) . 'Units');
Expand Down Expand Up @@ -142,12 +142,13 @@ protected function createSettingsModel()
protected function settingsHtml(): string
{
$unitsClassMap = array_flip(ClassHelper::getClassesInNamespace(Length::class));

return Craft::$app->view->renderTemplate(
'units/settings',
[
'settings' => $this->getSettings(),
'unitsClassMap' => $unitsClassMap,
]
'unitsClassMap' => $unitsClassMap,
]
);
}
}
10 changes: 6 additions & 4 deletions src/assetbundles/unitsfield/dist/css/Units.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
* @since 1.0.0
*/

.units-field-units {
margin: -20px 9px;
/* restrict to container on narrow widths */
.units-field-units-select select {
width: 100%;
}

.units-field-units-select {
margin: -16px 0px;
/* Prevent double margin and align prefix, suffix, field, and unit */
.units-field .flex:not(.flex-nowrap) > * {
margin-bottom: 0;
}
87 changes: 30 additions & 57 deletions src/fields/Units.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,30 @@

namespace nystudio107\units\fields;

use nystudio107\units\assetbundles\unitsfield\UnitsFieldAsset;
use Craft;
use craft\base\ElementInterface;
use craft\base\PreviewableFieldInterface;
use craft\fields\Number;
use craft\helpers\Json;
use craft\i18n\Locale;

use nystudio107\units\assetbundles\unitsfield\UnitsFieldAsset;
use nystudio107\units\helpers\ClassHelper;
use nystudio107\units\models\Settings;
use nystudio107\units\models\UnitsData;
use nystudio107\units\Units as UnitsPlugin;
use nystudio107\units\validators\EmbeddedUnitsDataValidator;

use Craft;
use craft\base\ElementInterface;
use craft\base\Field;
use craft\base\PreviewableFieldInterface;
use craft\helpers\Json;
use craft\i18n\Locale;
use PhpUnitsOfMeasure\PhysicalQuantity\Length;

use yii\base\InvalidConfigException;

use PhpUnitsOfMeasure\AbstractPhysicalQuantity;
use PhpUnitsOfMeasure\PhysicalQuantity\Length;

/**
* @author nystudio107
* @package Units
* @since 1.0.0
*/
class Units extends Field implements PreviewableFieldInterface
class Units extends Number implements PreviewableFieldInterface
{
// Static Methods
// =========================================================================
Expand All @@ -57,11 +55,6 @@ public static function displayName(): string
*/
public $defaultUnitsClass;

/**
* @var float The default value of the unit of measure
*/
public $defaultValue;

/**
* @var string The default units that the unit of measure is in
*/
Expand All @@ -72,26 +65,6 @@ public static function displayName(): string
*/
public $changeableUnits;

/**
* @var int|float The minimum allowed number
*/
public $min;

/**
* @var int|float|null The maximum allowed number
*/
public $max;

/**
* @var int The number of digits allowed after the decimal point
*/
public $decimals;

/**
* @var int|null The size of the field
*/
public $size;

// Public Methods
// =========================================================================

Expand All @@ -101,18 +74,26 @@ public static function displayName(): string
public function init()
{
parent::init();
/** @var Settings $settings */

if (UnitsPlugin::$plugin !== null) {
/** @var Settings $settings */
$settings = UnitsPlugin::$plugin->getSettings();

if (!empty($settings)) {
$this->defaultUnitsClass = $this->defaultUnitsClass ?? $settings->defaultUnitsClass;
$this->defaultValue = $this->defaultValue ?? $settings->defaultValue;
$this->defaultUnits = $this->defaultUnits ?? $settings->defaultUnits;
$this->changeableUnits = $this->changeableUnits ?? $settings->defaultChangeableUnits;
$this->min = $this->min ?? $settings->defaultMin;
$this->max = $this->max ?? $settings->defaultMax;
$this->decimals = $this->decimals ?? $settings->defaultDecimals;
$this->size = $this->size ?? $settings->defaultSize;

if ($this->defaultValue !== null && !$this->defaultValue) {
$this->defaultValue = $settings->defaultValue;
}

if ($this->size !== null && !$this->size) {
$this->size = $settings->defaultSize;
}
}
}
}
Expand All @@ -125,23 +106,10 @@ public function rules()
$rules = parent::rules();
$rules = array_merge($rules, [
['defaultUnitsClass', 'string'],
['defaultValue', 'number'],
['defaultUnits', 'string'],
['changeableUnits', 'boolean'],
[['min', 'max'], 'number'],
[['decimals', 'size'], 'integer'],
[
['max'],
'compare',
'compareAttribute' => 'min',
'operator' => '>=',
],
]);

if (!$this->decimals) {
$rules[] = [['min', 'max'], 'integer'];
}

return $rules;
}

Expand All @@ -150,7 +118,9 @@ public function rules()
*/
public function normalizeValue($value, ElementInterface $element = null)
{
if ($value instanceof UnitsData) {
$value = parent::normalizeValue($value, $element);

if ($value instanceof UnitsData || $value === null) {
return $value;
}
// Default config
Expand All @@ -163,16 +133,15 @@ public function normalizeValue($value, ElementInterface $element = null)
if (!empty($value)) {
// Handle a numeric value coming in (perhaps from a Number field)
if (\is_numeric($value)) {
$config['value'] = (float)$value;
$config['value'] = $value;
} elseif (\is_string($value)) {
$config = Json::decodeIfJson($value);
}
if (\is_array($value)) {
// TODO: why arrayfilter here?
$config = array_merge($config, array_filter($value));
}
}
// Typecast it to a float
$config['value'] = (float)$config['value'];
// Create and validate the model
$unitsData = new UnitsData($config);
if (!$unitsData->validate()) {
Expand All @@ -194,13 +163,17 @@ public function getSettingsHtml()
$unitsClassMap = array_flip(ClassHelper::getClassesInNamespace(Length::class));

// Render the settings template
return Craft::$app->getView()->renderTemplate(
$html = Craft::$app->getView()->renderTemplate(
'units/_components/fields/Units_settings',
[
'field' => $this,
'unitsClassMap' => $unitsClassMap,
]
);

$html .= parent::getSettingsHtml();

return $html;
}

/**
Expand Down
20 changes: 6 additions & 14 deletions src/models/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

namespace nystudio107\units\models;

use PhpUnitsOfMeasure\PhysicalQuantity\Length;

use craft\base\Model;

use PhpUnitsOfMeasure\PhysicalQuantity\Length;

/**
* @author nystudio107
* @package Units
Expand All @@ -30,9 +30,9 @@ class Settings extends Model
public $defaultUnitsClass = Length::class;

/**
* @var float The default value of the unit of measure
* @var int|float|null The default value of the unit of measure
*/
public $defaultValue = 0.0;
public $defaultValue;

/**
* @var string The default units that the unit of measure is in
Expand All @@ -57,12 +57,12 @@ class Settings extends Model
/**
* @var int The default number of digits allowed after the decimal point
*/
public $defaultDecimals = 3;
public $defaultDecimals = 0;

/**
* @var int|null The default size of the field
*/
public $defaultSize = 6;
public $defaultSize;

// Public Methods
// =========================================================================
Expand All @@ -75,25 +75,17 @@ public function rules(): array
$rules = parent::rules();
$rules = array_merge($rules, [
['defaultUnitsClass', 'string'],
['defaultUnitsClass', 'default', 'value' => Length::class],
['defaultValue', 'number'],
['defaultValue', 'default', 'value' => 0.0],
['defaultUnits', 'string'],
['defaultUnits', 'default', 'value' => 'ft'],
['defaultChangeableUnits', 'boolean'],
['defaultChangeableUnits', 'default', 'value' => true],
[['defaultMin', 'defaultMax'], 'number'],
[
['defaultMax'],
'compare',
'compareAttribute' => 'defaultMin',
'operator' => '>='
],
['defaultMin', 'default', 'value' => 0],
['defaultMax', 'default', 'value' => null],
[['defaultDecimals', 'defaultSize'], 'integer'],
['defaultDecimals', 'default', 'value' => 3],
['defaultSize', 'default', 'value' => 6],
]);

if (!$this->defaultDecimals) {
Expand Down
52 changes: 31 additions & 21 deletions src/templates/_components/fields/Units_input.twig
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,36 @@
{% do view.registerAssetBundle("nystudio107\\units\\assetbundles\\units\\UnitsAsset") %}
{% do view.registerAssetBundle("nystudio107\\units\\assetbundles\\unitsfield\\UnitsFieldAsset") %}

{{ forms.textField({
id: id ~ "value",
name: name ~ "[value]",
value: value,
size: field.size,
}) }}

{% if field.changeableUnits %}
<div class="field units-field-units-select">
{{ forms.select({
id: id ~ "units",
name: name ~ "[units]",
options: craft.units.availableUnits(model.unitsClass),
value: model.units,
}) }}
</div>
{% else %}
<div class="field units-field-units">
<div class="heading">
<p class="instructions">{{ field.defaultUnits }}</p>
<div class="flex units-field">
{% if field.prefix %}
<div>
{{ field.prefix|md(inlineOnly=true)|raw }}
</div>
{% endif %}
<div>
{{ forms.textField({
id: id ~ "value",
name: name ~ "[value]",
value: value,
size: field.size,
unit: not field.changeableUnits ? field.defaultUnits
}) }}
</div>
{% endif %}
<div>
{% if field.changeableUnits %}
<div class="field units-field-units-select">
{{ forms.select({
id: id ~ "units",
name: name ~ "[units]",
options: craft.units.availableUnits(model.unitsClass),
value: model.units,
}) }}
</div>
{% endif %}
</div>
{% if field.suffix %}
<div>
{{ field.suffix|md(inlineOnly=true)|raw }}
</div>
{% endif %}
</div>
Loading