From 6580cb84f7b11fccbc00a475f2d6c5ac818a52e6 Mon Sep 17 00:00:00 2001 From: poonam_b Date: Wed, 24 Jul 2019 17:41:46 +0530 Subject: [PATCH 01/27] Issues #149 chore: Render image in item detail view --- src/components/com_tjucm/site/views/item/tmpl/default.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/com_tjucm/site/views/item/tmpl/default.php b/src/components/com_tjucm/site/views/item/tmpl/default.php index af5260b4..56b3c8be 100644 --- a/src/components/com_tjucm/site/views/item/tmpl/default.php +++ b/src/components/com_tjucm/site/views/item/tmpl/default.php @@ -18,7 +18,7 @@ // Layout for field types $fieldLayout = array(); $fieldLayout['File'] = "file"; -$fieldLayout['Image'] = "file"; +$fieldLayout['Image'] = "image"; $fieldLayout['Checkbox'] = "checkbox"; $fieldLayout['Radio'] = "list"; $fieldLayout['List'] = "list"; @@ -190,7 +190,7 @@ authorise('core.type.deleteownitem','com_tjucm.type.' . $this->ucmTypeId)) { From 02d86946e84c88a9d3b75d9b424fd8364d069b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cankush=5Fm=E2=80=9D?= Date: Wed, 7 Aug 2019 13:04:06 +0530 Subject: [PATCH 02/27] Task #148791 feat: Impliment search filter and cluster filter on UCM items list view --- .../com_tjucm/site/models/items.php | 37 +- .../site/views/items/tmpl/default.php | 336 ++++++++++-------- 2 files changed, 209 insertions(+), 164 deletions(-) diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 08302d06..433a0c06 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -67,27 +67,19 @@ public function __construct($config = array()) * * @since 1.6 */ - protected function populateState($ordering = null, $direction = null) + protected function populateState($ordering = "a.id", $direction = "DESC") { $app = JFactory::getApplication(); $user = JFactory::getUser(); $db = JFactory::getDbo(); + // Load the filter state. + $search = $app->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'STRING'); + $this->setState('filter.search', $search); + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_tjucm/models'); $tjUcmModelType = JModelLegacy::getInstance('Type', 'TjucmModel'); - $list = $app->getUserState($this->context . '.list'); - - $ordering = isset($list['filter_order']) ? $list['filter_order'] : null; - $direction = isset($list['filter_order_Dir']) ? $list['filter_order_Dir'] : null; - - $list['limit'] = (int) JFactory::getConfig()->get('list_limit', 20); - $list['start'] = $app->input->getInt('start', 0); - $list['ordering'] = $ordering; - $list['direction'] = $direction; - - $app->setUserState($this->context . '.list', $list); - $app->input->set('list', null); $typeId = $app->input->get('id', "", "INT"); JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_tjucm/tables'); @@ -125,6 +117,13 @@ protected function populateState($ordering = null, $direction = null) $typeId = $tjUcmModelType->getTypeId($ucmType); } + $clusterId = $app->getUserStateFromRequest($this->context . '.cluster', 'cluster'); + + if ($clusterId) + { + $this->setState('filter.cluster_id', $clusterId); + } + $this->setState('ucm.client', $ucmType); $this->setState("ucmType.id", $typeId); @@ -164,7 +163,9 @@ protected function getListQuery() $query->select( $this->getState( 'list.select', 'DISTINCT ' . $db->quoteName('a.id') . ', ' - . $db->quoteName('a.state') . ', ' . $db->quoteName('a.created_by') . ',' . $group_concat + . $db->quoteName('a.state') . ', ' + . $db->quoteName('a.cluster_id') . ', ' + . $db->quoteName('a.created_by') . ',' . $group_concat ) ); @@ -248,6 +249,14 @@ protected function getListQuery() } } + // Filter by cluster + $clusterId = (int) $this->getState('filter.cluster_id'); + + if ($clusterId) + { + $query->where($db->quoteName('a.cluster_id') . ' = ' . $clusterId); + } + $query->group('fieldValue.content_id'); // Add the list ordering clause. diff --git a/src/components/com_tjucm/site/views/items/tmpl/default.php b/src/components/com_tjucm/site/views/items/tmpl/default.php index 69cbbdd4..18549c73 100644 --- a/src/components/com_tjucm/site/views/items/tmpl/default.php +++ b/src/components/com_tjucm/site/views/items/tmpl/default.php @@ -15,6 +15,8 @@ JHtml::_('behavior.multiselect'); JHtml::_('formbehavior.chosen', 'select'); +use Joomla\CMS\Component\ComponentHelper; + $user = JFactory::getUser(); $userId = $user->get('id'); $tjUcmFrontendHelper = new TjucmHelpersTjucm; @@ -37,213 +39,247 @@ $itemId = $tjUcmFrontendHelper->getItemId($link); ?>
- +
+
+ +
+
+ + +
+ showList)) + // Check if com_cluster component is installed + if (ComponentHelper::getComponent('com_cluster', true)->enabled) { - if (!empty($this->items)) - {?> -
- + JFormHelper::addFieldPath(JPATH_ADMINISTRATOR . '/components/com_tjfields/models/fields/'); + $cluster = JFormHelper::loadFieldType('cluster', false); + $this->clusterList = $cluster->getOptionsExternally(); + ?> + - clusterList, "cluster", 'class="input-medium" size="1" onchange="this.form.submit();"', "value", "text", $this->state->get('filter.cluster_id', '', 'INT')); ?> - - listcolumn)) - { - foreach ($this->listcolumn as $col_name) + + + +

+
+
- - - -
+ showList)) + { + if (!empty($this->items)) + {?> + + + items[0]->state)) { ?> - canEdit || $this->canDelete) - { ?> - - - - - - items)) - { - ?> - - - - - - - - showList)) - { - if (!empty($this->items)) - { - foreach ($this->items as $i => $item) - { - $link = JRoute::_('index.php?option=com_tjucm&view=item&id=' . $item->id . "&client=" . $this->client . '&Itemid=' . $itemId, false); + canEditOwn) + if (!empty($this->listcolumn)) { - $editown = (JFactory::getUser()->id == $item->created_by ? true : false); + foreach ($this->listcolumn as $col_name) + { + ?> + + canDeleteOwn) + if ($this->canEdit || $this->canDelete) { - $deleteOwn = (JFactory::getUser()->id == $item->created_by ? true : false); + ?> + + - - items[0]->state)) + + + + items)) + { + ?> + + + + + + + + showList)) + { + if (!empty($this->items)) + { + foreach ($this->items as $i => $item) + { + $link = JRoute::_('index.php?option=com_tjucm&view=item&id=' . $item->id . "&client=" . $this->client . '&Itemid=' . $itemId, false); + + $editown = false; + if ($this->canEditOwn) { - $class = ($this->canChange) ? 'active' : 'disabled'; ?> - + items[0]->state)) + { + $class = ($this->canChange) ? 'active' : 'disabled'; ?> + + + - - - field_values)) - { - foreach ($item->field_values as $field_values) + if (!empty($item->field_values)) { - ?> -
- + + - + +
- pagination->getListFooter(); ?> -
+ + + +
+ pagination->getListFooter(); ?> +
- + $editown = (JFactory::getUser()->id == $item->created_by ? true : false); + } + + $deleteOwn = false; + if ($this->canDeleteOwn) + { + $deleteOwn = (JFactory::getUser()->id == $item->created_by ? true : false); + } + + ?> +
+ + state == 1) + { + ?> + + state == 1) - { - ?>checked_out) && $item->checked_out) { - ?>uEditor, $item->checked_out_time, 'items.', $canCheckin); } ?> + + escape($item->id); ?> checked_out) && $item->checked_out) - { - echo JHtml::_('jgrid.checkedout', $i, $item->uEditor, $item->checked_out_time, 'items.', $canCheckin); - } - ?> - - escape($item->id); ?> - - - field_values as $field_values) { - $subFormData = json_decode($field_values); - - foreach ($subFormData as $subFormDataRow) + ?> + + - - $subFormDataColumn) + $subFormData = json_decode($field_values); + + foreach ($subFormData as $subFormDataRow) { ?> - +
' . $key . '' : ''; + foreach ($subFormDataRow as $key => $subFormDataColumn) + { + ?> + + ' . $key . '' : ''; + ?> + + - +
' . $subFormDataColumn . '
' . $subFormDataColumn . '
-
+ + + - - - + - - canEdit || $this->canDelete || $editown || $deleteOwn) - { - ?> - - canEdit || $editown) + if ($this->canEdit || $this->canDelete || $editown || $deleteOwn) { ?> - + canDelete || $deleteOwn) - { + if ($this->canEdit || $editown) + { + ?> + + canDelete || $deleteOwn) + { + ?> + + - - + - - - + + +
+ ?>
-
- - - + ?> + + + allowedToAdd) { From e4bbf30c58242e6bd673adfd46e15db20cbf174b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cankush=5Fm=E2=80=9D?= Date: Wed, 7 Aug 2019 17:21:41 +0530 Subject: [PATCH 03/27] Task #148791 feat: Impliment search filter and cluster filter on UCM items list view --- .../com_tjucm/site/models/items.php | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 433a0c06..460d6e71 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -50,6 +50,9 @@ public function __construct($config = array()) $this->fields_separator = "#:"; $this->records_separator = "#=>"; + // Load fields model + JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); + parent::__construct($config); } @@ -239,13 +242,50 @@ protected function getListQuery() if (!empty($search)) { + $search = $db->escape(trim($search), true); + if (stripos($search, 'id:') === 0) { - $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + $query->where($db->quoteName('a.id') . ' = ' . (int) $search); } else { - $search = $db->quote('%' . $db->escape($search, true) . '%'); + $fields = $this->getFields(); + $filterFieldFound = 0; + $searchString = ''; + + if (!empty($fields)) + { + $fieldCount = 0; + + foreach ($fields as $fieldId => $field) + { + $fieldCount++; + $searchString .= $db->quoteName('field_values') . ' LIKE ' . $db->q('%' . $fieldId . '#:' . $search . '%'); + + if ($fieldCount < count($fields)) + { + $searchString .= ' OR '; + } + + if (stripos($search, $field . ':') === 0) + { + $search = trim(str_replace($field . ':', '', $search)); + $query->having($db->quoteName('field_values') . ' LIKE ' . $db->q('%' . $fieldId . '#:' . $search . '%')); + $filterFieldFound = 1; + + break; + } + } + } + + if ($filterFieldFound == 0) + { + $query->having($searchString); + } + + //$search = $db->quote('%' . str_replace(' ', '%', $search . '%')); + //$query->having('field_values LIKE ' . $db->q('%85#:film19%') . ' OR ' . 'field_values LIKE ' . $db->q('%87#:film19%')); } } @@ -278,7 +318,6 @@ protected function getListQuery() */ public function getFields() { - JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); $items_model = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request'=> true)); $items_model->setState('filter.showonlist', 1); $items_model->setState('filter.state', 1); From 171fa57c435716498a8c5d5e100aedeba0f8f7e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cankush=5Fm=E2=80=9D?= Date: Wed, 7 Aug 2019 18:30:49 +0530 Subject: [PATCH 04/27] Task #148791 feat: Impliment search filter and cluster filter on UCM items list view --- .../com_tjucm/languages/site/en-GB/en-GB.com_tjucm.ini | 1 + src/components/com_tjucm/site/models/items.php | 5 ++--- .../com_tjucm/site/views/items/tmpl/default.php | 8 ++++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/com_tjucm/languages/site/en-GB/en-GB.com_tjucm.ini b/src/components/com_tjucm/languages/site/en-GB/en-GB.com_tjucm.ini index 9fe52daa..2b0bf53b 100644 --- a/src/components/com_tjucm/languages/site/en-GB/en-GB.com_tjucm.ini +++ b/src/components/com_tjucm/languages/site/en-GB/en-GB.com_tjucm.ini @@ -11,6 +11,7 @@ COM_TJUCM_DELETE_MESSAGE="Are you sure that you want delete this item?" COM_TJUCM_PUBLISH_ITEM="Publish" COM_TJUCM_UNPUBLISH_ITEM="Unpublish" COM_TJUCM_NO_ITEMS="There are no items in the list" +COM_TJUCM_ITEMS_SEARCH_TITLE="Prefix with 'Column Title:' to search records matching the value in the specified column eg. %s:xyz" COM_TJUCM_SEARCH_TOOLS="Search Tools" COM_TJUCM_SEARCH_TOOLS_DESC="" COM_TJUCM_SEARCH_FILTER_SUBMIT="Search" diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 460d6e71..1ae0994f 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -268,6 +268,7 @@ protected function getListQuery() $searchString .= ' OR '; } + // For field specific search if (stripos($search, $field . ':') === 0) { $search = trim(str_replace($field . ':', '', $search)); @@ -279,13 +280,11 @@ protected function getListQuery() } } + // For generic search if ($filterFieldFound == 0) { $query->having($searchString); } - - //$search = $db->quote('%' . str_replace(' ', '%', $search . '%')); - //$query->having('field_values LIKE ' . $db->q('%85#:film19%') . ' OR ' . 'field_values LIKE ' . $db->q('%87#:film19%')); } } diff --git a/src/components/com_tjucm/site/views/items/tmpl/default.php b/src/components/com_tjucm/site/views/items/tmpl/default.php index 18549c73..9b4829a1 100644 --- a/src/components/com_tjucm/site/views/items/tmpl/default.php +++ b/src/components/com_tjucm/site/views/items/tmpl/default.php @@ -35,6 +35,10 @@ $appendUrl .= "&client=" . $this->client; } +$tmpListColumn = $this->listcolumn; +reset($tmpListColumn); +$firstListColumn = key($tmpListColumn); + $link = 'index.php?option=com_tjucm&view=items' . $appendUrl; $itemId = $tjUcmFrontendHelper->getItemId($link); ?> @@ -42,9 +46,9 @@
+ placeholder=""/>
From 6ec15f29d481c78e15ea6321486ed164d13a9160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cankush=5Fm=E2=80=9D?= Date: Mon, 12 Aug 2019 18:36:47 +0530 Subject: [PATCH 05/27] Task #148791 feat: Impliment search filter and cluster filter on UCM items list view --- src/components/com_tjucm/site/models/itemform.php | 6 ++++++ src/components/com_tjucm/site/models/items.php | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/com_tjucm/site/models/itemform.php b/src/components/com_tjucm/site/models/itemform.php index fef4e9f4..e70cc2b7 100644 --- a/src/components/com_tjucm/site/models/itemform.php +++ b/src/components/com_tjucm/site/models/itemform.php @@ -669,6 +669,12 @@ public function delete($contentId) $id = (!empty($contentId)) ? $contentId : (int) $this->getState('item.id'); $table = $this->getTable(); + // Do not allow to delete if id is passes as empty + if (empty($id)) + { + return false; + } + // If there are child records then delete child records first $db = JFactory::getDbo(); $query = $db->getQuery(true); diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 1ae0994f..6f224930 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -261,7 +261,7 @@ protected function getListQuery() foreach ($fields as $fieldId => $field) { $fieldCount++; - $searchString .= $db->quoteName('field_values') . ' LIKE ' . $db->q('%' . $fieldId . '#:' . $search . '%'); + $searchString .= $db->quoteName('field_values') . ' LIKE ' . $db->q('%' . $fieldId . '#:%' . $search . '%'); if ($fieldCount < count($fields)) { @@ -272,7 +272,7 @@ protected function getListQuery() if (stripos($search, $field . ':') === 0) { $search = trim(str_replace($field . ':', '', $search)); - $query->having($db->quoteName('field_values') . ' LIKE ' . $db->q('%' . $fieldId . '#:' . $search . '%')); + $query->having($db->quoteName('field_values') . ' LIKE ' . $db->q('%' . $fieldId . '#:%' . $search . '%')); $filterFieldFound = 1; break; From 81d80f015fb5e44c8d522ea5080a79caae6a24de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cankush=5Fm=E2=80=9D?= Date: Wed, 14 Aug 2019 19:39:15 +0530 Subject: [PATCH 06/27] Task #166 feat: Cluster Filters on UCM list view --- .../com_tjucm/site/models/items.php | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 6f224930..338a6478 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -12,6 +12,8 @@ jimport('joomla.application.component.modellist'); +use Joomla\CMS\Component\ComponentHelper; + /** * Methods supporting a list of Tjucm records. * @@ -181,7 +183,7 @@ protected function getListQuery() // Join over the foreign key 'type_id' $query->join("INNER", $db->quoteName('#__tj_ucm_types', 'types') . ' ON (' . $db->quoteName('types.id') . ' = ' . $db->quoteName('a.type_id') . ')'); - $query->where('(' . $db->quoteName('types.state') . ' IN (1))'); + $query->where('(' . $db->quoteName('types.state') . ' = 1)'); // Join over the user field 'created_by' @@ -225,6 +227,38 @@ protected function getListQuery() $query->where($db->quoteName('a.created_by') . ' = ' . (INT) $createdBy); } + // Show records belonging to users cluster if com_cluster is installed and enabled - start + $clusterExist = ComponentHelper::getComponent('com_cluster', true)->enabled; + + if ($clusterExist) + { + JLoader::import('components.com_tjfields.table.field', JPATH_ADMINISTRATOR); + $fieldTable = JTable::getInstance('Field', 'TjfieldsTable', array('dbo', $db)); + $fieldTable->load(array('client' => $this->client, 'type' => 'cluster')); + + if ($fieldTable->id) + { + JFormHelper::addFieldPath(JPATH_ADMINISTRATOR . '/components/com_tjfields/models/fields/'); + $cluster = JFormHelper::loadFieldType('cluster', false); + $clusterList = $cluster->getOptionsExternally(); + + if (!empty($clusterList)) + { + $usersClusters = array(); + + foreach ($clusterList as $clusterList) + { + if (!empty($clusterList->value)) + { + $usersClusters[] = $clusterList->value; + } + } + } + + $query->where($db->quoteName('a.cluster_id') . ' IN (' . implode(",", $usersClusters) . ')'); + } + } + // Filter by published state $published = $this->getState('filter.state'); From aff783c4d256cb1c6e77cba15ed7fe0d07275541 Mon Sep 17 00:00:00 2001 From: Pravin_s Date: Mon, 19 Aug 2019 15:46:46 +0530 Subject: [PATCH 07/27] Task #149211 chore: Resolve PHPCS issues --- src/components/com_tjucm/site/models/itemform.php | 1 + src/components/com_tjucm/site/models/items.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/com_tjucm/site/models/itemform.php b/src/components/com_tjucm/site/models/itemform.php index e70cc2b7..16530e5b 100644 --- a/src/components/com_tjucm/site/models/itemform.php +++ b/src/components/com_tjucm/site/models/itemform.php @@ -659,6 +659,7 @@ public function delete($contentId) $canDeleteown = $user->authorise('core.type.deleteownitem', 'com_tjucm.type.' . $table->type_id); $deleteOwn = false; + if ($canDeleteown) { $deleteOwn = (JFactory::getUser()->id == $table->created_by ? true : false); diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 338a6478..971c51d0 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -302,7 +302,7 @@ protected function getListQuery() $searchString .= ' OR '; } - // For field specific search + // For field specific search if (stripos($search, $field . ':') === 0) { $search = trim(str_replace($field . ':', '', $search)); @@ -351,7 +351,7 @@ protected function getListQuery() */ public function getFields() { - $items_model = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request'=> true)); + $items_model = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request' => true)); $items_model->setState('filter.showonlist', 1); $items_model->setState('filter.state', 1); $this->client = $this->getState('ucm.client'); From 5cd9b3270e0ff75772857662f230de33973dc1bf Mon Sep 17 00:00:00 2001 From: ankush-maherwal Date: Mon, 19 Aug 2019 17:43:47 +0530 Subject: [PATCH 08/27] Bug #172 fix: List view not loading if there are large number of records added in a UCM type --- .../com_tjucm/site/models/items.php | 103 ++++++++---------- 1 file changed, 44 insertions(+), 59 deletions(-) diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 338a6478..46f40daf 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -159,18 +159,13 @@ protected function getListQuery() $db = $this->getDbo(); $query = $db->getQuery(true); - $group_concat = 'GROUP_CONCAT(CONCAT_WS("' . $this->fields_separator . '", - ' . $db->quoteName('fields.id') . ',' . $db->quoteName('fieldValue.value') . ')'; - - $group_concat .= 'SEPARATOR "' . $this->records_separator . '") AS field_values'; - // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'DISTINCT ' . $db->quoteName('a.id') . ', ' . $db->quoteName('a.state') . ', ' . $db->quoteName('a.cluster_id') . ', ' - . $db->quoteName('a.created_by') . ',' . $group_concat + . $db->quoteName('a.created_by') ) ); @@ -185,25 +180,6 @@ protected function getListQuery() ' ON (' . $db->quoteName('types.id') . ' = ' . $db->quoteName('a.type_id') . ')'); $query->where('(' . $db->quoteName('types.state') . ' = 1)'); - // Join over the user field 'created_by' - - $query->select($db->quoteName('ucby.name', 'created_by_name')); - $query->join("INNER", $db->quoteName('#__users', 'ucby') . ' ON (' . $db->quoteName('ucby.id') . - ' = ' . $db->quoteName('a.created_by') . ')'); - - // Join over the user field 'modified_by' - $query->select($db->quoteName('um.name', 'modified_by_name')); - $query->join("LEFT", $db->quoteName('#__users', 'um') . - ' ON (' . $db->quoteName('um.id') . ' = ' . $db->quoteName('a.modified_by') . ')'); - - // Join over the tjfield - $query->join("INNER", $db->quoteName('#__tjfields_fields', 'fields') . - ' ON (' . $db->quoteName('fields.client') . ' = ' . $db->quoteName('a.client') . ')'); - - // Join over the tjfield value - $query->join("INNER", $db->quoteName('#__tjfields_fields_value', 'fieldValue') . - ' ON (' . $db->quoteName('fieldValue.content_id') . ' = ' . $db->quoteName('a.id') . ')'); - $this->client = $this->getState('ucm.client'); if (!empty($this->client)) @@ -211,8 +187,6 @@ protected function getListQuery() $query->where($db->quoteName('a.client') . ' = ' . $db->quote($db->escape($this->client))); } - $query->where($db->quoteName('fields.id') . ' = ' . $db->quoteName('fieldValue.field_id')); - $ucmType = $this->getState('ucmType.id', '', 'INT'); if (!empty($ucmType)) @@ -330,8 +304,6 @@ protected function getListQuery() $query->where($db->quoteName('a.cluster_id') . ' = ' . $clusterId); } - $query->group('fieldValue.content_id'); - // Add the list ordering clause. $orderCol = $this->state->get('list.ordering'); $orderDirn = $this->state->get('list.direction'); @@ -403,51 +375,64 @@ public function getItems() } $items = parent::getItems(); + $itemsArray = (array) $items; + $contentIds = array_column($itemsArray, 'id'); + $fieldValues = $this->getFieldsData($contentIds); - foreach ($items as $item) + foreach ($items as &$item) { - if (!empty($item->field_values)) - { - $explode_field_values = explode($this->records_separator, $item->field_values); - - $colValue = array(); + $item->field_values = array(); - foreach ($explode_field_values as $field_values) + foreach ($fieldValues as $key => &$fieldValue) + { + if ($item->id == $fieldValue->content_id) { - $explode_explode_field_values = explode($this->fields_separator, $field_values); - - $fieldId = $explode_explode_field_values[0]; - $fieldValue = $explode_explode_field_values[1]; - - $colValue[$fieldId] = $fieldValue; + $item->field_values[$fieldValue->field_id] = $fieldValue->value; + unset($fieldValues[$key]); } + } + } - $listcolumns = $this->getFields(); - - if (!empty($listcolumns)) - { - $fieldData = array(); + $listcolumns = $this->getFields(); - foreach ($listcolumns as $col_id => $col_name) - { - if (array_key_exists($col_id, $colValue)) - { - $fieldData[$col_id] = $colValue[$col_id]; - } - else - { - $fieldData[$col_id] = ""; - } + foreach ($items as &$item) + { + $fieldValues = array(); - $item->field_values = $fieldData; - } + foreach ($listcolumns as $fieldId => $fieldValue) + { + if (!array_key_exists($fieldId, $item->field_values)) + { + $fieldValues[$fieldId] = ""; + } + else + { + $fieldValues[$fieldId] = $item->field_values[$fieldId]; } } + + $item->field_values = $fieldValues; } return $items; } + private function getFieldsData($contentIds) + { + $contentIds = implode(',', $contentIds); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('*'); + $query->from($db->quoteName('#__tjfields_fields_value', 'fv')); + $query->join('INNER', $db->qn('#__tjfields_fields', 'f') . ' ON (' . $db->qn('f.id') . ' = ' . $db->qn('fv.field_id') . ')'); + $query->where($db->qn('f.state') . '=1'); + $query->where($db->qn('fv.content_id') . ' IN (' . $contentIds . ')'); + $db->setQuery($query); + + return $db->loadObjectList(); + } + /** * Overrides the default function to check Date fields format, identified by * "_dateformat" suffix, and erases the field if it's not correct. From f8f864c90ce04c6195e40acf2ffacabdcb4b33a9 Mon Sep 17 00:00:00 2001 From: Pravin_s Date: Mon, 19 Aug 2019 18:15:35 +0530 Subject: [PATCH 09/27] Issue#173 fix: resolve fatal error --- src/components/com_tjucm/site/models/items.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 971c51d0..e3c34f84 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -232,7 +232,7 @@ protected function getListQuery() if ($clusterExist) { - JLoader::import('components.com_tjfields.table.field', JPATH_ADMINISTRATOR); + JLoader::import('components.com_tjfields.tables.field', JPATH_ADMINISTRATOR); $fieldTable = JTable::getInstance('Field', 'TjfieldsTable', array('dbo', $db)); $fieldTable->load(array('client' => $this->client, 'type' => 'cluster')); From 9a24a1d86ef31207d7c17d3e7d0757cac0828a79 Mon Sep 17 00:00:00 2001 From: ankush-maherwal Date: Tue, 20 Aug 2019 15:16:48 +0530 Subject: [PATCH 10/27] Bug #172 fix: List view not loading if there are large number of records added in a UCM type --- .../com_tjucm/site/models/items.php | 154 +++++++++++------- 1 file changed, 92 insertions(+), 62 deletions(-) diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 46f40daf..e2cd1b81 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -36,25 +36,16 @@ public function __construct($config = array()) if (empty($config['filter_fields'])) { $config['filter_fields'] = array( - 'id', 'a.id', - 'ordering', 'a.ordering', - 'state', 'a.state', - 'type_id', 'a.type_id', - 'created_by', 'a.created_by', - 'created_date', 'a.created_date', - 'modified_by', 'a.modified_by', - 'modified_date', 'a.modified_date', + 'id', + 'state', + 'type_id', + 'created_by', + 'created_date', + 'modified_by', + 'modified_date', ); } - $this->loginuserid = JFactory::getUser()->id; - - $this->fields_separator = "#:"; - $this->records_separator = "#=>"; - - // Load fields model - JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); - parent::__construct($config); } @@ -155,6 +146,8 @@ protected function populateState($ordering = "a.id", $direction = "DESC") */ protected function getListQuery() { + $this->fields = $this->getFields(); + // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); @@ -178,7 +171,7 @@ protected function getListQuery() // Join over the foreign key 'type_id' $query->join("INNER", $db->quoteName('#__tj_ucm_types', 'types') . ' ON (' . $db->quoteName('types.id') . ' = ' . $db->quoteName('a.type_id') . ')'); - $query->where('(' . $db->quoteName('types.state') . ' = 1)'); + $query->where($db->quoteName('types.state') . ' = 1'); $this->client = $this->getState('ucm.client'); @@ -254,46 +247,18 @@ protected function getListQuery() if (stripos($search, 'id:') === 0) { - $query->where($db->quoteName('a.id') . ' = ' . (int) $search); + $this->setState('filter.search', ''); + $query->where($db->quoteName('a.id') . ' = ' . (int) str_replace('id:', '', $search)); } - else - { - $fields = $this->getFields(); - $filterFieldFound = 0; - $searchString = ''; - - if (!empty($fields)) - { - $fieldCount = 0; - - foreach ($fields as $fieldId => $field) - { - $fieldCount++; - $searchString .= $db->quoteName('field_values') . ' LIKE ' . $db->q('%' . $fieldId . '#:%' . $search . '%'); - - if ($fieldCount < count($fields)) - { - $searchString .= ' OR '; - } - - // For field specific search - if (stripos($search, $field . ':') === 0) - { - $search = trim(str_replace($field . ':', '', $search)); - $query->having($db->quoteName('field_values') . ' LIKE ' . $db->q('%' . $fieldId . '#:%' . $search . '%')); - $filterFieldFound = 1; + } - break; - } - } - } + // Search on fields data + $filteredItemIds = $this->filterContent(); - // For generic search - if ($filterFieldFound == 0) - { - $query->having($searchString); - } - } + if (!empty($filteredItemIds)) + { + $filteredItemIds = implode(',', $filteredItemIds); + $query->where($db->quoteName('a.id') . ' IN (' . $filteredItemIds . ')'); } // Filter by cluster @@ -316,6 +281,57 @@ protected function getListQuery() return $query; } + /** + * Function to filter content as per field values + * + * @return Array Content Ids + * + * @since 1.2.1 + */ + private function filterContent() + { + $filterFieldFound = 0; + + // Apply search filter + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('content_id'); + $query->from($db->quoteName('#__tjfields_fields_value', 'fv')); + $query->join('INNER', $db->qn('#__tjfields_fields', 'f') . ' ON (' . $db->qn('fv.field_id') . ' = ' . $db->qn('f.id') . ')'); + $query->where($db->quoteName('f.state') . ' =1'); + $query->where($db->quoteName('f.client') . ' = ' . $db->quote($this->client)); + + // Filter by field value + $search = $this->getState('filter.search'); + + if (!empty($this->fields)) + { + foreach ($this->fields as $fieldId => $field) + { + // For field specific search + if (stripos($search, $field . ':') === 0) + { + $search = trim(str_replace($field . ':', '', $search)); + $query->where($db->qn('fv.field_id') . ' = ' . $fieldId); + $query->where($db->qn('fv.value') . ' LIKE ' . $db->q('%' . $search . '%')); + $filterFieldFound = 1; + + break; + } + } + } + + // For generic search + if ($filterFieldFound == 0 && !empty($search)) + { + $query->where($db->quoteName('fv.value') . ' LIKE ' . $db->q('%' . $search . '%')); + } + + $db->setQuery($query); + + return $db->loadColumn(); + } + /** * Get an array of data items * @@ -323,17 +339,19 @@ protected function getListQuery() */ public function getFields() { - $items_model = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request'=> true)); - $items_model->setState('filter.showonlist', 1); - $items_model->setState('filter.state', 1); + // Load fields model + JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); + $fieldsModel = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request'=> true)); + $fieldsModel->setState('filter.showonlist', 1); + $fieldsModel->setState('filter.state', 1); $this->client = $this->getState('ucm.client'); if (!empty($this->client)) { - $items_model->setState('filter.client', $this->client); + $fieldsModel->setState('filter.client', $this->client); } - $items = $items_model->getItems(); + $items = $fieldsModel->getItems(); $data = array(); @@ -393,13 +411,11 @@ public function getItems() } } - $listcolumns = $this->getFields(); - foreach ($items as &$item) { $fieldValues = array(); - foreach ($listcolumns as $fieldId => $fieldValue) + foreach ($this->fields as $fieldId => $fieldValue) { if (!array_key_exists($fieldId, $item->field_values)) { @@ -417,10 +433,24 @@ public function getItems() return $items; } + /** + * Method to fields data for given content Ids + * + * @param array $contentIds An array of record ids. + * + * @return ARRAY Fields data if successful, false if an error occurs. + * + * @since 1.2.1 + */ private function getFieldsData($contentIds) { $contentIds = implode(',', $contentIds); + if (empty($contentIds)) + { + return fasle; + } + $db = JFactory::getDbo(); $query = $db->getQuery(true); $query->select('*'); From 76bb26a16e929cf4397cd4b4a5e9c361b2ef5d1a Mon Sep 17 00:00:00 2001 From: ankush-maherwal Date: Tue, 20 Aug 2019 15:47:00 +0530 Subject: [PATCH 11/27] Bug #172 fix: List view not loading if there are large number of records added in a UCM type --- .../com_tjucm/site/views/items/tmpl/default.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/components/com_tjucm/site/views/items/tmpl/default.php b/src/components/com_tjucm/site/views/items/tmpl/default.php index 9b4829a1..c89be1cf 100644 --- a/src/components/com_tjucm/site/views/items/tmpl/default.php +++ b/src/components/com_tjucm/site/views/items/tmpl/default.php @@ -147,8 +147,6 @@ { foreach ($this->items as $i => $item) { - $link = JRoute::_('index.php?option=com_tjucm&view=item&id=' . $item->id . "&client=" . $this->client . '&Itemid=' . $itemId, false); - $editown = false; if ($this->canEditOwn) { @@ -229,11 +227,7 @@ } else { - ?> - - - - From 01c4e9215e600c57c7acd04d04c518ebdcfdf3ab Mon Sep 17 00:00:00 2001 From: ankush-maherwal Date: Tue, 20 Aug 2019 16:55:41 +0530 Subject: [PATCH 12/27] Bug #172 fix: List view not loading if there are large number of records added in a UCM type --- .../com_tjucm/site/layouts/detail/fields.php | 1 + .../site/views/items/tmpl/default.php | 26 ++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/components/com_tjucm/site/layouts/detail/fields.php b/src/components/com_tjucm/site/layouts/detail/fields.php index fe5b0f90..379b904d 100644 --- a/src/components/com_tjucm/site/layouts/detail/fields.php +++ b/src/components/com_tjucm/site/layouts/detail/fields.php @@ -26,6 +26,7 @@ $fieldLayout['Itemcategory'] = "itemcategory"; $fieldLayout['Video'] = $fieldLayout['Audio'] = $fieldLayout['Url'] = "link"; $fieldLayout['Calendar'] = "calendar"; +$fieldLayout['Cluster'] = "cluster"; // Load the tj-fields helper JLoader::import('components.com_tjfields.helpers.tjfields', JPATH_SITE); diff --git a/src/components/com_tjucm/site/views/items/tmpl/default.php b/src/components/com_tjucm/site/views/items/tmpl/default.php index c89be1cf..d5d54dad 100644 --- a/src/components/com_tjucm/site/views/items/tmpl/default.php +++ b/src/components/com_tjucm/site/views/items/tmpl/default.php @@ -61,16 +61,24 @@ // Check if com_cluster component is installed if (ComponentHelper::getComponent('com_cluster', true)->enabled) { - JFormHelper::addFieldPath(JPATH_ADMINISTRATOR . '/components/com_tjfields/models/fields/'); - $cluster = JFormHelper::loadFieldType('cluster', false); - $this->clusterList = $cluster->getOptionsExternally(); - ?> - - + clusterList, "cluster", 'class="input-medium" size="1" onchange="this.form.submit();"', "value", "text", $this->state->get('filter.cluster_id', '', 'INT')); + ?> +
+
From 83a8a3867d4ca731e45e7a07e8a3d812112d1c09 Mon Sep 17 00:00:00 2001 From: ankush-maherwal Date: Wed, 21 Aug 2019 18:02:36 +0530 Subject: [PATCH 13/27] Task #166 feat: Cluster Filters on UCM list view --- src/components/com_tjucm/site/models/itemform.php | 13 ++++++++++++- src/components/com_tjucm/site/models/items.php | 2 +- .../com_tjucm/site/views/items/tmpl/default.php | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/components/com_tjucm/site/models/itemform.php b/src/components/com_tjucm/site/models/itemform.php index e70cc2b7..af58ca8b 100644 --- a/src/components/com_tjucm/site/models/itemform.php +++ b/src/components/com_tjucm/site/models/itemform.php @@ -457,7 +457,18 @@ public function save($data, $extra_jform_data = '') $itemDetails = Table::getInstance('Item', 'TjucmTable'); $itemDetails->load(array('id' => $typeItemId)); - $data['created_by'] = $itemDetails->created_by; + // If there is ownership field in form and the field is assigned some value then update created_by for the record + $client = explode(".", $itemDetails->client); + $createdByField = $client[0] . '_' . $client[1] . '_ownershipcreatedby'; + + if (isset($extra_jform_data[$createdByField]) && !empty($extra_jform_data[$createdByField])) + { + $data['created_by'] = $extra_jform_data[$createdByField]; + } + else + { + $data['created_by'] = $itemDetails->created_by; + } if ($canEdit) { diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index e2cd1b81..20d1c05f 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -199,7 +199,7 @@ protected function getListQuery() if ($clusterExist) { - JLoader::import('components.com_tjfields.table.field', JPATH_ADMINISTRATOR); + JLoader::import('components.com_tjfields.tables.field', JPATH_ADMINISTRATOR); $fieldTable = JTable::getInstance('Field', 'TjfieldsTable', array('dbo', $db)); $fieldTable->load(array('client' => $this->client, 'type' => 'cluster')); diff --git a/src/components/com_tjucm/site/views/items/tmpl/default.php b/src/components/com_tjucm/site/views/items/tmpl/default.php index d5d54dad..5970e993 100644 --- a/src/components/com_tjucm/site/views/items/tmpl/default.php +++ b/src/components/com_tjucm/site/views/items/tmpl/default.php @@ -62,7 +62,7 @@ if (ComponentHelper::getComponent('com_cluster', true)->enabled) { - JLoader::import('components.com_tjfields.table.field', JPATH_ADMINISTRATOR); + JLoader::import('components.com_tjfields.tables.field', JPATH_ADMINISTRATOR); $fieldTable = JTable::getInstance('Field', 'TjfieldsTable', array('dbo', $db)); $fieldTable->load(array('client' => $this->client, 'type' => 'cluster')); From 043536946e1495c0719dac46813f065a413cba8c Mon Sep 17 00:00:00 2001 From: ankush-maherwal Date: Fri, 23 Aug 2019 11:54:20 +0530 Subject: [PATCH 14/27] Bug #172 fix: List view not loading if there are large number of records added in a UCM type --- .../com_tjucm/site/models/itemform.php | 1 + .../com_tjucm/site/models/items.php | 91 ++++++++++++++++--- .../site/views/items/tmpl/default.php | 43 +-------- .../site/views/items/tmpl/default_filters.php | 84 +++++++++++++++++ .../com_tjucm/site/views/items/view.html.php | 21 ++--- 5 files changed, 171 insertions(+), 69 deletions(-) create mode 100644 src/components/com_tjucm/site/views/items/tmpl/default_filters.php diff --git a/src/components/com_tjucm/site/models/itemform.php b/src/components/com_tjucm/site/models/itemform.php index af58ca8b..9c9c3aa8 100644 --- a/src/components/com_tjucm/site/models/itemform.php +++ b/src/components/com_tjucm/site/models/itemform.php @@ -670,6 +670,7 @@ public function delete($contentId) $canDeleteown = $user->authorise('core.type.deleteownitem', 'com_tjucm.type.' . $table->type_id); $deleteOwn = false; + if ($canDeleteown) { $deleteOwn = (JFactory::getUser()->id == $table->created_by ? true : false); diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index 20d1c05f..c0ae4b3c 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -83,6 +83,19 @@ protected function populateState($ordering = "a.id", $direction = "DESC") $typeTable->load(array('id' => $typeId)); $ucmType = $typeTable->unique_identifier; + // Set state for field filters + JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); + $fieldsModel = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request' => true)); + $fieldsModel->setState('filter.client', $this->client); + $fieldsModel->setState('filter.filterable', 1); + $fields = $fieldsModel->getItems(); + + foreach ($fields as $field) + { + $filterValue = $app->getUserStateFromRequest($this->context . '.' . $field->name, $field->name, '', 'STRING'); + $this->setState('filter.field.' . $field->name, $filterValue); + } + if (empty($ucmType)) { // Get the active item @@ -238,7 +251,7 @@ protected function getListQuery() $query->where(($db->quoteName('(a.state) ') . ' IN (0, 1)')); } - // Filter by search in title + // Search by content id $search = $this->getState('filter.search'); if (!empty($search)) @@ -255,10 +268,18 @@ protected function getListQuery() // Search on fields data $filteredItemIds = $this->filterContent(); - if (!empty($filteredItemIds)) + if (is_array($filteredItemIds)) { - $filteredItemIds = implode(',', $filteredItemIds); - $query->where($db->quoteName('a.id') . ' IN (' . $filteredItemIds . ')'); + if (!empty($filteredItemIds)) + { + $filteredItemIds = implode(',', $filteredItemIds); + $query->where($db->quoteName('a.id') . ' IN (' . $filteredItemIds . ')'); + } + else + { + // If no search results found then do not return any record + $query->where($db->quoteName('a.id') . '=0'); + } } // Filter by cluster @@ -291,13 +312,14 @@ protected function getListQuery() private function filterContent() { $filterFieldFound = 0; + $filterApplied = 0; // Apply search filter $db = JFactory::getDbo(); $query = $db->getQuery(true); - $query->select('content_id'); - $query->from($db->quoteName('#__tjfields_fields_value', 'fv')); - $query->join('INNER', $db->qn('#__tjfields_fields', 'f') . ' ON (' . $db->qn('fv.field_id') . ' = ' . $db->qn('f.id') . ')'); + $query->select('fv1.content_id'); + $query->from($db->quoteName('#__tjfields_fields_value', 'fv1')); + $query->join('INNER', $db->qn('#__tjfields_fields', 'f') . ' ON (' . $db->qn('fv1.field_id') . ' = ' . $db->qn('f.id') . ')'); $query->where($db->quoteName('f.state') . ' =1'); $query->where($db->quoteName('f.client') . ' = ' . $db->quote($this->client)); @@ -312,9 +334,10 @@ private function filterContent() if (stripos($search, $field . ':') === 0) { $search = trim(str_replace($field . ':', '', $search)); - $query->where($db->qn('fv.field_id') . ' = ' . $fieldId); - $query->where($db->qn('fv.value') . ' LIKE ' . $db->q('%' . $search . '%')); + $query->where($db->qn('fv1.field_id') . ' = ' . $fieldId); + $query->where($db->qn('fv1.value') . ' LIKE ' . $db->q('%' . $search . '%')); $filterFieldFound = 1; + $filterApplied = 1; break; } @@ -324,12 +347,54 @@ private function filterContent() // For generic search if ($filterFieldFound == 0 && !empty($search)) { - $query->where($db->quoteName('fv.value') . ' LIKE ' . $db->q('%' . $search . '%')); + $query->where($db->quoteName('fv1.value') . ' LIKE ' . $db->q('%' . $search . '%')); + $filterApplied = 1; } - $db->setQuery($query); + // For filterable fields + JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); + $fieldsModel = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request' => true)); + $fieldsModel->setState('filter.client', $this->client); + $fieldsModel->setState('filter.filterable', 1); + $fields = $fieldsModel->getItems(); + + $filterFieldsCount = 0; + + foreach ($fields as $field) + { + $filterValue = $this->getState('filter.field.' . $field->name); + + if ($filterValue != '') + { + $filterFieldsCount++; - return $db->loadColumn(); + if ($filterFieldsCount == 1) + { + $query->where($db->qn('fv1.field_id') . ' = ' . $field->id); + $query->where($db->qn('fv1.value') . ' = ' . $db->q($filterValue)); + $filterApplied = 1; + } + else + { + $query->join('LEFT', $db->qn('#__tjfields_fields_value', 'fv' . $filterFieldsCount) . ' ON (' . $db->qn('fv' . ($filterFieldsCount-1).'.content_id') . ' = ' . $db->qn('fv'.$filterFieldsCount.'.content_id') . ')'); + $query->where($db->qn('fv'.$filterFieldsCount.'.field_id') . ' = ' . $field->id); + $query->where($db->qn('fv'.$filterFieldsCount.'.value') . ' = ' . $db->q($filterValue)); + $filterApplied = 1; + } + } + } + + // If there is any filter applied then only execute the query + if ($filterApplied) + { + $db->setQuery($query); + + return $db->loadColumn(); + } + else + { + return fasle; + } } /** @@ -341,7 +406,7 @@ public function getFields() { // Load fields model JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); - $fieldsModel = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request'=> true)); + $fieldsModel = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request' => true)); $fieldsModel->setState('filter.showonlist', 1); $fieldsModel->setState('filter.state', 1); $this->client = $this->getState('ucm.client'); diff --git a/src/components/com_tjucm/site/views/items/tmpl/default.php b/src/components/com_tjucm/site/views/items/tmpl/default.php index 5970e993..de654e81 100644 --- a/src/components/com_tjucm/site/views/items/tmpl/default.php +++ b/src/components/com_tjucm/site/views/items/tmpl/default.php @@ -15,8 +15,6 @@ JHtml::_('behavior.multiselect'); JHtml::_('formbehavior.chosen', 'select'); -use Joomla\CMS\Component\ComponentHelper; - $user = JFactory::getUser(); $userId = $user->get('id'); $tjUcmFrontendHelper = new TjucmHelpersTjucm; @@ -43,46 +41,7 @@ $itemId = $tjUcmFrontendHelper->getItemId($link); ?> -
-
- -
-
- - -
- - enabled) - { - - JLoader::import('components.com_tjfields.tables.field', JPATH_ADMINISTRATOR); - $fieldTable = JTable::getInstance('Field', 'TjfieldsTable', array('dbo', $db)); - $fieldTable->load(array('client' => $this->client, 'type' => 'cluster')); - - if ($fieldTable->id) - { - JFormHelper::addFieldPath(JPATH_ADMINISTRATOR . '/components/com_tjfields/models/fields/'); - $cluster = JFormHelper::loadFieldType('cluster', false); - $this->clusterList = $cluster->getOptionsExternally(); - ?> - - -
-

+ loadTemplate('filters'); ?>
+ * @package Com_Tjucm + * @author Techjoomla + * @copyright Copyright (c) 2009-2018 TechJoomla. All rights reserved. + * @license GNU General Public License version 2 or later. + */ + +// No direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Component\ComponentHelper; +?> +
+
+ +
+
+ + +
+ + enabled) + { + JLoader::import('components.com_tjfields.tables.field', JPATH_ADMINISTRATOR); + $fieldTable = JTable::getInstance('Field', 'TjfieldsTable', array('dbo', $db)); + $fieldTable->load(array('client' => $this->client, 'type' => 'cluster')); + + if ($fieldTable->id) + { + JFormHelper::addFieldPath(JPATH_ADMINISTRATOR . '/components/com_tjfields/models/fields/'); + $cluster = JFormHelper::loadFieldType('cluster', false); + $this->clusterList = $cluster->getOptionsExternally(); + ?> + + true)); + $fieldsModel->setState('filter.client', $this->client); + $fieldsModel->setState('filter.filterable', 1); + $fields = $fieldsModel->getItems(); + + foreach ($fields as $field) + { + $tjFieldsOptionsModel = JModelLegacy::getInstance('Options', 'TjfieldsModel', array('ignore_request' => true)); + $tjFieldsOptionsModel->setState('filter.field_id', $field->id); + $options = $tjFieldsOptionsModel->getItems(); + + if (!empty($options)) + { + $defaultOption = new stdclass; + $defaultOption->value = ""; + $defaultOption->options = JText::_("JSELECT") . ' ' . ucfirst($field->label); + + $options = array_merge(array($defaultOption), $options); + ?> + + +
+

\ No newline at end of file diff --git a/src/components/com_tjucm/site/views/items/view.html.php b/src/components/com_tjucm/site/views/items/view.html.php index cdd683ff..82aeaa53 100644 --- a/src/components/com_tjucm/site/views/items/view.html.php +++ b/src/components/com_tjucm/site/views/items/view.html.php @@ -88,20 +88,13 @@ public function display($tpl = null) $model = $this->getModel("Items"); $this->ucmTypeId = $id = $model->getState('ucmType.id'); $this->client = $model->getState('ucm.client'); - $canCreate = $user->authorise('core.type.createitem', 'com_tjucm.type.' . $this->ucmTypeId); - $canView = $user->authorise('core.type.viewitem', 'com_tjucm.type.' . $this->ucmTypeId); - $canEdit = $user->authorise('core.type.edititem', 'com_tjucm.type.' . $this->ucmTypeId); - $canChange = $user->authorise('core.type.edititemstate', 'com_tjucm.type.' . $this->ucmTypeId); - $canEditOwn = $user->authorise('core.type.editownitem', 'com_tjucm.type.' . $this->ucmTypeId); - $canDelete = $user->authorise('core.type.deleteitem', 'com_tjucm.type.' . $this->ucmTypeId); - $canDeleteOwn = $user->authorise('core.type.deleteownitem', 'com_tjucm.type.' . $this->ucmTypeId); - $this->canCreate = $canCreate; - $this->canView = $canView; - $this->canEdit = $canEdit; - $this->canChange = $canChange; - $this->canEditOwn = $canEditOwn; - $this->canDelete = $canDelete; - $this->canDeleteOwn = $canDeleteOwn; + $this->canCreate = $user->authorise('core.type.createitem', 'com_tjucm.type.' . $this->ucmTypeId); + $this->canView = $user->authorise('core.type.viewitem', 'com_tjucm.type.' . $this->ucmTypeId); + $this->canEdit = $user->authorise('core.type.edititem', 'com_tjucm.type.' . $this->ucmTypeId); + $this->canChange = $user->authorise('core.type.edititemstate', 'com_tjucm.type.' . $this->ucmTypeId); + $this->canEditOwn = $user->authorise('core.type.editownitem', 'com_tjucm.type.' . $this->ucmTypeId); + $this->canDelete = $user->authorise('core.type.deleteitem', 'com_tjucm.type.' . $this->ucmTypeId); + $this->canDeleteOwn = $user->authorise('core.type.deleteownitem', 'com_tjucm.type.' . $this->ucmTypeId); // If did not get the client from url then get if from menu param if (empty($this->client)) From cc7076f1f85b1ab660adec112f2618d26f09cac0 Mon Sep 17 00:00:00 2001 From: ankush-maherwal Date: Fri, 23 Aug 2019 14:52:52 +0530 Subject: [PATCH 15/27] Bug #172 fix: List view not loading if there are large number of records added in a UCM type --- .../com_tjucm/site/models/items.php | 52 +++++--- .../site/views/items/tmpl/default_filter.php | 117 ------------------ 2 files changed, 33 insertions(+), 136 deletions(-) delete mode 100644 src/components/com_tjucm/site/views/items/tmpl/default_filter.php diff --git a/src/components/com_tjucm/site/models/items.php b/src/components/com_tjucm/site/models/items.php index c0ae4b3c..d6d4496f 100644 --- a/src/components/com_tjucm/site/models/items.php +++ b/src/components/com_tjucm/site/models/items.php @@ -260,7 +260,6 @@ protected function getListQuery() if (stripos($search, 'id:') === 0) { - $this->setState('filter.search', ''); $query->where($db->quoteName('a.id') . ' = ' . (int) str_replace('id:', '', $search)); } } @@ -311,9 +310,15 @@ protected function getListQuery() */ private function filterContent() { + // Flag to mark if field specific search is done from the search box $filterFieldFound = 0; + + // Flag to mark if any filter is applied or not $filterApplied = 0; + // Variable to store count of the self joins on the fields_value table + $filterFieldsCount = 0; + // Apply search filter $db = JFactory::getDbo(); $query = $db->getQuery(true); @@ -326,16 +331,23 @@ private function filterContent() // Filter by field value $search = $this->getState('filter.search'); - if (!empty($this->fields)) + if (!empty($this->fields) && (stripos($search, 'id:') !== 0)) { foreach ($this->fields as $fieldId => $field) { // For field specific search if (stripos($search, $field . ':') === 0) { + $filterFieldsCount++; + + if ($filterFieldsCount > 1) + { + $query->join('LEFT', $db->qn('#__tjfields_fields_value', 'fv' . $filterFieldsCount) . ' ON (' . $db->qn('fv' . ($filterFieldsCount-1).'.content_id') . ' = ' . $db->qn('fv'.$filterFieldsCount.'.content_id') . ')'); + } + $search = trim(str_replace($field . ':', '', $search)); - $query->where($db->qn('fv1.field_id') . ' = ' . $fieldId); - $query->where($db->qn('fv1.value') . ' LIKE ' . $db->q('%' . $search . '%')); + $query->where($db->qn('fv'.$filterFieldsCount.'.field_id') . ' = ' . $fieldId); + $query->where($db->qn('fv'.$filterFieldsCount.'.value') . ' LIKE ' . $db->q('%' . $search . '%')); $filterFieldFound = 1; $filterApplied = 1; @@ -345,11 +357,18 @@ private function filterContent() } // For generic search - if ($filterFieldFound == 0 && !empty($search)) + if ($filterFieldFound == 0 && !empty($search) && (stripos($search, 'id:') !== 0)) { - $query->where($db->quoteName('fv1.value') . ' LIKE ' . $db->q('%' . $search . '%')); + $filterFieldsCount++; + + if ($filterFieldsCount > 1) + { + $query->join('LEFT', $db->qn('#__tjfields_fields_value', 'fv' . $filterFieldsCount) . ' ON (' . $db->qn('fv' . ($filterFieldsCount-1).'.content_id') . ' = ' . $db->qn('fv'.$filterFieldsCount.'.content_id') . ')'); + } + + $query->where($db->quoteName('fv'.$filterFieldsCount.'.value') . ' LIKE ' . $db->q('%' . $search . '%')); $filterApplied = 1; - } + } // For filterable fields JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); @@ -358,8 +377,6 @@ private function filterContent() $fieldsModel->setState('filter.filterable', 1); $fields = $fieldsModel->getItems(); - $filterFieldsCount = 0; - foreach ($fields as $field) { $filterValue = $this->getState('filter.field.' . $field->name); @@ -368,22 +385,19 @@ private function filterContent() { $filterFieldsCount++; - if ($filterFieldsCount == 1) - { - $query->where($db->qn('fv1.field_id') . ' = ' . $field->id); - $query->where($db->qn('fv1.value') . ' = ' . $db->q($filterValue)); - $filterApplied = 1; - } - else + if ($filterFieldsCount > 1) { $query->join('LEFT', $db->qn('#__tjfields_fields_value', 'fv' . $filterFieldsCount) . ' ON (' . $db->qn('fv' . ($filterFieldsCount-1).'.content_id') . ' = ' . $db->qn('fv'.$filterFieldsCount.'.content_id') . ')'); - $query->where($db->qn('fv'.$filterFieldsCount.'.field_id') . ' = ' . $field->id); - $query->where($db->qn('fv'.$filterFieldsCount.'.value') . ' = ' . $db->q($filterValue)); - $filterApplied = 1; } + + $query->where($db->qn('fv'.$filterFieldsCount.'.field_id') . ' = ' . $field->id); + $query->where($db->qn('fv'.$filterFieldsCount.'.value') . ' = ' . $db->q($filterValue)); + $filterApplied = 1; } } + $query->setLimit($this->getState('list.limit')); + // If there is any filter applied then only execute the query if ($filterApplied) { diff --git a/src/components/com_tjucm/site/views/items/tmpl/default_filter.php b/src/components/com_tjucm/site/views/items/tmpl/default_filter.php deleted file mode 100644 index 0f45fe2f..00000000 --- a/src/components/com_tjucm/site/views/items/tmpl/default_filter.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright 2016 Techjoomla - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -defined('JPATH_BASE') or die; - -$data = $displayData; - -// Receive overridable options -$data['options'] = !empty($data['options']) ? $data['options'] : array(); - -// Check if any filter field has been filled -$filters = false; -$filtered = false; -$search_filter = false; - -if (isset($data['view']->filterForm)) -{ - $filters = $data['view']->filterForm->getGroup('filter'); -} - -// Check if there are filters set. -if ($filters !== false) -{ - $filterFields = array_keys($filters); - $filled = false; - - foreach ($filterFields as $filterField) - { - $filterField = substr($filterField, 7); - $filter = $data['view']->getState('filter.' . $filterField); - - if (!empty($filter)) - { - $filled = $filter; - } - - if (!empty($filled)) - { - $filtered = true; - break; - } - } - - $search_filter = $filters['filter_search']; - unset($filters['filter_search']); -} - -$options = $data['options']; - -// Set some basic options -$customOptions = array( - 'filtersHidden' => isset($options['filtersHidden']) ? $options['filtersHidden'] : empty($data['view']->activeFilters) && !$filtered, - 'defaultLimit' => isset($options['defaultLimit']) ? $options['defaultLimit'] : JFactory::getApplication()->get('list_limit', 20), - 'searchFieldSelector' => '#filter_search', - 'orderFieldSelector' => '#list_fullordering', -); - -$data['options'] = array_unique(array_merge($customOptions, $data['options'])); - -$formSelector = !empty($data['options']['formSelector']) ? $data['options']['formSelector'] : '#adminForm'; - -// Load search tools -JHtml::_('searchtools.form', $formSelector, $data['options']); -?> - -
-
-
- - -
- input; ?> - -
- -
- -
- - -
- -
-
-
- -
- - - $field) : ?> - -
- renderField(); ?> -
- - - -
-
\ No newline at end of file From 750fa51a2a4845bd439b1524bb4dbd09bcb46a2e Mon Sep 17 00:00:00 2001 From: ankush-maherwal Date: Fri, 23 Aug 2019 16:32:29 +0530 Subject: [PATCH 16/27] Task #177 feat: Introducing UCM type param for selecting details and list view layout for given UCM type --- .../administrator/models/forms/type.xml | 2 ++ .../com_tjucm/administrator/models/type.php | 2 ++ .../administrator/views/type/tmpl/edit.php | 3 ++- .../administrator/en-GB/en-GB.com_tjucm.ini | 8 +++++-- .../com_tjucm/site/views/item/view.html.php | 10 ++++++++ .../site/views/itemform/view.html.php | 23 +++++++++++-------- .../com_tjucm/site/views/items/view.html.php | 15 ++++++++---- 7 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/components/com_tjucm/administrator/models/forms/type.xml b/src/components/com_tjucm/administrator/models/forms/type.xml index 7bf1bfb2..705170c4 100644 --- a/src/components/com_tjucm/administrator/models/forms/type.xml +++ b/src/components/com_tjucm/administrator/models/forms/type.xml @@ -39,6 +39,8 @@
state == 1) { - ?> From 77eb5150fe051b8e6189cecdac9bade6efd440dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cankush=5Fm=E2=80=9D?= Date: Thu, 3 Oct 2019 12:03:03 +0530 Subject: [PATCH 22/27] Task #199 feat: ItemForm save process optimisation --- .../administrator/assets/js/itemform.js | 900 ++++++++++++++++++ .../assets/js/tjucm_ajaxForm_save.js | 217 ----- .../administrator/models/forms/type.xml | 2 +- .../com_tjucm/administrator/tables/item.php | 53 +- .../administrator/views/item/tmpl/edit.php | 2 +- .../languages/site/en-GB/en-GB.com_tjucm.ini | 8 + .../com_tjucm/media/js/com_tjucm.js | 9 + .../com_tjucm/media/js/core/base.js | 97 ++ .../com_tjucm/media/js/core/class.js | 68 ++ src/components/com_tjucm/media/js/load_js.php | 23 + .../com_tjucm/media/js/services/item.js | 39 + .../site/controllers/itemform.json.php | 439 +++++++++ .../com_tjucm/site/models/forms/fielddata.xml | 3 + .../com_tjucm/site/models/forms/itemform.xml | 47 +- .../com_tjucm/site/models/itemform.php | 316 +++++- src/components/com_tjucm/site/tjucm.php | 14 + .../site/views/itemform/tmpl/default.php | 14 +- .../site/views/items/tmpl/default_filter.php | 117 +++ 18 files changed, 2065 insertions(+), 303 deletions(-) create mode 100644 src/components/com_tjucm/administrator/assets/js/itemform.js delete mode 100644 src/components/com_tjucm/administrator/assets/js/tjucm_ajaxForm_save.js create mode 100755 src/components/com_tjucm/media/js/com_tjucm.js create mode 100755 src/components/com_tjucm/media/js/core/base.js create mode 100755 src/components/com_tjucm/media/js/core/class.js create mode 100755 src/components/com_tjucm/media/js/load_js.php create mode 100755 src/components/com_tjucm/media/js/services/item.js create mode 100644 src/components/com_tjucm/site/controllers/itemform.json.php create mode 100644 src/components/com_tjucm/site/models/forms/fielddata.xml create mode 100644 src/components/com_tjucm/site/views/items/tmpl/default_filter.php diff --git a/src/components/com_tjucm/administrator/assets/js/itemform.js b/src/components/com_tjucm/administrator/assets/js/itemform.js new file mode 100644 index 00000000..75044ef7 --- /dev/null +++ b/src/components/com_tjucm/administrator/assets/js/itemform.js @@ -0,0 +1,900 @@ +/*Variable to store the updated options of related field*/ +var tjucmRelatedFieldUpdatedOptions = ''; +var tjUcmTinyMCEFieldIds = new Array(); +var tjUcmClickedOnNext = 0; +var tjUcmClickedOnPrev = 0; + +/* This function executes for autosave form */ +jQuery(window).load(function() +{ + /*Code to get item state*/ + var itemState = Number(jQuery('#itemState').val()); + + /*Code for auto save on blur event add new record or editing draft record only*/ + if (itemState == '' || itemState === 0) + { + var tjUcmAutoSave = jQuery('#item-form #tjucm-autosave').val(); + + /*Check if auto save is enabled for UCM type*/ + if (tjUcmAutoSave == 1) + { + /* Save form values */ + jQuery("#item-form").on("change select", ":input", function(){ + tjUcmItemForm.onUcmFormChange(this); + }); + + /* To save calendar field value */ + jQuery("#item-form .field-calendar input:text").blur(function(){ + if (jQuery('#item-form').hasClass('dirty')) + { + tjUcmItemForm.onUcmFormChange(this); + } + }); + + var tjUcmTinyMCE = Joomla.getOptions("plg_editor_tinymce"); + + /* Get the value of editor fields*/ + if (tjUcmTinyMCE != undefined) + { + jQuery.each(tjUcmTinyMCE.tinyMCE, function(index, value){ + if (jQuery("#item-form #jform_"+index).length) + { + var tjUcmEditorFieldContent = jQuery("#jform_"+index+"_ifr").contents().find('body').html(); + tjUcmTinyMCEFieldIds[index] = tjUcmEditorFieldContent; + } + else if ((jQuery("#item-form #jform_"+index).length == 0) && (index != 'default')) + { + var tjUcmSubFormEditorFields = jQuery("textarea[id$='__"+index+"']"); + + if (tjUcmSubFormEditorFields.length) + { + jQuery.each(tjUcmSubFormEditorFields, function(findex, fvalue){ + var tjUcmEditorFieldContentId = jQuery(fvalue).attr('id'); + var tjUcmEditorFieldContent = jQuery("#"+tjUcmEditorFieldContentId+"_ifr").contents().find('body').html(); + var tjucmTempIndex = tjUcmEditorFieldContentId.replace("jform_", ""); + tjUcmTinyMCEFieldIds[tjucmTempIndex] = tjUcmEditorFieldContent; + }); + } + } + }); + + /* Check after some time if the content of editor is changed and if so then save it in DB*/ + setInterval(function () { + for (var key in tjUcmTinyMCEFieldIds) { + if (tjUcmTinyMCEFieldIds.hasOwnProperty(key)) { + var tjUcmEditorFieldContent = jQuery("#jform_"+key+"_ifr").contents().find('body').html(); + + if (tjUcmTinyMCEFieldIds[key] != tjUcmEditorFieldContent) + { + var tjUcmTempFieldObj = jQuery("#jform_"+key); + tjUcmTempFieldObj.val(tjUcmEditorFieldContent); + tjUcmTinyMCEFieldIds[key] = tjUcmEditorFieldContent; + tjUcmItemForm.onUcmFormChange(tjUcmTempFieldObj); + } + } + } + },7000); + } + + /* To save calendar field value */ + jQuery("#item-form .field-calendar input:text").blur(function(){ + tjUcmItemForm.onUcmFormChange(this); + //steppedFormSave(this.form.id, "draft", 0); + }); + } + } + + /*Update the options of related field for new record of subform*/ + jQuery(document).on('subform-row-add', function(event, row){ + var tjucmSubFormCount = jQuery(row).attr('data-group').replace(jQuery(row).attr('data-base-name'), ""); + + /* If there is any editor field in sub-form then add its reference in variable tjUcmTinyMCEFieldIds*/ + if (jQuery(row).find('.js-editor-tinymce textarea')) + { + var tjUcmIdOfEditorFieldInSubForm = jQuery(row).find('.js-editor-tinymce textarea').attr('id'); + + if (tjUcmIdOfEditorFieldInSubForm) + { + var tjUcmSubFormEditorFieldContent = jQuery("#"+tjUcmIdOfEditorFieldInSubForm+"_ifr").contents().find('body').html(); + tjUcmIdOfEditorFieldInSubForm = tjUcmIdOfEditorFieldInSubForm.replace('jform_', ''); + tjUcmTinyMCEFieldIds[tjUcmIdOfEditorFieldInSubForm] = tjUcmSubFormEditorFieldContent; + } + } + + /* Update options of related fields*/ + jQuery.each(tjucmRelatedFieldUpdatedOptions, function(index, value) { + if (value.templateId) + { + var tjucmNewTemplateId = value.templateId.replace("XXX_XXX", tjucmSubFormCount); + jQuery(row).find("#"+tjucmNewTemplateId).html(''); + jQuery.each(value.options, function(i, val) { + jQuery(row).find("#"+tjucmNewTemplateId).append(''); + }); + + jQuery(row).find("#"+tjucmNewTemplateId).trigger("liszt:updated"); + } + }); + }); + + /* Handle next and previous button click on the form*/ + jQuery("#next_button, #previous_button").on('click', function (){ + + if (jQuery(this).attr('id') == 'next_button') + { + tjUcmClickedOnNext = 1; + } + else + { + tjUcmClickedOnPrev = 1; + } + + tjUcmItemForm.saveSectionData(jQuery('#tjucm_myTabTabs > .active a').attr('href')); + }); +}); + +var tjUcmItemForm = { + onUcmFormChange: function (fieldObj){ + var tjUcmParentClient = jQuery('#item-form').find("input[name='jform[client]']").val(); + + var getParentRecordid = new Promise(function(resolve, reject) { + var tjucmParentRecordId = jQuery('#item-form').find("input[name='jform[id]']").val(); + + if (tjucmParentRecordId == '') + { + var tjUcmItemFormData = new FormData(); + + /* Set parent client in the data form*/ + if (tjUcmParentClient != '') + { + tjUcmItemFormData.append('client', tjUcmParentClient); + } + + /* Add CSRF token to the form*/ + tjUcmItemFormData.append(Joomla.getOptions('csrf.token'), 1); + + /* Callback function after creating the parent UCM record */ + var afterCreateParentUcmRecord = function (error, response){ + if (error == null) + { + if (response.data !== null && jQuery.isNumeric(response.data.id)) + { + /* Set parent record id in the form*/ + jQuery('#item-form').find("input[name='jform[id]']").val(response.data.id); + + /* Update parent record id in the URL if the parent record is created successfully*/ + var tjucmUrl = window.location.href.split('#')[0]; + var tjucmUrlSeparator = (tjucmUrl.indexOf("?")===-1)?"?":"&"; + var tjucmNewParam = "id=" + response.data.id; + + if (!(tjucmUrl.indexOf(tjucmNewParam) >= 0)) + { + tjucmUrl+=tjucmUrlSeparator+tjucmNewParam; + } + + history.pushState(null, null, tjucmUrl); + + resolve(response.data.id); + } + else + { + reject(response); + } + } + }; + + /* Create the record in draft mode*/ + tjUcmItemFormData.append('draft', 1); + + /* Add new UCM parent record for UCM type if its not created yet*/ + com_tjucm.Services.Item.create(tjUcmItemFormData, afterCreateParentUcmRecord); + } + else if (jQuery.isNumeric(tjucmParentRecordId) && tjucmParentRecordId != 0) + { + resolve(tjucmParentRecordId); + } + }); + + // Action on after creating the parent UCM record + getParentRecordid.then(function (response){ + /* Save the field value which was added/changed */ + tjUcmItemForm.initUcmFormFieldDataSave(fieldObj, tjUcmParentClient, response); + }).catch(function (error){ + console.log(error); + + return false; + }); + }, + initUcmFormFieldDataSave: function (fieldObj, tjUcmParentClient, tjUcmParentRecordId){ + var childRecordContentIdFieldId = ''; + var tjUcmItemFormData = new FormData(); + + /* Add CSRF token to the form*/ + tjUcmItemFormData.append(Joomla.getOptions('csrf.token'), 1); + + if (jQuery(fieldObj).parent().parent().parent().attr('data-base-name') !== undefined || jQuery(fieldObj).parent().parent().parent().parent().attr('data-base-name') !== undefined) + { + // In case of field of subform + var tjucmSubFormFieldName = jQuery(fieldObj).parent().parent().parent().attr('data-base-name'); + + // In case of editor field of subform + if (tjucmSubFormFieldName == undefined) + { + tjucmSubFormFieldName = jQuery(fieldObj).parent().parent().parent().parent().attr('data-base-name'); + } + + /* This block is executed when the field which is updated/added is from ucmsubform field under the parent form*/ + var tjUcmCurrentFieldId = jQuery(fieldObj).attr('id'); + childRecordContentIdFieldId = tjUcmCurrentFieldId.replace(tjUcmCurrentFieldId.split('_').pop(), "contentid"); + var tjucmClient = 'com_tjucm.'+childRecordContentIdFieldId.split('__').pop().replace('_contentid', '').replace('com_tjucm_', ''); + var tjucmRecordId = jQuery('#'+childRecordContentIdFieldId).val(); + + /* If record is being edited then send recordId in the request else create the record*/ + if (tjucmRecordId == '') + { + /* Callback function after creating the UCM subform record */ + var afterCreateUcmSubFormRecord = function (error, response){ + if (error == null) + { + if (response.data !== null && jQuery.isNumeric(response.data.id)) + { + jQuery('#'+childRecordContentIdFieldId).val(response.data.id); + } + + /* Save the ucm-subform field data*/ + var afterAddFieldValueForUcmSubFormField = function (err, rsp){ + var tjUcmIsMultiSelect = (jQuery(fieldObj).attr('name').slice(-2) == '[]') ? '[]' : ''; + var tjUcmUpdatedSubFormFieldName = 'jform['+jQuery(fieldObj).attr('id').split('__').pop()+']'+tjUcmIsMultiSelect; + jQuery(fieldObj).attr('name', tjUcmUpdatedSubFormFieldName); + + tjUcmItemForm.saveUcmFormFieldData(tjucmClient, response.data.id, fieldObj); + } + + /* Add entry for ucm-subform-field in field_value table for the parent record*/ + tjUcmItemFormData.append('jform['+tjucmSubFormFieldName+']', tjucmClient); + tjUcmItemFormData.append('client', tjUcmParentClient); + tjUcmItemFormData.append('recordid', tjUcmParentRecordId); + com_tjucm.Services.Item.saveFieldData(tjUcmItemFormData, afterAddFieldValueForUcmSubFormField); + + return true; + } + }; + + /* Add new UCM record for UCM type is its not created yet*/ + tjUcmItemFormData.append('parent_id', tjUcmParentRecordId); + tjUcmItemFormData.append('client', tjucmClient); + + /* Create the record in draft mode*/ + tjUcmItemFormData.append('draft', 1); + com_tjucm.Services.Item.create(tjUcmItemFormData, afterCreateUcmSubFormRecord); + } + else if (jQuery.isNumeric(tjucmRecordId) && tjucmRecordId != 0) + { + var tjUcmIsMultiSelect = (jQuery(fieldObj).attr('name').slice(-2) == '[]') ? '[]' : ''; + var tjUcmUpdatedSubFormFieldName = 'jform['+jQuery(fieldObj).attr('id').split('__').pop()+']'+tjUcmIsMultiSelect; + jQuery(fieldObj).attr('name', tjUcmUpdatedSubFormFieldName); + + tjUcmItemForm.saveUcmFormFieldData(tjucmClient, tjucmRecordId, fieldObj); + + return true; + } + + return false; + } + else + { + /* This block is executed when the field which is updated/added is from the parent form*/ + tjUcmItemForm.saveUcmFormFieldData(tjUcmParentClient, tjUcmParentRecordId, fieldObj); + + return true; + } + }, + saveUcmFormFieldData: function (tjUcmClient, tjUcmRecordId, fieldObj){ + var tjUcmItemFieldFormData = new FormData(); + + /* Add CSRF token to the form*/ + tjUcmItemFieldFormData.append(Joomla.getOptions('csrf.token'), 1); + tjUcmItemFieldFormData.append('client', tjUcmClient); + tjUcmItemFieldFormData.append('recordid', tjUcmRecordId); + + if (jQuery(fieldObj).attr('type') != 'file') + { + tjUcmItemFieldFormData.append(jQuery(fieldObj).attr('name'), jQuery(fieldObj).val()); + } + else + { + tjUcmItemFieldFormData.append(jQuery(fieldObj).attr('name'), jQuery(fieldObj)[0].files[0]); + } + + com_tjucm.Services.Item.saveFieldData(tjUcmItemFieldFormData, tjUcmItemForm.afterFieldDataSave); + + return true; + }, + afterFieldDataSave: function (error, response){ + /* Remove the dirty class fromt the form once the field data is saved*/ + jQuery('#item-form').removeClass('dirty'); + + /* Enable the sce button once the field data is saved*/ + jQuery('#finalSave').attr('disabled', false); + jQuery('#draftSave').attr('disabled', false); + + /* Add content_id in ucmsubform records */ + if (response.data.childContentIds) + { + jQuery.each(response.data.childContentIds, function(elementId, val) { + jQuery("#"+elementId).val(val); + }); + } + + if (tjUcmClickedOnNext) + { + tjUcmClickedOnNext = 0; + jQuery('#tjucm_myTabTabs > .active').next('li').find('a').trigger('click'); + tjUcmItemForm.setVisibilityOfNavigationButtons(); + } + + if (tjUcmClickedOnPrev) + { + tjUcmClickedOnPrev = 0; + jQuery('#tjucm_myTabTabs > .active').prev('li').find('a').trigger('click'); + tjUcmItemForm.setVisibilityOfNavigationButtons(); + } + + /* Update the options of related field */ + var tjUcmParentClient = jQuery('#item-form').find("input[name='jform[client]']").val(); + var tjucmParentRecordId = jQuery('#item-form').find("input[name='jform[id]']").val(); + tjUcmItemForm.updateRelatedFieldsOptions(tjUcmParentClient, tjucmParentRecordId); + + /* If there are errors in the response then show them on the screen*/ + tjUcmItemForm.displayFormErrors(response); + }, + displayFormErrors: function (response) + { + if (response != null) + { + if (response.messages !== null) + { + if (response.messages.error !== null) + { + jQuery.each(response.messages.error, function(index, value) { + Joomla.renderMessages({'error':[value]}); + }); + + jQuery("html, body").animate({ scrollTop: 0 }, "slow"); + } + } + } + }, + updateRelatedFieldsOptions: function (tjUcmParentClient, tjUcmParentRecordId) { + var tjUcmItemFormData = new FormData(); + + var tjUcmUpdateRelatedFieldsOptions = function (error, response){ + tjucmRelatedFieldUpdatedOptions = response.data; + + if(tjucmRelatedFieldUpdatedOptions == '') + { + return false; + } + + jQuery.each(response.data, function(index, value) { + jQuery("#"+value.elementId).html(''); + + jQuery.each(value.options, function(i, val) { + var tjucmSelectedFieldOption = ''; + + if (val.selected == '1'){ + tjucmSelectedFieldOption = ' selected="selected" '; + } + + jQuery("#"+value.elementId).append(''); + }); + + jQuery("#"+value.elementId).trigger("liszt:updated"); + }); + }; + + tjUcmItemFormData.append('client', tjUcmParentClient); + tjUcmItemFormData.append('content_id', tjUcmParentRecordId); + com_tjucm.Services.Item.getUpdatedRelatedFieldsOptions(tjUcmItemFormData, tjUcmUpdateRelatedFieldsOptions); + }, + saveUcmFormData: function(){ + if (document.formvalidator.isValid(document.getElementById('item-form'))) + { + /* Disable the save button till the record is saved*/ + jQuery('#finalSave').attr('disabled', true); + jQuery('#draftSave').attr('disabled', true); + jQuery('#previous_button').attr('disabled', true); + jQuery('#next_button').attr('disabled', true); + + /* For AJAX save need to assign values to the editor field containers*/ + jQuery("#item-form .toggle-editor a").each(function(index) { + this.click(); + }); + + var tjUcmParentClient = jQuery('#item-form').find("input[name='jform[client]']").val(); + var getParentRecordid = new Promise(function(resolve, reject) { + var tjucmParentRecordId = jQuery('#item-form').find("input[name='jform[id]']").val(); + + if (tjucmParentRecordId == '') + { + var tjUcmItemFormData = new FormData(); + + /* Set parent client in the data form*/ + if (tjUcmParentClient != '') + { + tjUcmItemFormData.append('client', tjUcmParentClient); + } + + /* Add CSRF token to the form*/ + tjUcmItemFormData.append(Joomla.getOptions('csrf.token'), 1); + + /* Callback function after creating the parent UCM record */ + var afterCreateParentUcmRecord = function (error, response){ + if (error == null) + { + if (response.data !== null && jQuery.isNumeric(response.data.id)) + { + /* Set parent record id in the form*/ + jQuery('#item-form').find("input[name='jform[id]']").val(response.data.id); + + /* Update parent record id in the URL if the parent record is created successfully*/ + var tjucmUrl = window.location.href.split('#')[0]; + var tjucmUrlSeparator = (tjucmUrl.indexOf("?")===-1)?"?":"&"; + var tjucmNewParam = "id=" + response.data.id; + + if (!(tjucmUrl.indexOf(tjucmNewParam) >= 0)) + { + tjucmUrl+=tjucmUrlSeparator+tjucmNewParam; + } + + history.pushState(null, null, tjucmUrl); + + resolve(response.data.id); + } + else + { + reject(response); + } + } + }; + + /* Add new UCM parent record for UCM type if its not created yet*/ + com_tjucm.Services.Item.create(tjUcmItemFormData, afterCreateParentUcmRecord); + } + else if (jQuery.isNumeric(tjucmParentRecordId) && tjucmParentRecordId != 0) + { + resolve(tjucmParentRecordId); + } + }); + + /* Once data is assigned to the textarea toggle the editors*/ + jQuery("#item-form .toggle-editor a").each(function(index) { + this.click(); + }); + + // Action on after creating the parent UCM record + getParentRecordid.then(function (response){ + var myForm = document.getElementById('item-form'); + var tjUcmItemFormData = new FormData(myForm); + tjUcmItemFormData.delete('task'); + tjUcmItemFormData.delete('option'); + tjUcmItemFormData.delete('view'); + tjUcmItemFormData.delete('layout'); + var tjUcmClient = jQuery('#item-form').find("input[name='jform[client]']").val(); + var tjUcmRecordId = jQuery('#item-form').find("input[name='jform[id]']").val(); + + /* Add CSRF token to the form*/ + tjUcmItemFormData.append(Joomla.getOptions('csrf.token'), 1); + tjUcmItemFormData.append('client', tjUcmClient); + tjUcmItemFormData.append('recordid', tjUcmRecordId); + + com_tjucm.Services.Item.saveFormData(tjUcmItemFormData, tjUcmItemForm.afterFieldDataSave); + + return true; + }).catch(function (error){ + console.log(error); + + return false; + }); + } + else + { + tjUcmItemForm.setVisibilityOfNavigationButtons(); + jQuery('#finalSave').attr('disabled', false); + jQuery('#draftSave').attr('disabled', false); + jQuery("html, body").animate({ scrollTop: 0 }, "slow"); + + return false; + } + }, + saveSectionData: function (tabId){ + var tjUcmSectionFormData = new FormData(); + var tjUcmSectionInputElements = jQuery(tabId).find('input, textarea, select, fieldset'); + + if (tjUcmItemForm.validateSection(tjUcmSectionInputElements)) + { + /* For AJAX save need to assign values to the editor field containers*/ + jQuery("#item-form .toggle-editor a").each(function(index) { + this.click(); + }); + + if (tjUcmSectionInputElements.length) + { + tjUcmSectionInputElements.each(function (){ + if (jQuery(this).attr('type') == 'file') + { + if (jQuery(this)[0].files[0] != undefined) + { + tjUcmSectionFormData.append(jQuery(this).attr('name'), jQuery(this)[0].files[0]); + } + } + else + { + if (jQuery(this).val() != undefined) + { + tjUcmSectionFormData.append(jQuery(this).attr('name'), jQuery(this).val()); + } + } + }); + } + + /* Disable the save button till the record is saved*/ + jQuery('#finalSave').attr('disabled', true); + jQuery('#draftSave').attr('disabled', true); + jQuery('#previous_button').attr('disabled', true); + jQuery('#next_button').attr('disabled', true); + + var tjUcmParentClient = jQuery('#item-form').find("input[name='jform[client]']").val(); + var getParentRecordid = new Promise(function(resolve, reject) { + var tjucmParentRecordId = jQuery('#item-form').find("input[name='jform[id]']").val(); + + if (tjucmParentRecordId == '') + { + var tjUcmItemFormData = new FormData(); + + /* Set parent client in the data form*/ + if (tjUcmParentClient != '') + { + tjUcmItemFormData.append('client', tjUcmParentClient); + } + + /* Add CSRF token to the form*/ + tjUcmItemFormData.append(Joomla.getOptions('csrf.token'), 1); + + /* Callback function after creating the parent UCM record */ + var afterCreateParentUcmRecord = function (error, response){ + if (error == null) + { + if (response.data !== null && jQuery.isNumeric(response.data.id)) + { + /* Set parent record id in the form*/ + jQuery('#item-form').find("input[name='jform[id]']").val(response.data.id); + + /* Update parent record id in the URL if the parent record is created successfully*/ + var tjucmUrl = window.location.href.split('#')[0]; + var tjucmUrlSeparator = (tjucmUrl.indexOf("?")===-1)?"?":"&"; + var tjucmNewParam = "id=" + response.data.id; + + if (!(tjucmUrl.indexOf(tjucmNewParam) >= 0)) + { + tjucmUrl+=tjucmUrlSeparator+tjucmNewParam; + } + + history.pushState(null, null, tjucmUrl); + + resolve(response.data.id); + } + else + { + reject(response); + } + } + }; + + /* Add new UCM parent record for UCM type if its not created yet*/ + com_tjucm.Services.Item.create(tjUcmItemFormData, afterCreateParentUcmRecord); + } + else if (jQuery.isNumeric(tjucmParentRecordId) && tjucmParentRecordId != 0) + { + resolve(tjucmParentRecordId); + } + }); + + // Action on after creating the parent UCM record + getParentRecordid.then(function (response){ + tjUcmSectionFormData.delete('task'); + tjUcmSectionFormData.delete('option'); + tjUcmSectionFormData.delete('view'); + tjUcmSectionFormData.delete('layout'); + var tjUcmClient = jQuery('#item-form').find("input[name='jform[client]']").val(); + var tjUcmRecordId = jQuery('#item-form').find("input[name='jform[id]']").val(); + + /* Add CSRF token to the form*/ + tjUcmSectionFormData.append(Joomla.getOptions('csrf.token'), 1); + tjUcmSectionFormData.append('client', tjUcmClient); + tjUcmSectionFormData.append('recordid', tjUcmRecordId); + tjUcmSectionFormData.append('tjUcmFormSection', jQuery("a[href='"+tabId+"']").html()); + + com_tjucm.Services.Item.saveFormData(tjUcmSectionFormData, tjUcmItemForm.afterFieldDataSave); + + return true; + }).catch(function (error){ + console.log(error); + + return false; + }); + } + else + { + jQuery("html, body").animate({ scrollTop: 0 }, "slow"); + + return false; + } + }, + validateSection: function (fields){ + var valid = true, message, error, label, invalid = [], i, l; + + // Validate section fields + for (i = 0, l = fields.length; i < l; i++) { + // Ignore Rule/Filters/Assigned field for spead up validation + // And other fields that has class="novalidate" + if(jQuery(fields[i]).hasClass('novalidate')) { + continue; + } + if (document.formvalidator.validate(fields[i]) === false) { + valid = false; + invalid.push(fields[i]); + } + } + + // Run custom form validators if present + jQuery.each(document.formvalidator.custom, function(key, validator) { + if (validator.exec() !== true) { + valid = false; + } + }); + + if (!valid && invalid.length > 0) { + message = Joomla.JText._('JLIB_FORM_FIELD_INVALID'); + error = {"error": []}; + for (i = invalid.length - 1; i >= 0; i--) { + label = jQuery(invalid[i]).data("label"); + if (label) { + error.error.push(message + label.text().replace("*", "")); + } + } + Joomla.renderMessages(error); + } + + return valid; + }, + setVisibilityOfNavigationButtons: function(){ + var tjUcmCurrentFormTab = jQuery('#tjucm_myTabTabs').find('li.active'); + + if (jQuery(tjUcmCurrentFormTab).next('li').length) + { + jQuery("#next_button").attr('disabled', false); + } + else + { + jQuery("#next_button").attr('disabled', true); + } + + if (jQuery(tjUcmCurrentFormTab).prev('li').length) + { + jQuery("#previous_button").attr('disabled', false); + } + else + { + jQuery("#previous_button").attr('disabled', true); + } + } +}; + +/* This function carries stepped saving via ajax */ +function steppedFormSave(form_id, status, showDraftSuccessMsg) +{ + /* For AJAX save need to add this to prevent popup message for page unload*/ + window.onbeforeunload = null; + + /* For AJAX save need to assign values to the editor field containers*/ + jQuery("#item-form .toggle-editor a").each(function(index) { + this.click(); + }); + + var item_basic_form = jQuery('#' + form_id); + var promise = false; + jQuery('#form_status').val(status); + + if ('save' == status) { + + if(confirm(Joomla.JText._("COM_TJUCM_ITEMFORM_SUBMIT_ALERT"))) + { + /* code to remove the class added by are-you-sure alert box */ + jQuery('#item-form').removeClass('dirty'); + + if (!document.formvalidator.isValid('#item-form')) + { + jQuery('#finalSave').attr('disabled', false); + jQuery('#draftSave').attr('disabled', false); + jQuery("html, body").animate({ scrollTop: 0 }, "slow"); + + return false; + } + } + else + { + jQuery('#draftSave').attr('disabled', false); + jQuery('#finalSave').attr('disabled', false); + jQuery("html, body").animate({ scrollTop: 0 }, "slow"); + + return false; + } + } + + if(item_basic_form) + { + jQuery(item_basic_form).ajaxSubmit({ + datatype:'JSON', + async: false, + success: function(data) { + var returnedData = JSON.parse(data); + + if (returnedData.messages !== null) + { + if (returnedData.messages.error !== null) + { + jQuery.each(returnedData.messages.error, function(index, value) { + Joomla.renderMessages({'error':[value]}); + }); + + jQuery("html, body").animate({ scrollTop: 0 }, "slow"); + } + } + + if (returnedData.message !== null && returnedData.message != '') + { + Joomla.renderMessages({'info':[returnedData.message]}); + + jQuery("html, body").animate({ scrollTop: 0 }, "slow"); + } + + if (returnedData.data !== null) + { + jQuery("#recordId").val(returnedData.data.id); + + if ('save' == status) + { + jQuery("#finalSave").attr("disabled", "disabled"); + Joomla.renderMessages({'success':[Joomla.JText._('COM_TJUCM_MSG_ON_SAVED_FORM')]}); + jQuery('html, body').animate({ + scrollTop: jQuery("#system-message-container").offset().top-40 + }, "slow"); + } + else + { + promise = true; + + if (showDraftSuccessMsg === "1") + { + jQuery("#draft_msg").show(); + setTimeout(function() { jQuery("#draft_msg").hide(); }, 5000); + } + } + + /* Update item id in the URL if the data is stored successfully */ + var tjucmUrl = window.location.href.split('#')[0]; + var tjucmUrlSeparator = (tjucmUrl.indexOf("?")===-1)?"?":"&"; + var tjucmNewParam = "id=" + returnedData.data.id; + + /* Add content_id in ucmsubform records */ + jQuery.each(returnedData.data.childContentIds, function(i, val) { + jQuery("input[name='"+val.elementName+"']").val(val.content_id); + }); + + /* Add content_id in ucmsubform records */ + tjucmRelatedFieldUpdatedOptions = returnedData.data.relatedFieldOptions; + jQuery.each(returnedData.data.relatedFieldOptions, function(index, value) { + jQuery("#"+value.elementId).html(''); + + jQuery.each(value.options, function(i, val) { + var tjucmSelectedFieldOption = ''; + + if (val.selected == '1'){ + tjucmSelectedFieldOption = ' selected="selected" '; + } + + jQuery("#"+value.elementId).append(''); + }); + + jQuery("#"+value.elementId).trigger("liszt:updated"); + }); + + if (!(tjucmUrl.indexOf(tjucmNewParam) >= 0)) + { + tjucmUrl+=tjucmUrlSeparator+tjucmNewParam; + } + + history.pushState(null, null, tjucmUrl); + } + + jQuery('#draftSave').attr('disabled', false); + jQuery('#finalSave').attr('disabled', false); + + /* After AJAX save need to toggle back the editors as we had previoussly toggled them to post the values*/ + jQuery("#item-form .toggle-editor a").each(function(index) { + this.click(); + }); + } + }); + } + + return promise; +} + +/*Function triggered by clicking on the "Save and next"*/ +function itemformactions(tab_id, navDirection) +{ + var tjUcmCurrentFormTab = jQuery('ul#tjucm_myTabTabs').find('li.active a'); + + if (jQuery(tjUcmCurrentFormTab).next('li') == undefined) + { + jQuery("#previous_button").attr('disabled', true); + } + else + { + jQuery("#previous_button").attr('disabled', false); + } + + if (jQuery(tjUcmCurrentFormTab).prev('li') == undefined) + { + jQuery("#next_button").attr('disabled', true); + } + else + { + jQuery("#next_button").attr('disabled', false); + } + + if (next) + { + jQuery('#tjucm_myTabTabs > .active').next('li').find('a').trigger('click'); + } + else + { + jQuery('#tjucm_myTabTabs > .active').next('li').prev('a').trigger('click'); + } + + + var nextTabName = jQuery('ul#' + getTabId).find('li.active').next('li').children('a').attr('href'); + var prevTabName = jQuery('ul#' + getTabId).find('li.active').prev('li').children('a').attr('href'); + + if (nextTabName == undefined) + { + jQuery('#next_button').attr('disabled', true); + } + else + { + jQuery('#next_button').attr('disabled', false); + } + + if (prevTabName == undefined) + { + jQuery('#previous_button').attr('disabled', true); + } + else + { + jQuery('#previous_button').attr('disabled', false); + } + + /* Once all fields are validated, enable Final Save*/ + steppedFormSave('item-form', 'draft', 1); + + if (navDirection == "next") + { + jQuery('#' + getTabId + ' > .active').next('li').find('a').trigger('click'); + } + + if (navDirection == "prev") + { + jQuery('#' + getTabId + ' > .active').prev('li').find('a').trigger('click'); + } +} diff --git a/src/components/com_tjucm/administrator/assets/js/tjucm_ajaxForm_save.js b/src/components/com_tjucm/administrator/assets/js/tjucm_ajaxForm_save.js deleted file mode 100644 index f3c72d7f..00000000 --- a/src/components/com_tjucm/administrator/assets/js/tjucm_ajaxForm_save.js +++ /dev/null @@ -1,217 +0,0 @@ -/*Variable to store the updated options of related field*/ -var tjucmRelatedFieldUpdatedOptions = ''; - -/* This function executes for autosave form */ -jQuery(document).ready(function() -{ - /*Code to get item state*/ - var itemState = jQuery('#itemState').val(); - - /*Code for auto save on blur event add new record or editing draft record only*/ - if (itemState == '' || itemState === 0) - { - var tjUcmAutoSave = jQuery('#item-form #tjucm-autosave').val(); - - /*Check if auto save is enabled for UCM type*/ - if (tjUcmAutoSave == 1) - { - /* Save form values */ - jQuery("#item-form").on("change select", ":input", function(){ - steppedFormSave(this.form.id, "draft", 0); - }); - - /* To save calendar field value */ - jQuery("#item-form .field-calendar input:text").blur(function(){ - var tjUcmFormDirty = jQuery('#item-form').hasClass('dirty'); - - if (tjUcmFormDirty === true) - { - steppedFormSave(this.form.id, "draft", 0); - } - }); - } - } - - /*Update the options of related field for new record of subform*/ - jQuery(document).on('subform-row-add', function(event, row){ - var tjucmSubFormCount = jQuery(row).attr('data-group').replace(jQuery(row).attr('data-base-name'), ""); - - jQuery.each(tjucmRelatedFieldUpdatedOptions, function(index, value) { - if (value.templateId) - { - var tjucmNewTemplateId = value.templateId.replace("XXX_XXX", tjucmSubFormCount); - jQuery(row).find("#"+tjucmNewTemplateId).html(''); - jQuery.each(value.options, function(i, val) { - jQuery(row).find("#"+tjucmNewTemplateId).append(''); - }); - - jQuery(row).find("#"+tjucmNewTemplateId).trigger("liszt:updated"); - } - }); - }); -}); - -/* This function carries stepped saving via ajax */ -function steppedFormSave(form_id, status, showDraftSuccessMsg) -{ - /* For AJAX save need to add this to prevent popup message for page unload*/ - window.onbeforeunload = null; - - /* For AJAX save need to assign values to the editor field containers*/ - jQuery("#item-form .toggle-editor a").each(function(index) { - this.click(); - }); - - var item_basic_form = jQuery('#' + form_id); - var promise = false; - jQuery('#form_status').val(status); - - if ('save' == status) { - - if(confirm(Joomla.JText._("COM_TJUCM_ITEMFORM_SUBMIT_ALERT"))) - { - /* code to remove the class added by are-you-sure alert box */ - jQuery('#item-form').removeClass('dirty'); - - if (!document.formvalidator.isValid('#item-form')) - { - jQuery('#finalSave').attr('disabled', false); - jQuery('#draftSave').attr('disabled', false); - jQuery("html, body").animate({ scrollTop: 0 }, "slow"); - - return false; - } - } - else - { - jQuery('#draftSave').attr('disabled', false); - jQuery('#finalSave').attr('disabled', false); - jQuery("html, body").animate({ scrollTop: 0 }, "slow"); - - return false; - } - } - - if(item_basic_form) - { - jQuery(item_basic_form).ajaxSubmit({ - datatype:'JSON', - async: false, - success: function(data) { - var returnedData = JSON.parse(data); - - if (returnedData.messages !== null) - { - if (returnedData.messages.error !== null) - { - jQuery.each(returnedData.messages.error, function(index, value) { - Joomla.renderMessages({'error':[value]}); - }); - - jQuery("html, body").animate({ scrollTop: 0 }, "slow"); - } - } - - if (returnedData.message !== null && returnedData.message != '') - { - Joomla.renderMessages({'info':[returnedData.message]}); - - jQuery("html, body").animate({ scrollTop: 0 }, "slow"); - } - - if (returnedData.data !== null) - { - jQuery('#item-form').removeClass('dirty'); - jQuery("#recordId").val(returnedData.data.id); - - if ('save' == status) - { - jQuery("#finalSave").attr("disabled", "disabled"); - Joomla.renderMessages({'success':[Joomla.JText._('COM_TJUCM_MSG_ON_SAVED_FORM')]}); - jQuery('html, body').animate({ - scrollTop: jQuery("#system-message-container").offset().top-40 - }, "slow"); - } - else - { - promise = true; - - if (showDraftSuccessMsg === "1") - { - jQuery("#draft_msg").show(); - setTimeout(function() { jQuery("#draft_msg").hide(); }, 5000); - } - } - - /* Update item id in the URL if the data is stored successfully */ - var tjucmUrl = window.location.href.split('#')[0]; - var tjucmUrlSeparator = (tjucmUrl.indexOf("?")===-1)?"?":"&"; - var tjucmNewParam = "id=" + returnedData.data.id; - - /* Add content_id in ucmsubform records */ - jQuery.each(returnedData.data.childContentIds, function(i, val) { - jQuery("input[name='"+val.elementName+"']").val(val.content_id); - }); - - /* Add content_id in ucmsubform records */ - tjucmRelatedFieldUpdatedOptions = returnedData.data.relatedFieldOptions; - jQuery.each(returnedData.data.relatedFieldOptions, function(index, value) { - jQuery("#"+value.elementId).html(''); - - jQuery.each(value.options, function(i, val) { - var tjucmSelectedFieldOption = ''; - - if (val.selected == '1'){ - tjucmSelectedFieldOption = ' selected="selected" '; - } - - jQuery("#"+value.elementId).append(''); - }); - - jQuery("#"+value.elementId).trigger("liszt:updated"); - }); - - if (!(tjucmUrl.indexOf(tjucmNewParam) >= 0)) - { - tjucmUrl+=tjucmUrlSeparator+tjucmNewParam; - } - - history.pushState(null, null, tjucmUrl); - } - - jQuery('#draftSave').attr('disabled', false); - jQuery('#finalSave').attr('disabled', false); - - /* After AJAX save need to toggle back the editors as we had previoussly toggled them to post the values*/ - jQuery("#item-form .toggle-editor a").each(function(index) { - this.click(); - }); - } - }); - } - - return promise; -} - -/*Function triggered by clicking on the "Save and next"*/ -function itemformactions(tab_id, navDirection) -{ - var getTabId = tab_id + "Tabs"; - - var currentTabName = jQuery('ul#' + getTabId).find('li.active a').attr('href'); - var nextTabName = jQuery('ul#' + getTabId).find('li.active').next('li').children('a').attr('href'); - var prevTabName = jQuery('ul#' + getTabId).find('li.active').prev('li').children('a').attr('href'); - - /* Once all fields are validated, enable Final Save*/ - steppedFormSave('item-form', 'draft', 1); - - if (navDirection == "next") - { - jQuery('#' + getTabId + ' > .active').next('li').find('a').trigger('click'); - } - - if (navDirection == "prev") - { - jQuery('#' + getTabId + ' > .active').prev('li').find('a').trigger('click'); - } -} diff --git a/src/components/com_tjucm/administrator/models/forms/type.xml b/src/components/com_tjucm/administrator/models/forms/type.xml index 705170c4..3497a681 100644 --- a/src/components/com_tjucm/administrator/models/forms/type.xml +++ b/src/components/com_tjucm/administrator/models/forms/type.xml @@ -15,7 +15,7 @@ - + diff --git a/src/components/com_tjucm/administrator/tables/item.php b/src/components/com_tjucm/administrator/tables/item.php index 4e13ccb9..ba04039c 100644 --- a/src/components/com_tjucm/administrator/tables/item.php +++ b/src/components/com_tjucm/administrator/tables/item.php @@ -34,7 +34,7 @@ public function __construct(&$db) /** * Overloaded bind function to pre-process the params. * - * @param array $array Named array + * @param array $data Named array * @param mixed $ignore Optional array or list of parameters to ignore * * @return null|string null is operation was satisfactory, otherwise returns an error @@ -42,55 +42,20 @@ public function __construct(&$db) * @see JTable:bind * @since 1.5 */ - public function bind($array, $ignore = '') + public function bind($data, $ignore = '') { - if ($array['id'] == 0) + if (empty($data['id'])) { - $array['created_by'] = !empty($array['created_by']) ? $array['created_by'] : JFactory::getUser()->id; - $array['created_date'] = JFactory::getDate()->toSql(); + $data['created_by'] = JFactory::getUser()->id; + $data['created_date'] = JFactory::getDate()->toSql(); } - - $array['modified_by'] = JFactory::getUser()->id; - $array['modified_date'] = JFactory::getDate()->toSql(); - - if (isset($array['params']) && is_array($array['params'])) - { - $registry = new JRegistry; - $registry->loadArray($array['params']); - $array['params'] = (string) $registry; - } - - if (isset($array['metadata']) && is_array($array['metadata'])) - { - $registry = new JRegistry; - $registry->loadArray($array['metadata']); - $array['metadata'] = (string) $registry; - } - - if (!JFactory::getUser()->authorise('core.admin', 'com_tjucm.item.' . $array['id'])) - { - $actions = JAccess::getActionsFromFile( - JPATH_ADMINISTRATOR . '/components/com_tjucm/access.xml', - "/access/section[@name='item']/" - ); - $default_actions = JAccess::getAssetRules('com_tjucm.item.' . $array['id'])->getData(); - $array_jaccess = array(); - - foreach ($actions as $action) - { - $array_jaccess[$action->name] = $default_actions[$action->name]; - } - - $array['rules'] = $this->JAccessRulestoArray($array_jaccess); - } - - // Bind the rules for ACL where supported. - if (isset($array['rules']) && is_array($array['rules'])) + else { - $this->setRules($array['rules']); + $data['modified_by'] = JFactory::getUser()->id; + $data['modified_date'] = JFactory::getDate()->toSql(); } - return parent::bind($array, $ignore); + return parent::bind($data, $ignore); } /** diff --git a/src/components/com_tjucm/administrator/views/item/tmpl/edit.php b/src/components/com_tjucm/administrator/views/item/tmpl/edit.php index 01050760..1cf14d63 100644 --- a/src/components/com_tjucm/administrator/views/item/tmpl/edit.php +++ b/src/components/com_tjucm/administrator/views/item/tmpl/edit.php @@ -21,7 +21,7 @@ $lang->load('com_tjucm', JPATH_SITE); $doc = JFactory::getDocument(); $doc->addScript(JUri::root() . 'administrator/components/com_tjucm/assets/js/jquery.form.js'); -$doc->addScript(JUri::root() . 'administrator/components/com_tjucm/assets/js/tjucm_ajaxForm_save.js'); +$doc->addScript(JUri::root() . 'administrator/components/com_tjucm/assets/js/itemform.js'); $doc->addScript(JUri::root() . 'administrator/components/com_tjucm/assets/js/tjfield.js'); $jinput = JFactory::getApplication(); diff --git a/src/components/com_tjucm/languages/site/en-GB/en-GB.com_tjucm.ini b/src/components/com_tjucm/languages/site/en-GB/en-GB.com_tjucm.ini index df106b4f..5143f3af 100644 --- a/src/components/com_tjucm/languages/site/en-GB/en-GB.com_tjucm.ini +++ b/src/components/com_tjucm/languages/site/en-GB/en-GB.com_tjucm.ini @@ -169,3 +169,11 @@ COM_TJUCM_FILE_DELETE_ERROR="Sorry the file could not be deleted, please try aga COM_TJUCM_FILE_DELETE_CONFIRM="Are you sure you want to delete this file?" COM_TJUCM_MSG_FOR_AUTOSAVE_FEATURE_DISABLED="Your changes will be lost if you don’t save them. Submit the form to update your changes."; COM_TJUCM_NO_FORM_DATA="No data to save"; + +; Since 1.2.1 +COM_TJUCM_FORM_VALIDATATION_FAILED="Provided data is not valid" +COM_TJUCM_FORM_SAVE_FAILED="Unable to process the request" +COM_TJUCM_FORM_SAVE_FAILED_CLIENT_REQUIRED="Unable to process the request as client is not provided" +COM_TJUCM_FORM_SAVE_FAILED_RECORD_ID_REQUIRED="Unable to process the request as record id is not provided" +COM_TJUCM_FORM_SAVE_FAILED_FIELD_DATA_REQUIRED="Unable to process the request as field data is not provided" +COM_TJUCM_FORM_SAVE_FAILED_AUTHORIZATION_ERROR="You are not authorized to perform this operation." diff --git a/src/components/com_tjucm/media/js/com_tjucm.js b/src/components/com_tjucm/media/js/com_tjucm.js new file mode 100755 index 00000000..b2d3aa99 --- /dev/null +++ b/src/components/com_tjucm/media/js/com_tjucm.js @@ -0,0 +1,9 @@ +// Declare Namespace +/** global: window */ +window.com_tjucm = {}; +var Services = function () {}; +var UI = function () {}; +window.com_tjucm.Services = new Services(); +window.com_tjucm.UI = new UI(); +Services = undefined; +UI = undefined; \ No newline at end of file diff --git a/src/components/com_tjucm/media/js/core/base.js b/src/components/com_tjucm/media/js/core/base.js new file mode 100755 index 00000000..dae0116e --- /dev/null +++ b/src/components/com_tjucm/media/js/core/base.js @@ -0,0 +1,97 @@ +'use strict'; +/** global: com_tjucm */ +com_tjucm.Services.Base = Class.extend({ + /** + * @param string url API Request URL + * @param config object Configuration object + * @param cb function Callback function + */ + get: function (url, config, cb) { + config = config || {}; + config.headers = config.headers || {}; + if (typeof cb !== 'function') { + throw "base expects callback to be function"; + } + + return jQuery.ajax({ + type: "GET", + url: url, + headers: config.headers, + beforeSend: function () { + }, + success: function (res) { + cb(null, res); + }, + error: function (err) { + cb(err, null); + } + }); + }, + /** + * @param string url API Request URL + * @param data object Data to post + * @param config object Configuration object which have headers + * @param cb function Callback function + */ + post: function (url, data, config, cb) { + data = data || {}; + config = config || {}; + config.headers = config.headers || {}; + + if (typeof cb !== 'function') { + throw "base expects callback to be function"; + } + + config.contentType = typeof config.contentType != "undefined" ? config.contentType : 'application/x-www-form-urlencoded; charset=UTF-8'; + config.processData = typeof config.processData != "undefined" ? config.processData : true; + + return jQuery.ajax({ + type: "POST", + url: url, + data: data, + contentType: config.contentType, + processData: config.processData, + headers: config.headers, + beforeSend: function () { + }, + success: function (res) { + cb(null, res); + }, + error: function (err) { + cb(err, null); + } + }); + }, + /** + * @param string url API Request URL + * @param config object Configuration object which have headers + * @param cb function Callback function + */ + patch: function (url, data, config, cb) { + data = data || {}; + config = config || {}; + config.headers = config.headers || {}; + + if (typeof cb !== 'function') { + throw "base expects callback to be function"; + } + + if (typeof data === 'object') { + data = JSON.stringify(data); + } + return jQuery.ajax({ + type: "PATCH", + url: url, + data: data, + headers: config.headers, + beforeSend: function () { + }, + success: function (res) { + cb(null, res); + }, + error: function (xhr) { + cb(xhr, null); + } + }); + } +}); \ No newline at end of file diff --git a/src/components/com_tjucm/media/js/core/class.js b/src/components/com_tjucm/media/js/core/class.js new file mode 100755 index 00000000..e718893b --- /dev/null +++ b/src/components/com_tjucm/media/js/core/class.js @@ -0,0 +1,68 @@ +/* Simple JavaScript Inheritance + * By John Resig http://ejohn.org/ + * MIT Licensed. + */ +// Inspired by base2 and Prototype +(function () { + /* istanbul ignore next */ + var initializing = false, + fnTest = /xyz/.test(function () { + xyz; + }) ? /\b_super\b/ : /.*/; + + // The base Class implementation (does nothing) + this.Class = function () {}; + + // Create a new Class that inherits from this class + Class.extend = function (prop) { + var _super = this.prototype; + + // Instantiate a base class (but only create the instance, + // don't run the init constructor) + initializing = true; + var prototype = new this(); + initializing = false; + + // Copy the properties over onto the new prototype + for (var name in prop) { + // Check if we're overwriting an existing function + prototype[name] = typeof prop[name] == "function" && + typeof _super[name] == "function" && fnTest.test(prop[name]) ? + (function (name, fn) { + return function () { + var tmp = this._super; + + // Add a new ._super() method that is the same method + // but on the super-class + this._super = _super[name]; + + // The method only need to be bound temporarily, so we + // remove it when we're done executing + var ret = fn.apply(this, arguments); + this._super = tmp; + + return ret; + }; + })(name, prop[name]) : + prop[name]; + } + + // The dummy class constructor + function Class() { + // All construction is actually done in the init method + if (!initializing && this.init) + this.init.apply(this, arguments); + } + + // Populate our constructed prototype object + Class.prototype = prototype; + + // Enforce the constructor to be what we expect + Class.prototype.constructor = Class; + + // And make this class extendable + Class.extend = arguments.callee; + + return Class; + }; +})(); \ No newline at end of file diff --git a/src/components/com_tjucm/media/js/load_js.php b/src/components/com_tjucm/media/js/load_js.php new file mode 100755 index 00000000..b7007e06 --- /dev/null +++ b/src/components/com_tjucm/media/js/load_js.php @@ -0,0 +1,23 @@ + + * @copyright Copyright (C) 2009 - 2019 Techjoomla. All rights reserved. + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +// No direct access +defined('_JEXEC') or die('Restricted access'); + +$doc = JFactory::getDocument(); + +// Add Javascript vars in array +$doc->addScriptOptions('tjucm', array()); + +// Load JS files +JHtml::script(JUri::root() . 'media/com_tjucm/js/core/class.js'); +JHtml::script(JUri::root() . 'media/com_tjucm/js/com_tjucm.js'); +JHtml::script(JUri::root() . 'media/com_tjucm/js/core/base.js'); +JHtml::script(Juri::root() . 'media/com_tjucm/js/services/item.js'); diff --git a/src/components/com_tjucm/media/js/services/item.js b/src/components/com_tjucm/media/js/services/item.js new file mode 100755 index 00000000..d287e809 --- /dev/null +++ b/src/components/com_tjucm/media/js/services/item.js @@ -0,0 +1,39 @@ +/* + * @package TJ-UCM + * @author Techjoomla + * @copyright Copyright (c) 2009-2019 TechJoomla. All rights reserved + * @license GNU General Public License version 2, or later + */ +'use strict'; +/** global: com_tjucm */ +com_tjucm.Services.Item = new (com_tjucm.Services.Base.extend({ + createNewRecordUrl: window.tjSiteRoot + "index.php?option=com_tjucm&format=json&task=itemform.save", + saveFormDataUrl: window.tjSiteRoot + "index.php?option=com_tjucm&format=json&task=itemform.saveFormData", + autoSaveFieldDataUrl: window.tjSiteRoot + "index.php?option=com_tjucm&format=json&task=itemform.saveFieldData", + getRelatedFieldUpdatedOptionsUrl: window.tjSiteRoot + "index.php?option=com_tjucm&format=json&task=itemform.getRelatedFieldOptions", + config: { + headers: {} + }, + response: { + "success": "", + "message": "" + }, + create: function (ucmTypeData, callback){ + this.config.processData = false; + this.config.contentType = false; + this.post(this.createNewRecordUrl, ucmTypeData, this.config, callback); + }, + saveFieldData: function (ucmFormData, callback) { + this.config.processData = false; + this.config.contentType = false; + this.post(this.autoSaveFieldDataUrl, ucmFormData, this.config, callback); + }, + getUpdatedRelatedFieldsOptions: function (tjUcmItemFormData, callback){ + this.post(this.getRelatedFieldUpdatedOptionsUrl, tjUcmItemFormData, this.config, callback); + }, + saveFormData: function (ucmFormData, callback) { + this.config.processData = false; + this.config.contentType = false; + this.post(this.saveFormDataUrl, ucmFormData, this.config, callback); + } +})); diff --git a/src/components/com_tjucm/site/controllers/itemform.json.php b/src/components/com_tjucm/site/controllers/itemform.json.php new file mode 100644 index 00000000..2f8818e0 --- /dev/null +++ b/src/components/com_tjucm/site/controllers/itemform.json.php @@ -0,0 +1,439 @@ + + * @copyright Copyright (C) 2009 - 2019 Techjoomla. All rights reserved. + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +// No direct access +defined('_JEXEC') or die; +use Joomla\CMS\Factory; +use Joomla\CMS\User\User; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Session\Session; +use Joomla\CMS\Router\Route; + +jimport('joomla.filesystem.file'); + +require_once JPATH_SITE . "/components/com_tjfields/filterFields.php"; + +/** + * Item controller class. + * + * @since 1.6 + */ +class TjucmControllerItemForm extends JControllerForm +{ + // Use imported Trait in model + use TjfieldsFilterField; + + /** + * Constructor + * + * @throws Exception + */ + public function __construct() + { + $app = Factory::getApplication(); + $this->client = $app->input->get('client', '', 'STRING'); + + // If client is empty then get client from post data + if (empty($this->client)) + { + $this->client = $app->input->post->get('client', '', 'STRING'); + } + + // Get UCM type id for the client + if (!empty($this->client)) + { + JLoader::import('components.tables.type', JPATH_ADMINISTRATOR); + $tjUcmTypeTable = JTable::getInstance('Type', 'TjucmTable', array('dbo', Factory::getDbo())); + $tjUcmTypeTable->load(array('unique_identifier' => $this->client)); + + if (!empty($tjUcmTypeTable->id)) + { + $this->typeId = $tjUcmTypeTable->unique_identifier; + } + } + + parent::__construct(); + } + + /** + * Method to check if you can add a new record. + * + * Extended classes can override this if necessary. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since 12.2 + */ + protected function allowAdd($data = array()) + { + $user = Factory::getUser(); + + return $user->authorise('core.type.createitem', 'com_tjucm.type.' . $this->ucmTypeId); + } + + /** + * Method to check if you can edit an existing record. + * + * Extended classes can override this if necessary. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key; default is id. + * + * @return boolean + * + * @since 12.2 + */ + protected function allowEdit($data = array(), $key = 'id') + { + $user = Factory::getUser(); + $edit = $user->authorise('core.type.edititem', 'com_tjucm.type.' . $this->ucmTypeId); + $editOwn = $user->authorise('core.type.editownitem', 'com_tjucm.type.' . $this->ucmTypeId); + + if ($edit || $editOwn) + { + return true; + } + else + { + return false; + } + } + + /** + * Function to save ucm data item + * + * @param int $key admin approval 1 or 0 + * @param int $urlVar id of user who has enrolle the user + * + * @return boolean true or false + * + * @since 1.0.0 + */ + public function save($key = null, $urlVar = null) + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $post = Factory::getApplication()->input->post; + $model = $this->getModel('itemform'); + + $data = array(); + $data['id'] = $post->get('id', 0, 'INT'); + + if (empty($data['id'])) + { + $client = $post->get('client', '', 'STRING'); + + // For new record if there is no client specified or invalid client is given then do not process the request + if ($client == '' || empty($this->typeId)) + { + echo new JResponseJson('', JText::_('COM_TJUCM_FORM_SAVE_FAILED_CLIENT_REQUIRED'), true); + } + + $data['client'] = $client; + } + + $data['state'] = $post->get('state', 0, 'INT'); + $data['draft'] = $post->get('draft', 0, 'INT'); + $data['parent_id'] = $post->get('parent_id', 0, 'INT'); + + try + { + $form = $model->getForm(); + $data = $model->validate($form, $data); + + if ($data == false) + { + $errors = $model->getErrors(); + $this->processErrors($errors); + + echo new JResponseJson('', JText::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), true); + } + + if ($model->save($data)) + { + $result['id'] = $model->getState($model->getName() . '.id'); + + + echo new JResponseJson($result, JText::_('COM_TJUCM_ITEM_SAVED_SUCCESSFULLY')); + } + else + { + $errors = $model->getErrors(); + $this->processErrors($errors); + echo new JResponseJson('', JText::_('COM_TJUCM_FORM_SAVE_FAILED'), true); + } + } + catch (Exception $e) + { + echo new JResponseJson($e); + } + } + + public function saveFieldData() + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $app = Factory::getApplication(); + $post = $app->input->post; + $recordId = $post->get('recordid', 0, 'INT'); + $client = $post->get('client', '', 'STRING'); + $fieldData = $post->get('jform', array(), 'ARRAY'); + + $model = $this->getModel('itemform'); + + if (empty($fieldData)) + { + $fieldData = $app->input->files->get('jform'); + } + + if (empty($fieldData)) + { + $app->enqueueMessage(JText::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), 'error'); + echo new JResponseJson(null); + } + + try + { + // Create JForm object for the field + $form = $model->getFieldForm($fieldData); + + // Validate field data + $data = $model->validate($form, $fieldData); + + if ($data == false) + { + $errors = $model->getErrors(); + $this->processErrors($errors); + + echo new JResponseJson(null); + } + + $table = $model->getTable(); + $table->load($recordId); + + $fieldData = array(); + $fieldData['content_id'] = $recordId; + $fieldData['fieldsvalue'] = $data; + $fieldData['client'] = $client; + $fieldData['created_by'] = $table->created_by; + + // If data is valid then save the data into DB + $response = $model->saveExtraFields($fieldData); + + echo new JResponseJson($response); + } + catch (Exception $e) + { + echo new JResponseJson($e); + } + } + + public function saveFormData() + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $app = Factory::getApplication(); + $post = $app->input->post; + $recordId = $post->get('recordid', 0, 'INT'); + $client = $post->get('client', '', 'STRING'); + $formData = $post->get('jform', array(), 'ARRAY'); + $filesData = $app->input->files->get('jform', array(), 'ARRAY'); + $formData = array_merge_recursive($formData, $filesData); + $section = $post->get('tjUcmFormSection', '', 'STRING'); + + if (empty($formData) || empty($client)) + { + $app->enqueueMessage(JText::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), 'error'); + echo new JResponseJson(null); + } + + try + { + // Create JForm object for the field + $model = $this->getModel('itemform'); + $formData['client'] = $client; + $form = $model->getTypeForm($formData); + + if (!empty($section)) + { + $formData['section'] = $section; + $form = $model->getSectionForm($formData); + } + else + { + $form = $model->getTypeForm($formData); + } + + // Validate field data + $data = $model->validate($form, $formData); + + if ($data == false) + { + $errors = $model->getErrors(); + $this->processErrors($errors); + + echo new JResponseJson(null); + } + + $table = $model->getTable(); + $table->load($recordId); + + $formData = array(); + $formData['content_id'] = $recordId; + $formData['fieldsvalue'] = $data; + $formData['client'] = $client; + $formData['created_by'] = $table->created_by; + + // If data is valid then save the data into DB + $response = $model->saveExtraFields($formData); + + echo new JResponseJson($response); + } + catch (Exception $e) + { + echo new JResponseJson($e); + } + } + + /** + * Function to save ucm item field data + * + * @param int $key admin approval 1 or 0 + * @param int $urlVar id of user who has enrolle the user + * + * @return boolean true or false + * + * @since 1.0.0 + */ + public function saveItemFieldData($key = null, $urlVar = null) + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $post = Factory::getApplication()->input->post; + $model = $this->getModel('itemform'); + + $data = array(); + $data['id'] = $post->get('id', 0, 'INT'); + + if (empty($data['id'])) + { + $client = $post->get('client', '', 'STRING'); + + // For new record if there is no client specified then do not process the request + if ($client == '') + { + echo new JResponseJson('', JText::_('COM_TJUCM_FORM_SAVE_FAILED'), true); + } + + $data['created_by'] = Factory::getUser()->id; + $data['created_date'] = Factory::getDate()->toSql(); + $data['client'] = $client; + } + else + { + $data['modified_by'] = Factory::getUser()->id; + $data['modified_date'] = Factory::getDate()->toSql(); + } + + $data['state'] = $post->get('state', 0, 'INT'); + $data['draft'] = $post->get('draft', 0, 'INT'); + + try + { + $form = $model->getForm(); + $data = $model->validate($form, $data); + + if ($data == false) + { + $errors = $model->getErrors(); + $this->processErrors($errors); + + echo new JResponseJson('', JText::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), true); + } + + if ($model->save($data)) + { + $result['id'] = $model->getState($model->getName() . '.id'); + + echo new JResponseJson($result, JText::_('COM_TJUCM_ITEM_SAVED_SUCCESSFULLY')); + } + else + { + $errors = $model->getErrors(); + $this->processErrors($errors); + echo new JResponseJson('', JText::_('COM_TJUCM_FORM_SAVE_FAILED'), true); + } + } + catch (Exception $e) + { + echo new JResponseJson($e); + } + } + + /** + * Method to procees errors + * + * @param ARRAY $errors ERRORS + * + * @return void + * + * @since 1.0 + */ + private function processErrors($errors) + { + $app = Factory::getApplication(); + + if (!empty($errors)) + { + $code = 500; + $msg = array(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $code = $errors[$i]->getCode(); + $msg[] = $errors[$i]->getMessage(); + } + else + { + $msg[] = $errors[$i]; + } + } + + $app->enqueueMessage(implode("\n", $msg), 'error'); + } + } + + public function getRelatedFieldOptions() + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $app = Factory::getApplication(); + $post = $app->input->post; + $model = $this->getModel('itemform'); + + $client = $post->get('client', '', 'STRING'); + $contentId = $post->get('content_id', 0, 'INT'); + + if (empty($client) || empty($contentId)) + { + echo new JResponseJson(null); + } + + $app->input->set('id', $contentId); + $updatedOptionsForRelatedField = $model->getUdatedRelatedFieldOptions($client, $contentId); + + echo new JResponseJson($updatedOptionsForRelatedField); + } +} diff --git a/src/components/com_tjucm/site/models/forms/fielddata.xml b/src/components/com_tjucm/site/models/forms/fielddata.xml new file mode 100644 index 00000000..65281da5 --- /dev/null +++ b/src/components/com_tjucm/site/models/forms/fielddata.xml @@ -0,0 +1,3 @@ + + + diff --git a/src/components/com_tjucm/site/models/forms/itemform.xml b/src/components/com_tjucm/site/models/forms/itemform.xml index dd3eb82c..67432aa0 100644 --- a/src/components/com_tjucm/site/models/forms/itemform.xml +++ b/src/components/com_tjucm/site/models/forms/itemform.xml @@ -1,26 +1,27 @@
-
- - - - - - - - - - - - -
-
- - -
+
+ + + + + + + + + + + + + +
+
+ + +
diff --git a/src/components/com_tjucm/site/models/itemform.php b/src/components/com_tjucm/site/models/itemform.php index b17fed59..985cf079 100644 --- a/src/components/com_tjucm/site/models/itemform.php +++ b/src/components/com_tjucm/site/models/itemform.php @@ -28,7 +28,7 @@ * * @since 1.6 */ -class TjucmModelItemForm extends JModelForm +class TjucmModelItemForm extends JModelAdmin { private $item = null; @@ -374,6 +374,151 @@ public function getForm($data = array(), $loadData = true) return $form; } + /** + * Method to get the field form object. + * + * @param array $data An optional array of data for the form to interogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getFieldForm($data = array(), $loadData = true) + { + // Path of empty form XML to create form object dynamically + $formPath = JPATH_SITE . '/components/com_tjucm/models/forms/fielddata.xml'; + + // Get the form. + $form = $this->loadForm( + array_key_first($data), $formPath, + array('control' => 'jform', + 'load_data' => $loadData, + ) + ); + + if (empty($form)) + { + return false; + } + else + { + $form->addFieldPath('administrator/components/com_tjfields/models/fields'); + $form->addRulePath('administrator/components/com_tjfields/models/rules'); + + $fieldName = array_key_first($data); + $fieldNamePart = explode('_', str_replace('com_tjucm_', '', $fieldName)); + unset($fieldNamePart[array_key_last($fieldNamePart)]); + $parentFormPath = JPATH_SITE . "/administrator/components/com_tjucm/models/forms/" . implode("_", $fieldNamePart) . "_extra.xml"; + + // Get parent form. + $parentForm = $this->loadForm( + 'com_tjucm.itemform', $parentFormPath, + array('control' => 'jform', + 'load_data' => false, + ) + ); + + // Get the field XML from parent form + $fieldXml = $parentForm->getFieldXml($fieldName); + + // Set the field XML to the field form + $form->setField($fieldXml); + $form->setvalue($fieldName, '', $data[$fieldName]); + } + + return $form; + } + + public function getTypeForm($data = array(), $loadData = true) + { + $clientPart = explode(".", $data['client']); + + // Path of empty form XML to create form object dynamically + $formPath = JPATH_SITE . '/components/com_tjucm/models/forms/' . $clientPart[1] . 'form_extra.xml'; + + // Get the form. + $form = $this->loadForm( + $data['client'], $formPath, + array('control' => 'jform', + 'load_data' => $loadData, + ) + ); + + if (empty($form)) + { + return false; + } + + return $form; + } + + public function getSectionForm($data = array(), $loadData = true) + { + if (empty($data['client']) || empty($data['section'])) + { + return false; + } + + // Create xml with the fieldset of provided section + $newXML = new SimpleXMLElement('
'); + $newXmlFilePath = JPATH_SITE . '/components/com_tjucm/models/forms/tempfieldsetform.xml'; + + // Get path of parent UCM type XML + $fieldNamePart = explode('.', $data['client']); + $parentFormPath = JPATH_SITE . "/administrator/components/com_tjucm/models/forms/" . $fieldNamePart[1] . "_extra.xml"; + + // Get parent form. + $parentForm = $this->loadForm( + 'com_tjucm.itemform', $parentFormPath, + array('control' => 'jform', + 'load_data' => false, + ) + ); + + // Get the fieldset XML from parent form + $formXml = $parentForm->getXml(); + $fieldsetXml = $formXml->xpath('//fieldset[@name="' . $data['section'] . '" and not(ancestor::field/form/*)]'); + + if ($fieldsetXml[0] instanceof \SimpleXMLElement) + { + $newFieldsetXml = $newXML->addChild('fieldset'); + + foreach ($fieldsetXml[0]->children() as $child) + { + $fieldXml = $newFieldsetXml->addChild('field'); + + foreach ($child->attributes() as $attributeName => $attributeValue) + { + $fieldXml->addAttribute($attributeName, $attributeValue); + } + } + } + + $newXML->asXML($newXmlFilePath); + + // Get parent form. + $sectionForm = $this->loadForm( + 'com_tjucm.itemform.section', $newXmlFilePath, + array('control' => 'jform', + 'load_data' => false, + ) + ); + + // Delete temp xml once its object is created + if (JFile::exists($newXmlFilePath)) + { + JFile::delete($newXmlFilePath); + } + + if (empty($sectionForm)) + { + return false; + } + + return $sectionForm; + } + /** * Method to get the data that should be injected in the form. * @@ -399,6 +544,157 @@ protected function loadFormData() return $data; } + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $user = JFactory::getUser(); + + // Guest users are not allowed to add the records + if (empty($user->id)) + { + $this->setError(JText::_('COM_TJUCM_FORM_SAVE_FAILED_AUTHORIZATION_ERROR')); + + return false; + } + + // Get instance of UCM type table + JLoader::import('components.com_tjucm.tables.type', JPATH_ADMINISTRATOR); + $tjUcmTypeTable = JTable::getInstance('Type', 'TjucmTable', array('dbo', Factory::getDbo())); + + // Check and assign valid client and type_id to the record + if (!empty($data['type_id']) || !empty($data['client'])) + { + if ($data['client'] != '') + { + $tjUcmTypeTable->load(array('unique_identifier' => $data['client'])); + $data['type_id'] = $tjUcmTypeTable->id; + } + else + { + $tjUcmTypeTable->load(array('id' => $data['type_id'])); + $data['client'] = $tjUcmTypeTable->unique_identifier; + } + } + else + { + $this->setError(JText::_('COM_TJUCM_FORM_SAVE_FAILED_CLIENT_REQUIRED')); + + return false; + } + + $ucmTypeParams = new Registry($tjUcmTypeTable->params); + + // Check if user is allowed to add/edit the record + if (empty($data['id'])) + { + $allowedCount = $ucmTypeParams->get('allowed_count', 0, 'INT'); + + // Check if the user is allowed to add record for given UCM type + $canAdd = $user->authorise('core.type.createitem', 'com_tjucm.type.' . $data['type_id']); + + if (!$canAdd) + { + $this->setError(JText::_('COM_TJUCM_FORM_SAVE_FAILED_AUTHORIZATION_ERROR')); + + return false; + } + + // Check allowed limit if its set for given UCM type + if (!empty($allowedCount)) + { + $canAdd = $this->allowedToAddTypeData($user->id, $data['client'], $allowedCount); + + if (!$canAdd) + { + $this->setError(JText::sprintf('COM_TJUCM_ALLOWED_COUNT_LIMIT', $allowedCount)); + + return false; + } + } + } + else + { + // Check if the user can edit this record + $canEdit = $user->authorise('core.type.edititem', 'com_tjucm.type.' . $data['type_id']); + $canEditOwn = $user->authorise('core.type.editownitem', 'com_tjucm.type.' . $data['type_id']); + + $itemTable = $this->getTable(); + $itemTable->load(array('id' => $data['id'])); + + if ($canEdit) + { + $authorised = true; + } + elseif (($canEditOwn) && ($itemTable->created_by == $user->id)) + { + $authorised = true; + } + + if (!$authorised) + { + $this->setError(JText::_('COM_TJUCM_FORM_SAVE_FAILED_AUTHORIZATION_ERROR')); + + return false; + } + } + + return parent::save($data); + } + + /** + * Method to save the form fields data. + * + * @param array $fieldData The form data. + * + * @return boolean True on success. + * + * @since 1.2.1 + */ + public function saveExtraFields($fieldData) + { + // If the data contain data related to cluster field or ownership field then update the ucm_data table accordingly + if (!empty($fieldData['fieldsvalue']) && !empty($fieldData['content_id'])) + { + $clusterFieldName = str_replace('.', '_', $fieldData['client']) . '_clusterclusterid'; + $ownerShipFieldName = str_replace('.', '_', $fieldData['client']) . '_ownershipcreatedby'; + $itemCategoryFieldName = str_replace('.', '_', $fieldData['client']) . '_itemcategory'; + + if (array_key_exists($clusterFieldName, $fieldData['fieldsvalue']) || array_key_exists($ownerShipFieldName, $fieldData['fieldsvalue']) || array_key_exists($itemCategoryFieldName, $fieldData['fieldsvalue'])) + { + JLoader::import('components.com_tjucm.tables.item', JPATH_ADMINISTRATOR); + $ucmItemTable = JTable::getInstance('Item', 'TjucmTable', array('dbo', JFactory::getDbo())); + $ucmItemTable->load(array('id' => $fieldData['content_id'])); + + if (!empty($fieldData['fieldsvalue'][$clusterFieldName])) + { + $ucmItemTable->cluster_id = $fieldData['fieldsvalue'][$clusterFieldName]; + } + + if (!empty($fieldData['fieldsvalue'][$ownerShipFieldName])) + { + $ucmItemTable->created_by = $fieldData['fieldsvalue'][$ownerShipFieldName]; + } + + if (!empty($fieldData['fieldsvalue'][$itemCategoryFieldName])) + { + $ucmItemTable->category_id = $fieldData['fieldsvalue'][$itemCategoryFieldName]; + } + + $ucmItemTable->store(); + } + } + + return TjfieldsFilterField::saveExtraFields($fieldData); + } + /** * Method to save the form data. * @@ -409,7 +705,7 @@ protected function loadFormData() * * @since 1.6 */ - public function save($data, $extra_jform_data = '') + public function saveTOBEDELETED($data, $extra_jform_data = '') { $app = JFactory::getApplication(); $user = JFactory::getUser(); @@ -1128,26 +1424,26 @@ public function getUcmSubFormFieldDataJson($parentRecordId, $efd) * * @return ARRAY */ - public function getUdatedRelatedFieldOptions($contentId) + public function getUdatedRelatedFieldOptions($client, $contentId) { - $db = JFactory::getDbo(); + if (empty($client) || empty($contentId)) + { + return false; + } - // Get UCM details from the content id - JLoader::import('components.com_tjucm.tables.item', JPATH_ADMINISTRATOR); - $ucmItemTable = JTable::getInstance('Item', 'TjucmTable', array('dbo', $db)); - $ucmItemTable->load(array('id' => $contentId)); + $db = JFactory::getDbo(); // Get all the fields of the UCM type JLoader::import('components.com_tjfields.models.fields', JPATH_ADMINISTRATOR); $tjFieldsModelFields = JModelLegacy::getInstance('Fields', 'TjfieldsModel', array('ignore_request' => true)); - $tjFieldsModelFields->setState("filter.client", $ucmItemTable->client); + $tjFieldsModelFields->setState("filter.client", $client); $tjFieldsModelFields->setState("filter.state", 1); $fields = $tjFieldsModelFields->getItems(); // Get data of the UCM form for given content id and ucm client JLoader::import('components.com_tjfields.helpers.tjfields', JPATH_SITE); $tjFieldsHelper = new TjfieldsHelper; - $ucmData = $tjFieldsHelper->FetchDatavalue(array('client' => $ucmItemTable->client, 'content_id' => $contentId)); + $ucmData = $tjFieldsHelper->FetchDatavalue(array('client' => $client, 'content_id' => $contentId)); // Get object of TJ-Fields field model JLoader::import('components.com_tjfields.models.field', JPATH_ADMINISTRATOR); diff --git a/src/components/com_tjucm/site/tjucm.php b/src/components/com_tjucm/site/tjucm.php index da477d81..3f7b4c4e 100644 --- a/src/components/com_tjucm/site/tjucm.php +++ b/src/components/com_tjucm/site/tjucm.php @@ -29,6 +29,10 @@ JLoader::load('TjucmHelper'); } +// Load required JS files +//JLoader::import('media.com_tjucm.js.load_js', JPATH_SITE); +require_once JPATH_SITE . '/media/com_tjucm/js/load_js.php'; + $path = JPATH_COMPONENT_ADMINISTRATOR . '/classes/' . 'funlist.php'; if (!class_exists('TjucmFunList')) @@ -38,6 +42,16 @@ JLoader::load('TjucmFunList'); } +// Load tjassets +jimport('joomla.filesystem.file'); +$tjStrapperPath = JPATH_SITE . '/media/techjoomla_strapper/tjstrapper.php'; + +if (JFile::exists($tjStrapperPath)) +{ + require_once $tjStrapperPath; + TjStrapper::loadTjAssets(); +} + JLoader::register('TjucmHelpersTjucm', JPATH_SITE . '/components/com_tjucm/helpers/tjucm.php'); JLoader::load('TjucmHelpersTjucm'); TjucmHelpersTjucm::getLanguageConstantForJs(); diff --git a/src/components/com_tjucm/site/views/itemform/tmpl/default.php b/src/components/com_tjucm/site/views/itemform/tmpl/default.php index 16da2f3a..6c94e717 100644 --- a/src/components/com_tjucm/site/views/itemform/tmpl/default.php +++ b/src/components/com_tjucm/site/views/itemform/tmpl/default.php @@ -21,7 +21,7 @@ $lang->load('com_tjucm', JPATH_SITE); $doc = JFactory::getDocument(); $doc->addScript(JUri::root() . 'administrator/components/com_tjucm/assets/js/jquery.form.js'); -$doc->addScript(JUri::root() . 'administrator/components/com_tjucm/assets/js/tjucm_ajaxForm_save.js'); +$doc->addScript(JUri::root() . 'administrator/components/com_tjucm/assets/js/itemform.js'); $doc->addScript(JUri::root() . 'administrator/components/com_tjfields/assets/js/tjfields.js'); JHtml::_('stylesheet', 'administrator/components/com_tjucm/assets/css/tjucm.css'); @@ -161,11 +161,11 @@ if (!empty($this->allow_draft_save)) { ?> - - @@ -178,14 +178,14 @@ if (($this->allow_auto_save || $this->allow_draft_save) && empty($itemState)) { ?> - " - onclick="javascript: this.disabled=true; steppedFormSave(this.form.id, 'draft', 1);" /> + onclick="javascript: this.disabled=true; tjUcmItemForm.saveSectionData();" /> " - id="finalSave" onclick="javascript: this.disabled=true; steppedFormSave(this.form.id, 'save', 1);" /> + id="finalSave" onclick="javascript: this.disabled=true; tjUcmItemForm.saveUcmFormData();" /> diff --git a/src/components/com_tjucm/site/views/items/tmpl/default_filter.php b/src/components/com_tjucm/site/views/items/tmpl/default_filter.php new file mode 100644 index 00000000..0f45fe2f --- /dev/null +++ b/src/components/com_tjucm/site/views/items/tmpl/default_filter.php @@ -0,0 +1,117 @@ + + * @copyright 2016 Techjoomla + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('JPATH_BASE') or die; + +$data = $displayData; + +// Receive overridable options +$data['options'] = !empty($data['options']) ? $data['options'] : array(); + +// Check if any filter field has been filled +$filters = false; +$filtered = false; +$search_filter = false; + +if (isset($data['view']->filterForm)) +{ + $filters = $data['view']->filterForm->getGroup('filter'); +} + +// Check if there are filters set. +if ($filters !== false) +{ + $filterFields = array_keys($filters); + $filled = false; + + foreach ($filterFields as $filterField) + { + $filterField = substr($filterField, 7); + $filter = $data['view']->getState('filter.' . $filterField); + + if (!empty($filter)) + { + $filled = $filter; + } + + if (!empty($filled)) + { + $filtered = true; + break; + } + } + + $search_filter = $filters['filter_search']; + unset($filters['filter_search']); +} + +$options = $data['options']; + +// Set some basic options +$customOptions = array( + 'filtersHidden' => isset($options['filtersHidden']) ? $options['filtersHidden'] : empty($data['view']->activeFilters) && !$filtered, + 'defaultLimit' => isset($options['defaultLimit']) ? $options['defaultLimit'] : JFactory::getApplication()->get('list_limit', 20), + 'searchFieldSelector' => '#filter_search', + 'orderFieldSelector' => '#list_fullordering', +); + +$data['options'] = array_unique(array_merge($customOptions, $data['options'])); + +$formSelector = !empty($data['options']['formSelector']) ? $data['options']['formSelector'] : '#adminForm'; + +// Load search tools +JHtml::_('searchtools.form', $formSelector, $data['options']); +?> + +
+
+
+ + +
+ input; ?> + +
+ +
+ +
+ + +
+ +
+
+
+ +
+ + + $field) : ?> + +
+ renderField(); ?> +
+ + + +
+
\ No newline at end of file From 3658e22225b51d06db06c7098f4b126048cd3265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cankush=5Fm=E2=80=9D?= Date: Fri, 4 Oct 2019 10:20:51 +0530 Subject: [PATCH 23/27] Task #199 feat: Save process optimisation --- .../administrator/assets/js/itemform.js | 202 ++++++++++++++---- src/components/com_tjucm/media/js/.htaccess | 3 + .../site/controllers/itemform.json.php | 68 ++++-- .../com_tjucm/site/models/forms/itemform.xml | 3 + .../site/views/itemform/tmpl/default.php | 21 +- 5 files changed, 225 insertions(+), 72 deletions(-) create mode 100755 src/components/com_tjucm/media/js/.htaccess diff --git a/src/components/com_tjucm/administrator/assets/js/itemform.js b/src/components/com_tjucm/administrator/assets/js/itemform.js index 75044ef7..76e471a7 100644 --- a/src/components/com_tjucm/administrator/assets/js/itemform.js +++ b/src/components/com_tjucm/administrator/assets/js/itemform.js @@ -1,33 +1,46 @@ /*Variable to store the updated options of related field*/ var tjucmRelatedFieldUpdatedOptions = ''; +/*Variable to store the data of editor field*/ var tjUcmTinyMCEFieldIds = new Array(); +/*Variable to store if the next button is clicked*/ var tjUcmClickedOnNext = 0; +/*Variable to store if the prev button is clicked*/ var tjUcmClickedOnPrev = 0; +/*Variable to store if autosave is currently allowed for the form*/ +var tjUcmCurrentAutoSaveState = 0; /* This function executes for autosave form */ jQuery(window).load(function() { /*Code to get item state*/ - var itemState = Number(jQuery('#itemState').val()); + var tjUcmItemInDraftState = Number(jQuery('#itemState').val()); - /*Code for auto save on blur event add new record or editing draft record only*/ - if (itemState == '' || itemState === 0) + /* If record is submitted and no longet in the draft state then dont allow autosave to work*/ + if (tjUcmItemInDraftState === 1) { - var tjUcmAutoSave = jQuery('#item-form #tjucm-autosave').val(); + var tjUcmAllowAutoSave = jQuery('#item-form #tjucm-autosave').val(); /*Check if auto save is enabled for UCM type*/ - if (tjUcmAutoSave == 1) + if (tjUcmAllowAutoSave == 1) { + tjUcmCurrentAutoSaveState = 1; + /* Save form values */ jQuery("#item-form").on("change select", ":input", function(){ - tjUcmItemForm.onUcmFormChange(this); + if (tjUcmCurrentAutoSaveState) + { + tjUcmItemForm.onUcmFormChange(this); + } }); /* To save calendar field value */ jQuery("#item-form .field-calendar input:text").blur(function(){ if (jQuery('#item-form').hasClass('dirty')) { - tjUcmItemForm.onUcmFormChange(this); + if (tjUcmCurrentAutoSaveState) + { + tjUcmItemForm.onUcmFormChange(this); + } } }); @@ -78,11 +91,17 @@ jQuery(window).load(function() /* To save calendar field value */ jQuery("#item-form .field-calendar input:text").blur(function(){ - tjUcmItemForm.onUcmFormChange(this); - //steppedFormSave(this.form.id, "draft", 0); + if (tjUcmCurrentAutoSaveState) + { + tjUcmItemForm.onUcmFormChange(this); + } }); } } + else + { + jQuery("#tjucm-auto-save-disabled-msg").show(); + } /*Update the options of related field for new record of subform*/ jQuery(document).on('subform-row-add', function(event, row){ @@ -118,7 +137,6 @@ jQuery(window).load(function() /* Handle next and previous button click on the form*/ jQuery("#next_button, #previous_button").on('click', function (){ - if (jQuery(this).attr('id') == 'next_button') { tjUcmClickedOnNext = 1; @@ -128,12 +146,49 @@ jQuery(window).load(function() tjUcmClickedOnPrev = 1; } - tjUcmItemForm.saveSectionData(jQuery('#tjucm_myTabTabs > .active a').attr('href')); + if (jQuery('#item-form').hasClass('dirty')) + { + if (tjUcmCurrentAutoSaveState) + { + tjUcmItemForm.saveSectionData(jQuery('#tjucm_myTabTabs > .active a').attr('href')); + } + } + else + { + var tjUcmSectionInputElements = jQuery(jQuery('#tjucm_myTabTabs > .active a').attr('href')).find('input, textarea, select, fieldset'); + + if (tjUcmItemForm.validateSection(tjUcmSectionInputElements)) + { + /* Clear the error messages first if any before processing the data*/ + jQuery("#system-message-container").html(""); + + if (tjUcmClickedOnNext) + { + tjUcmClickedOnNext = 0; + jQuery('#tjucm_myTabTabs > .active').next('li').find('a').trigger('click'); + tjUcmItemForm.setVisibilityOfNavigationButtons(); + } + + if (tjUcmClickedOnPrev) + { + tjUcmClickedOnPrev = 0; + jQuery('#tjucm_myTabTabs > .active').prev('li').find('a').trigger('click'); + tjUcmItemForm.setVisibilityOfNavigationButtons(); + } + } + else + { + jQuery("html, body").animate({ scrollTop: 0 }, "slow"); + } + } }); }); var tjUcmItemForm = { onUcmFormChange: function (fieldObj){ + /* Disable the action buttons before performing the action*/ + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', true); + var tjUcmParentClient = jQuery('#item-form').find("input[name='jform[client]']").val(); var getParentRecordid = new Promise(function(resolve, reject) { @@ -205,6 +260,9 @@ var tjUcmItemForm = { }); }, initUcmFormFieldDataSave: function (fieldObj, tjUcmParentClient, tjUcmParentRecordId){ + /* Disable the action buttons before performing the action*/ + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', true); + var childRecordContentIdFieldId = ''; var tjUcmItemFormData = new FormData(); @@ -289,6 +347,8 @@ var tjUcmItemForm = { } }, saveUcmFormFieldData: function (tjUcmClient, tjUcmRecordId, fieldObj){ + /* Disable the action buttons before performing the action*/ + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', true); var tjUcmItemFieldFormData = new FormData(); /* Add CSRF token to the form*/ @@ -305,52 +365,77 @@ var tjUcmItemForm = { tjUcmItemFieldFormData.append(jQuery(fieldObj).attr('name'), jQuery(fieldObj)[0].files[0]); } - com_tjucm.Services.Item.saveFieldData(tjUcmItemFieldFormData, tjUcmItemForm.afterFieldDataSave); + com_tjucm.Services.Item.saveFieldData(tjUcmItemFieldFormData, tjUcmItemForm.afterDataSave); return true; }, - afterFieldDataSave: function (error, response){ + afterDataSave: function (error, response){ /* Remove the dirty class fromt the form once the field data is saved*/ jQuery('#item-form').removeClass('dirty'); - /* Enable the sce button once the field data is saved*/ - jQuery('#finalSave').attr('disabled', false); - jQuery('#draftSave').attr('disabled', false); + if (response == null) + { + return false; + } + + /* Enable the save buttons once the field data is saved*/ + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', false); /* Add content_id in ucmsubform records */ - if (response.data.childContentIds) + if (response.data != null) { - jQuery.each(response.data.childContentIds, function(elementId, val) { - jQuery("#"+elementId).val(val); - }); + if (response.data.childContentIds) + { + jQuery.each(response.data.childContentIds, function(elementId, val) { + jQuery("#"+elementId).val(val); + }); + } } if (tjUcmClickedOnNext) { tjUcmClickedOnNext = 0; jQuery('#tjucm_myTabTabs > .active').next('li').find('a').trigger('click'); - tjUcmItemForm.setVisibilityOfNavigationButtons(); } if (tjUcmClickedOnPrev) { tjUcmClickedOnPrev = 0; jQuery('#tjucm_myTabTabs > .active').prev('li').find('a').trigger('click'); - tjUcmItemForm.setVisibilityOfNavigationButtons(); } + tjUcmItemForm.setVisibilityOfNavigationButtons(); + /* Update the options of related field */ - var tjUcmParentClient = jQuery('#item-form').find("input[name='jform[client]']").val(); - var tjucmParentRecordId = jQuery('#item-form').find("input[name='jform[id]']").val(); - tjUcmItemForm.updateRelatedFieldsOptions(tjUcmParentClient, tjucmParentRecordId); + if (response.data) + { + var tjUcmParentClient = jQuery('#item-form').find("input[name='jform[client]']").val(); + var tjucmParentRecordId = jQuery('#item-form').find("input[name='jform[id]']").val(); + tjUcmItemForm.updateRelatedFieldsOptions(tjUcmParentClient, tjucmParentRecordId); + } /* If there are errors in the response then show them on the screen*/ - tjUcmItemForm.displayFormErrors(response); + tjUcmItemForm.renderResponseMessages(response); }, - displayFormErrors: function (response) + renderResponseMessages: function (response) { if (response != null) { + if (response.message !== null) + { + if (response.data) + { + tjUcmItemForm.afterItemSaveSuccess(); + Joomla.renderMessages({'success':[response.message]}); + } + else + { + Joomla.renderMessages({'error':[response.message]}); + } + + jQuery("html, body").animate({ scrollTop: 0 }, "slow"); + } + if (response.messages !== null) { if (response.messages.error !== null) @@ -364,6 +449,12 @@ var tjUcmItemForm = { } } }, + afterItemSaveSuccess: function (){ + jQuery("#tjucm-auto-save-disabled-msg").show(); + jQuery("#itemState").val(0); + jQuery("#tjUcmSectionDraftSave").remove(); + tjUcmCurrentAutoSaveState = 0; + }, updateRelatedFieldsOptions: function (tjUcmParentClient, tjUcmParentRecordId) { var tjUcmItemFormData = new FormData(); @@ -397,13 +488,27 @@ var tjUcmItemForm = { com_tjucm.Services.Item.getUpdatedRelatedFieldsOptions(tjUcmItemFormData, tjUcmUpdateRelatedFieldsOptions); }, saveUcmFormData: function(){ + /* Disable the action buttons before performing the action*/ + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', true); + var tjUcmFormSubmitCallingButtonId = event.target.id; + + if (tjUcmFormSubmitCallingButtonId == 'tjUcmSectionFinalSave') + { + if(!confirm(Joomla.JText._("COM_TJUCM_ITEMFORM_SUBMIT_ALERT"))) + { + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', false); + + return false; + } + } + if (document.formvalidator.isValid(document.getElementById('item-form'))) { + /* Clear the error messages first if any before processing the data*/ + jQuery("#system-message-container").html(""); + /* Disable the save button till the record is saved*/ - jQuery('#finalSave').attr('disabled', true); - jQuery('#draftSave').attr('disabled', true); - jQuery('#previous_button').attr('disabled', true); - jQuery('#next_button').attr('disabled', true); + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', true); /* For AJAX save need to assign values to the editor field containers*/ jQuery("#item-form .toggle-editor a").each(function(index) { @@ -487,7 +592,12 @@ var tjUcmItemForm = { tjUcmItemFormData.append('client', tjUcmClient); tjUcmItemFormData.append('recordid', tjUcmRecordId); - com_tjucm.Services.Item.saveFormData(tjUcmItemFormData, tjUcmItemForm.afterFieldDataSave); + if (tjUcmFormSubmitCallingButtonId == 'tjUcmSectionDraftSave') + { + tjUcmItemFormData.append('draft', 1); + } + + com_tjucm.Services.Item.saveFormData(tjUcmItemFormData, tjUcmItemForm.afterDataSave); return true; }).catch(function (error){ @@ -499,19 +609,24 @@ var tjUcmItemForm = { else { tjUcmItemForm.setVisibilityOfNavigationButtons(); - jQuery('#finalSave').attr('disabled', false); - jQuery('#draftSave').attr('disabled', false); + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', false); jQuery("html, body").animate({ scrollTop: 0 }, "slow"); return false; } }, saveSectionData: function (tabId){ + /* Disable the action buttons before performing the action*/ + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', true); + var tjUcmSectionFormData = new FormData(); var tjUcmSectionInputElements = jQuery(tabId).find('input, textarea, select, fieldset'); if (tjUcmItemForm.validateSection(tjUcmSectionInputElements)) { + /* Clear the error messages first if any before processing the data*/ + jQuery("#system-message-container").html(""); + /* For AJAX save need to assign values to the editor field containers*/ jQuery("#item-form .toggle-editor a").each(function(index) { this.click(); @@ -538,10 +653,7 @@ var tjUcmItemForm = { } /* Disable the save button till the record is saved*/ - jQuery('#finalSave').attr('disabled', true); - jQuery('#draftSave').attr('disabled', true); - jQuery('#previous_button').attr('disabled', true); - jQuery('#next_button').attr('disabled', true); + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', true); var tjUcmParentClient = jQuery('#item-form').find("input[name='jform[client]']").val(); var getParentRecordid = new Promise(function(resolve, reject) { @@ -614,7 +726,7 @@ var tjUcmItemForm = { tjUcmSectionFormData.append('recordid', tjUcmRecordId); tjUcmSectionFormData.append('tjUcmFormSection', jQuery("a[href='"+tabId+"']").html()); - com_tjucm.Services.Item.saveFormData(tjUcmSectionFormData, tjUcmItemForm.afterFieldDataSave); + com_tjucm.Services.Item.saveFormData(tjUcmSectionFormData, tjUcmItemForm.afterDataSave); return true; }).catch(function (error){ @@ -714,8 +826,7 @@ function steppedFormSave(form_id, status, showDraftSuccessMsg) if (!document.formvalidator.isValid('#item-form')) { - jQuery('#finalSave').attr('disabled', false); - jQuery('#draftSave').attr('disabled', false); + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', false); jQuery("html, body").animate({ scrollTop: 0 }, "slow"); return false; @@ -723,8 +834,7 @@ function steppedFormSave(form_id, status, showDraftSuccessMsg) } else { - jQuery('#draftSave').attr('disabled', false); - jQuery('#finalSave').attr('disabled', false); + jQuery(".form-actions button[type='button'], .form-actions input[type='button']").attr('disabled', false); jQuery("html, body").animate({ scrollTop: 0 }, "slow"); return false; @@ -764,7 +874,7 @@ function steppedFormSave(form_id, status, showDraftSuccessMsg) if ('save' == status) { - jQuery("#finalSave").attr("disabled", "disabled"); + jQuery("#tjUcmSectionFinalSave").attr("disabled", "disabled"); Joomla.renderMessages({'success':[Joomla.JText._('COM_TJUCM_MSG_ON_SAVED_FORM')]}); jQuery('html, body').animate({ scrollTop: jQuery("#system-message-container").offset().top-40 @@ -817,8 +927,8 @@ function steppedFormSave(form_id, status, showDraftSuccessMsg) history.pushState(null, null, tjucmUrl); } - jQuery('#draftSave').attr('disabled', false); - jQuery('#finalSave').attr('disabled', false); + jQuery('#tjUcmSectionDraftSave').attr('disabled', false); + jQuery('#tjUcmSectionFinalSave').attr('disabled', false); /* After AJAX save need to toggle back the editors as we had previoussly toggled them to post the values*/ jQuery("#item-form .toggle-editor a").each(function(index) { diff --git a/src/components/com_tjucm/media/js/.htaccess b/src/components/com_tjucm/media/js/.htaccess new file mode 100755 index 00000000..79a12fe2 --- /dev/null +++ b/src/components/com_tjucm/media/js/.htaccess @@ -0,0 +1,3 @@ + + Allow from All + \ No newline at end of file diff --git a/src/components/com_tjucm/site/controllers/itemform.json.php b/src/components/com_tjucm/site/controllers/itemform.json.php index 2f8818e0..05f66ec0 100644 --- a/src/components/com_tjucm/site/controllers/itemform.json.php +++ b/src/components/com_tjucm/site/controllers/itemform.json.php @@ -15,6 +15,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\Session\Session; use Joomla\CMS\Router\Route; +use Joomla\Registry\Registry; jimport('joomla.filesystem.file'); @@ -120,7 +121,7 @@ protected function allowEdit($data = array(), $key = 'id') */ public function save($key = null, $urlVar = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + JSession::checkToken() or jexit(Text::_('JINVALID_TOKEN')); $post = Factory::getApplication()->input->post; $model = $this->getModel('itemform'); @@ -135,13 +136,18 @@ public function save($key = null, $urlVar = null) // For new record if there is no client specified or invalid client is given then do not process the request if ($client == '' || empty($this->typeId)) { - echo new JResponseJson('', JText::_('COM_TJUCM_FORM_SAVE_FAILED_CLIENT_REQUIRED'), true); + echo new JResponseJson('', Text::_('COM_TJUCM_FORM_SAVE_FAILED_CLIENT_REQUIRED'), true); } + // Set the state of record as per UCM type config + $typeTable = $model->getTable('type'); + $typeTable->load(array('unique_identifier' => $client)); + $typeParams = new Registry($typeTable->params); + $data['state'] = $typeParams->get('publish_items', 0); + $data['client'] = $client; } - $data['state'] = $post->get('state', 0, 'INT'); $data['draft'] = $post->get('draft', 0, 'INT'); $data['parent_id'] = $post->get('parent_id', 0, 'INT'); @@ -155,21 +161,20 @@ public function save($key = null, $urlVar = null) $errors = $model->getErrors(); $this->processErrors($errors); - echo new JResponseJson('', JText::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), true); + echo new JResponseJson('', Text::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), true); } if ($model->save($data)) { $result['id'] = $model->getState($model->getName() . '.id'); - - echo new JResponseJson($result, JText::_('COM_TJUCM_ITEM_SAVED_SUCCESSFULLY')); + echo new JResponseJson($result, Text::_('COM_TJUCM_ITEM_SAVED_SUCCESSFULLY')); } else { $errors = $model->getErrors(); $this->processErrors($errors); - echo new JResponseJson('', JText::_('COM_TJUCM_FORM_SAVE_FAILED'), true); + echo new JResponseJson('', Text::_('COM_TJUCM_FORM_SAVE_FAILED'), true); } } catch (Exception $e) @@ -178,9 +183,16 @@ public function save($key = null, $urlVar = null) } } + /** + * Method to save single field data. + * + * @return void + * + * @since 1.2.1 + */ public function saveFieldData() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + JSession::checkToken() or jexit(Text::_('JINVALID_TOKEN')); $app = Factory::getApplication(); $post = $app->input->post; @@ -197,7 +209,7 @@ public function saveFieldData() if (empty($fieldData)) { - $app->enqueueMessage(JText::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), 'error'); + $app->enqueueMessage(Text::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), 'error'); echo new JResponseJson(null); } @@ -237,9 +249,16 @@ public function saveFieldData() } } + /** + * Method to save form data. + * + * @return void + * + * @since 1.2.1 + */ public function saveFormData() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + JSession::checkToken() or jexit(Text::_('JINVALID_TOKEN')); $app = Factory::getApplication(); $post = $app->input->post; @@ -249,10 +268,11 @@ public function saveFormData() $filesData = $app->input->files->get('jform', array(), 'ARRAY'); $formData = array_merge_recursive($formData, $filesData); $section = $post->get('tjUcmFormSection', '', 'STRING'); + $draft = $post->get('draft', 0, 'INT'); if (empty($formData) || empty($client)) { - $app->enqueueMessage(JText::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), 'error'); + $app->enqueueMessage(Text::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), 'error'); echo new JResponseJson(null); } @@ -295,8 +315,18 @@ public function saveFormData() // If data is valid then save the data into DB $response = $model->saveExtraFields($formData); + $msg = null; - echo new JResponseJson($response); + if ($response && empty($section) && empty($draft)) + { + $msg = ($response) ? Text::_("COM_TJUCM_ITEM_SAVED_SUCCESSFULLY") : Text::_("COM_TJUCM_FORM_SAVE_FAILED"); + + // Disable the draft mode of the item if full f)orm is submitted + $table->draft = 0; + $table->store(); + } + + echo new JResponseJson($response, $msg); } catch (Exception $e) { @@ -312,11 +342,11 @@ public function saveFormData() * * @return boolean true or false * - * @since 1.0.0 + * @since 1.2.1 */ public function saveItemFieldData($key = null, $urlVar = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + JSession::checkToken() or jexit(Text::_('JINVALID_TOKEN')); $post = Factory::getApplication()->input->post; $model = $this->getModel('itemform'); @@ -331,7 +361,7 @@ public function saveItemFieldData($key = null, $urlVar = null) // For new record if there is no client specified then do not process the request if ($client == '') { - echo new JResponseJson('', JText::_('COM_TJUCM_FORM_SAVE_FAILED'), true); + echo new JResponseJson('', Text::_('COM_TJUCM_FORM_SAVE_FAILED'), true); } $data['created_by'] = Factory::getUser()->id; @@ -357,20 +387,20 @@ public function saveItemFieldData($key = null, $urlVar = null) $errors = $model->getErrors(); $this->processErrors($errors); - echo new JResponseJson('', JText::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), true); + echo new JResponseJson('', Text::_('COM_TJUCM_FORM_VALIDATATION_FAILED'), true); } if ($model->save($data)) { $result['id'] = $model->getState($model->getName() . '.id'); - echo new JResponseJson($result, JText::_('COM_TJUCM_ITEM_SAVED_SUCCESSFULLY')); + echo new JResponseJson($result, Text::_('COM_TJUCM_ITEM_SAVED_SUCCESSFULLY')); } else { $errors = $model->getErrors(); $this->processErrors($errors); - echo new JResponseJson('', JText::_('COM_TJUCM_FORM_SAVE_FAILED'), true); + echo new JResponseJson('', Text::_('COM_TJUCM_FORM_SAVE_FAILED'), true); } } catch (Exception $e) @@ -417,7 +447,7 @@ private function processErrors($errors) public function getRelatedFieldOptions() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + JSession::checkToken() or jexit(Text::_('JINVALID_TOKEN')); $app = Factory::getApplication(); $post = $app->input->post; diff --git a/src/components/com_tjucm/site/models/forms/itemform.xml b/src/components/com_tjucm/site/models/forms/itemform.xml index 67432aa0..b3abf068 100644 --- a/src/components/com_tjucm/site/models/forms/itemform.xml +++ b/src/components/com_tjucm/site/models/forms/itemform.xml @@ -12,6 +12,9 @@
+ + +