diff --git a/administrator/components/com_categories/helpers/categories.php b/administrator/components/com_categories/helpers/categories.php
index 4e4d603c3411e..5f263761acf6c 100644
--- a/administrator/components/com_categories/helpers/categories.php
+++ b/administrator/components/com_categories/helpers/categories.php
@@ -137,4 +137,50 @@ public static function getAssociations($pk, $extension = 'com_content')
return $associations;
}
+
+ /**
+ * Check if Category ID exists otherwise assign to ROOT category.
+ *
+ * @param mixed $catid Name or ID of category.
+ * @param string $extension Extension that triggers this function
+ *
+ * @return int $catid Category ID.
+ */
+ public static function validateCategoryId($catid, $extension)
+ {
+ JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables');
+
+ $categoryTable = JTable::getInstance('Category');
+
+ $data = array();
+ $data['id'] = $catid;
+ $data['extension'] = $extension;
+
+ if (!$categoryTable->load($data))
+ {
+ $catid = 0;
+ }
+
+ return (int) $catid;
+ }
+
+ /**
+ * Create new Category from within item view.
+ *
+ * @param array $data Array of data for new category.
+ *
+ * @return integer.
+ */
+ public static function createCategory($data)
+ {
+ JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/models');
+ JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables');
+
+ $categoryModel = JModelLegacy::getInstance('Category', 'CategoriesModel');
+ $categoryModel->save($data);
+
+ $catid = $categoryModel->getState('category.id');
+
+ return $catid;
+ }
}
diff --git a/administrator/components/com_categories/models/fields/categoryedit.php b/administrator/components/com_categories/models/fields/categoryedit.php
index cf6f558a9d493..01db332a5a6dd 100644
--- a/administrator/components/com_categories/models/fields/categoryedit.php
+++ b/administrator/components/com_categories/models/fields/categoryedit.php
@@ -20,6 +20,14 @@
*/
class JFormFieldCategoryEdit extends JFormFieldList
{
+ /**
+ * To allow creation of new categories.
+ *
+ * @var int
+ * @since 3.6
+ */
+ protected $allowAdd;
+
/**
* A flexible category list that respects access controls
*
@@ -28,6 +36,77 @@ class JFormFieldCategoryEdit extends JFormFieldList
*/
public $type = 'CategoryEdit';
+ /**
+ * Method to attach a JForm object to the field.
+ *
+ * @param SimpleXMLElement $element The SimpleXMLElement object representing the tag for the form field object.
+ * @param mixed $value The form field value to validate.
+ * @param string $group The field name group control value. This acts as as an array container for the field.
+ * For example if the field has name="foo" and the group value is set to "bar" then the
+ * full field name would end up being "bar[foo]".
+ *
+ * @return boolean True on success.
+ *
+ * @see JFormField::setup()
+ * @since 3.2
+ */
+ public function setup(SimpleXMLElement $element, $value, $group = null)
+ {
+ $return = parent::setup($element, $value, $group);
+
+ if ($return)
+ {
+ $this->allowAdd = isset($this->element['allowAdd']) ? $this->element['allowAdd'] : '';
+ }
+
+ return $return;
+ }
+
+ /**
+ * Method to get certain otherwise inaccessible properties from the form field object.
+ *
+ * @param string $name The property name for which to the the value.
+ *
+ * @return mixed The property value or null.
+ *
+ * @since 3.6
+ */
+ public function __get($name)
+ {
+ switch ($name)
+ {
+ case 'allowAdd':
+ return $this->$name;
+ }
+
+ return parent::__get($name);
+ }
+
+ /**
+ * Method to set certain otherwise inaccessible properties of the form field object.
+ *
+ * @param string $name The property name for which to the the value.
+ * @param mixed $value The value of the property.
+ *
+ * @return void
+ *
+ * @since 3.6
+ */
+ public function __set($name, $value)
+ {
+ $value = (string) $value;
+
+ switch ($name)
+ {
+ case 'allowAdd':
+ $value = (string) $value;
+ $this->$name = ($value === 'true' || $value === $name || $value === '1');
+ break;
+ default:
+ parent::__set($name, $value);
+ }
+ }
+
/**
* Method to get a list of categories that respects access controls and can be used for
* either category assignment or parent category assignment in edit screens.
@@ -229,4 +308,85 @@ protected function getOptions()
// Merge any additional options in the XML definition.
return array_merge(parent::getOptions(), $options);
}
+
+ /**
+ * Method to get the field input markup for a generic list.
+ * Use the multiple attribute to enable multiselect.
+ *
+ * @return string The field input markup.
+ *
+ * @since 3.6
+ */
+ protected function getInput()
+ {
+ $html = array();
+ $class = array();
+ $attr = '';
+
+ // Initialize some field attributes.
+ $class[] = !empty($this->class) ? $this->class : '';
+
+ if ($this->allowAdd)
+ {
+ $customGroupText = JText::_('JGLOBAL_CUSTOM_CATEGORY');
+
+ $class[] = 'chzn-custom-value';
+ $attr .= ' data-custom_group_text="' . $customGroupText . '" '
+ . 'data-no_results_text="' . JText::_('JGLOBAL_ADD_CUSTOM_CATEGORY') . '" '
+ . 'data-placeholder="' . JText::_('JGLOBAL_TYPE_OR_SELECT_CATEGORY') . '" ';
+ }
+
+ if ($class)
+ {
+ $attr .= 'class="' . implode(' ', $class) . '"';
+ }
+
+ $attr .= !empty($this->size) ? ' size="' . $this->size . '"' : '';
+ $attr .= $this->multiple ? ' multiple' : '';
+ $attr .= $this->required ? ' required aria-required="true"' : '';
+ $attr .= $this->autofocus ? ' autofocus' : '';
+
+ // To avoid user's confusion, readonly="true" should imply disabled="true".
+ if ((string) $this->readonly == '1' || (string) $this->readonly == 'true' || (string) $this->disabled == '1'|| (string) $this->disabled == 'true')
+ {
+ $attr .= ' disabled="disabled"';
+ }
+
+ // Initialize JavaScript field attributes.
+ $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : '';
+
+ // Get the field options.
+ $options = (array) $this->getOptions();
+
+ // Create a read-only list (no name) with hidden input(s) to store the value(s).
+ if ((string) $this->readonly == '1' || (string) $this->readonly == 'true')
+ {
+ $html[] = JHtml::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $this->value, $this->id);
+
+ // E.g. form field type tag sends $this->value as array
+ if ($this->multiple && is_array($this->value))
+ {
+ if (!count($this->value))
+ {
+ $this->value[] = '';
+ }
+
+ foreach ($this->value as $value)
+ {
+ $html[] = '';
+ }
+ }
+ else
+ {
+ $html[] = '';
+ }
+ }
+ else
+ // Create a regular list.
+ {
+ $html[] = JHtml::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id);
+ }
+
+ return implode($html);
+ }
}
diff --git a/administrator/components/com_content/models/article.php b/administrator/components/com_content/models/article.php
index 75e401854f7ae..43589296b8507 100644
--- a/administrator/components/com_content/models/article.php
+++ b/administrator/components/com_content/models/article.php
@@ -487,6 +487,31 @@ public function save($data)
$data['images'] = (string) $registry;
}
+ JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php');
+
+ // Cast catid to integer for comparison
+ $catid = (int) $data['catid'];
+
+ // Check if New Category exists
+ if ($catid > 0)
+ {
+ $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_content');
+ }
+
+ // Save New Category
+ if ($catid == 0)
+ {
+ $table = array();
+ $table['title'] = $data['catid'];
+ $table['parent_id'] = 1;
+ $table['extension'] = 'com_content';
+ $table['language'] = $data['language'];
+ $table['published'] = 1;
+
+ // Create new category and get catid back
+ $data['catid'] = CategoriesHelper::createCategory($table);
+ }
+
if (isset($data['urls']) && is_array($data['urls']))
{
$check = $input->post->get('jform', array(), 'array');
diff --git a/administrator/components/com_content/models/forms/article.xml b/administrator/components/com_content/models/forms/article.xml
index 1ed973d17fd30..056ec2d6739b9 100644
--- a/administrator/components/com_content/models/forms/article.xml
+++ b/administrator/components/com_content/models/forms/article.xml
@@ -42,9 +42,13 @@
JTRASHED
-
diff --git a/administrator/components/com_content/views/article/tmpl/edit.php b/administrator/components/com_content/views/article/tmpl/edit.php
index ef414b960983d..a4d57b4df4e33 100644
--- a/administrator/components/com_content/views/article/tmpl/edit.php
+++ b/administrator/components/com_content/views/article/tmpl/edit.php
@@ -14,7 +14,7 @@
JHtml::_('behavior.formvalidator');
JHtml::_('behavior.keepalive');
-JHtml::_('formbehavior.chosen', 'select');
+JHtml::_('formbehavior.chosen', 'select', null, array('disable_search_threshold' => 0 ));
$this->configFieldsets = array('editorConfig');
$this->hiddenFieldsets = array('basic-limited');
diff --git a/administrator/language/en-GB/en-GB.ini b/administrator/language/en-GB/en-GB.ini
index 49c527a4c3005..9322082cf59b4 100644
--- a/administrator/language/en-GB/en-GB.ini
+++ b/administrator/language/en-GB/en-GB.ini
@@ -187,7 +187,7 @@ JFIELD_BASIS_LOGOUT_DESCRIPTION_DESC="Text for logout page."
JFIELD_BASIS_LOGOUT_DESCRIPTION_LABEL="Logout Description Text"
JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_DESC="Show or hide logout description."
JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_LABEL="Logout Text"
-JFIELD_CATEGORY_DESC="The category that this item is assigned to."
+JFIELD_CATEGORY_DESC="The category that this item is assigned to. You may select an existing category or enter a new category by typing the name in the field and pressing enter."
JFIELD_ENABLED_DESC="The enabled status of this item."
JFIELD_KEY_REFERENCE_DESC="Used to store information referring to an external resource."
JFIELD_KEY_REFERENCE_LABEL="Key Reference"
@@ -242,6 +242,7 @@ JFIELD_XREFERENCE_LABEL="External Reference"
JGLOBAL_ACROSS="Across"
JGLOBAL_ACTION_PERMISSIONS_LABEL="Permissions"
JGLOBAL_ACTION_PERMISSIONS_DESCRIPTION="Set the action permissions for this asset"
+JGLOBAL_ADD_CUSTOM_CATEGORY="Add new Category"
JGLOBAL_ALL_ARTICLE="Max Levels Articles"
JGLOBAL_ALL_LIST="Max Levels as List"
JGLOBAL_ALLOW_COMMENTS_DESC="If Yes, viewers will be able to add and view comments for the article."
@@ -301,6 +302,7 @@ JGLOBAL_CLICK_TO_TOGGLE_STATE="Select icon to toggle state."
JGLOBAL_COPY="(copy)"
JGLOBAL_CREATED="Created"
JGLOBAL_CREATED_DATE="Created Date"
+JGLOBAL_CUSTOM_CATEGORY="New Categories"
JGLOBAL_DATE_FORMAT_DESC="Optional format string for showing the date. If left blank, it uses DATE_FORMAT_LC1 from your language file (for example, D M Y for day month year or you can use d-m-y for a short version eg. 10-07-10. See http://www.php.net/manual/en/function.date.php)."
JGLOBAL_DATE_FORMAT_LABEL="Date Format"
JGLOBAL_DESCRIPTION="Description"
@@ -556,6 +558,7 @@ JGLOBAL_TITLE_REVERSE_ALPHABETICAL="Title Reverse Alphabetical"
JGLOBAL_TOGGLE_FEATURED="Toggle featured status."
JGLOBAL_TOP="Top"
JGLOBAL_TPL_CPANEL_LINK_TEXT="Return to Control Panel"
+JGLOBAL_TYPE_OR_SELECT_CATEGORY="Type or Select a Category"
JGLOBAL_USE_GLOBAL="Use Global"
JGLOBAL_USERNAME="Username"
JGLOBAL_VALIDATION_FORM_FAILED="Invalid form"
diff --git a/components/com_content/models/forms/article.xml b/components/com_content/models/forms/article.xml
index 7b2a5808e6b60..3708ed76454e5 100644
--- a/components/com_content/models/forms/article.xml
+++ b/components/com_content/models/forms/article.xml
@@ -98,7 +98,8 @@
label="JCATEGORY"
description="JFIELD_CATEGORY_DESC"
class="inputbox"
- required="true">
+ required="true"
+ >