diff --git a/resources/css/pedigree-chart.css b/resources/css/pedigree-chart.css
index 09d3d1a..4f49e25 100644
--- a/resources/css/pedigree-chart.css
+++ b/resources/css/pedigree-chart.css
@@ -1,10 +1,7 @@
/* Form */
-.form-element-with-description {
- padding-left: 1.5em;
-}
-
-.form-element-with-description .form-check {
- padding-left: 0;
+.form-element-description {
+ -webkit-box-decoration-break: clone;
+ box-decoration-break: clone;
}
#webtrees-pedigree-chart-form .row {
diff --git a/resources/js/modules/custom/configuration.js b/resources/js/modules/custom/configuration.js
index 341a9d2..e2ed354 100644
--- a/resources/js/modules/custom/configuration.js
+++ b/resources/js/modules/custom/configuration.js
@@ -24,6 +24,7 @@ export default class Configuration
* @param {Number} generations
* @param {Boolean} showEmptyBoxes
* @param {String} treeLayout
+ * @param {Boolean} openNewTabOnClick
* @param {Boolean} rtl
* @param {Number} direction
*/
@@ -32,6 +33,7 @@ export default class Configuration
generations = 4,
showEmptyBoxes = false,
treeLayout = LAYOUT_LEFTRIGHT,
+ openNewTabOnClick = true,
rtl = false,
direction = 1
) {
@@ -39,6 +41,8 @@ export default class Configuration
this._treeLayout = treeLayout;
this._orientations = new OrientationCollection();
+ this._openNewTabOnClick = openNewTabOnClick;
+
//
this.duration = 750;
@@ -146,4 +150,14 @@ export default class Configuration
{
return this._orientations.get()[this.treeLayout];
}
+
+ /**
+ * Returns TRUE or FALSE depending on whether to open the current individual's details page in a new tab.
+ *
+ * @returns {Boolean}
+ */
+ get openNewTabOnClick()
+ {
+ return this._openNewTabOnClick;
+ }
}
diff --git a/resources/js/modules/index.js b/resources/js/modules/index.js
index 4b10543..040adf6 100644
--- a/resources/js/modules/index.js
+++ b/resources/js/modules/index.js
@@ -29,6 +29,7 @@ export class PedigreeChart
* @param {Number} options.generations
* @param {Boolean} options.showEmptyBoxes
* @param {String} options.treeLayout
+ * @param {Boolean} options.openNewTabOnClick
* @param {String[]} options.cssFiles
* @param {Data[]} options.data
*/
@@ -43,6 +44,7 @@ export class PedigreeChart
options.generations,
options.showEmptyBoxes,
options.treeLayout,
+ options.openNewTabOnClick,
options.rtl
);
diff --git a/resources/js/modules/lib/chart.js b/resources/js/modules/lib/chart.js
index c10c405..27f3c3b 100644
--- a/resources/js/modules/lib/chart.js
+++ b/resources/js/modules/lib/chart.js
@@ -184,7 +184,9 @@ export default class Chart
*/
redirectToIndividual(url)
{
- window.open(url, "_blank");
+ this._configuration.openNewTabOnClick
+ ? window.open(url, "_blank")
+ : window.location = url;
}
/**
diff --git a/resources/views/modules/pedigree-chart/chart.phtml b/resources/views/modules/pedigree-chart/chart.phtml
index aef58f0..49f2a96 100644
--- a/resources/views/modules/pedigree-chart/chart.phtml
+++ b/resources/views/modules/pedigree-chart/chart.phtml
@@ -51,6 +51,10 @@ new WebtreesPedigreeChart.PedigreeChart(
return treeLayout ?? = json_encode($configuration->getLayout()) ?>;
},
+ get openNewTabOnClick() {
+ return openNewTabOnClick ?? = json_encode($configuration->getOpenNewTabOnClick()) ?>;
+ },
+
data: = json_encode($data) ?>
}
);
diff --git a/resources/views/modules/pedigree-chart/form/layout.phtml b/resources/views/modules/pedigree-chart/form/layout.phtml
index d618cad..5c1f7ec 100644
--- a/resources/views/modules/pedigree-chart/form/layout.phtml
+++ b/resources/views/modules/pedigree-chart/form/layout.phtml
@@ -31,5 +31,19 @@ use MagicSunday\Webtrees\PedigreeChart\Configuration;
'unchecked' => '0',
])
?>
+
+
+ =
+ view($moduleName . '::modules/components/checkbox', [
+ 'name' => 'openNewTabOnClick',
+ 'label' => I18N::translate('Open individual in new browser window/tab'),
+ 'checked' => $configuration->getOpenNewTabOnClick(),
+ 'unchecked' => '0',
+ ])
+ ?>
+
+ = I18N::translate('Open the current individual\'s detail page in a new browser window/tab when it\'s left-clicked, otherwise the current window/tab is used.') ?>
+
+
diff --git a/resources/views/modules/pedigree-chart/page.phtml b/resources/views/modules/pedigree-chart/page.phtml
index 75e7f12..b002067 100644
--- a/resources/views/modules/pedigree-chart/page.phtml
+++ b/resources/views/modules/pedigree-chart/page.phtml
@@ -167,6 +167,7 @@ const storage = new WebtreesPedigreeChart.Storage("webtrees-pedigree-chart");
storage.register("generations");
storage.register("layout");
storage.register("showEmptyBoxes");
+storage.register("openNewTabOnClick");
// Handle option toggle button
toggleMoreOptions(storage);
@@ -175,10 +176,11 @@ toggleMoreOptions(storage);
let formElements = document.getElementById("webtrees-pedigree-chart-form").elements;
formElements.namedItem("layout").value = storage.read("layout");
-const generations = parseInt(storage.read("generations"));
-const showEmptyBoxes = storage.read("showEmptyBoxes");
-const treeLayout = storage.read("layout");
-const ajaxUrl = getUrl(= json_encode($ajaxUrl) ?>, storage.read("generations"));
+const generations = parseInt(storage.read("generations"));
+const showEmptyBoxes = storage.read("showEmptyBoxes");
+const treeLayout = storage.read("layout");
+const openNewTabOnClick = storage.read("openNewTabOnClick");
+const ajaxUrl = getUrl(= json_encode($ajaxUrl) ?>, storage.read("generations"));
document.getElementById("pedigree-chart-url")
.setAttribute('data-wt-ajax-url', ajaxUrl);
diff --git a/src/Configuration.php b/src/Configuration.php
index fa77ac4..87eaec4 100644
--- a/src/Configuration.php
+++ b/src/Configuration.php
@@ -146,7 +146,7 @@ public function getShowEmptyBoxes(): bool
->boolean(
'showEmptyBoxes',
(bool) $this->module->getPreference(
- 'default_show_empty_boxes',
+ 'default_showEmptyBoxes',
'0'
)
);
@@ -175,7 +175,7 @@ public function getLayout(): string
->string(
'layout',
$this->module->getPreference(
- 'default_tree_layout',
+ 'default_layout',
self::DEFAULT_TREE_LAYOUT
)
);
@@ -204,4 +204,27 @@ public function getLayouts(): array
self::LAYOUT_TOPBOTTOM => view('icons/pedigree-down') . I18N::translate('down'),
];
}
+
+ /**
+ * Returns whether to open a new browser window/tab on left-click on an individual or not.
+ *
+ * @return bool
+ */
+ public function getOpenNewTabOnClick(): bool
+ {
+ if ($this->request->getMethod() === RequestMethodInterface::METHOD_POST) {
+ $validator = Validator::parsedBody($this->request);
+ } else {
+ $validator = Validator::queryParams($this->request);
+ }
+
+ return $validator
+ ->boolean(
+ 'openNewTabOnClick',
+ (bool) $this->module->getPreference(
+ 'default_openNewTabOnClick',
+ '1'
+ )
+ );
+ }
}
diff --git a/src/Module.php b/src/Module.php
index 43a31b8..ad6c2d8 100644
--- a/src/Module.php
+++ b/src/Module.php
@@ -166,11 +166,12 @@ public function handle(ServerRequestInterface $request): ResponseInterface
route(
self::ROUTE_DEFAULT,
[
- 'tree' => $tree->name(),
- 'xref' => $validator->string('xref', ''),
- 'generations' => $validator->integer('generations', 4),
- 'showEmptyBoxes' => $validator->boolean('showEmptyBoxes', false),
- 'layout' => $validator->string('layout', Configuration::LAYOUT_LEFTRIGHT),
+ 'tree' => $tree->name(),
+ 'xref' => $validator->string('xref', ''),
+ 'generations' => $validator->integer('generations', 4),
+ 'showEmptyBoxes' => $validator->boolean('showEmptyBoxes', false),
+ 'layout' => $validator->string('layout', Configuration::LAYOUT_LEFTRIGHT),
+ 'openNewTabOnClick' => $validator->boolean('openNewTabOnClick', true),
]
)
);
@@ -266,10 +267,11 @@ private function getAjaxRoute(Individual $individual, string $xref): string
return $this->chartUrl(
$individual,
[
- 'ajax' => true,
- 'generations' => $this->configuration->getGenerations(),
- 'layout' => $this->configuration->getLayout(),
- 'xref' => $xref,
+ 'ajax' => true,
+ 'generations' => $this->configuration->getGenerations(),
+ 'layout' => $this->configuration->getLayout(),
+ 'openNewTabOnClick' => $this->configuration->getOpenNewTabOnClick(),
+ 'xref' => $xref,
]
);
}
diff --git a/src/Traits/ModuleConfigTrait.php b/src/Traits/ModuleConfigTrait.php
index c3a8beb..20d3ae7 100644
--- a/src/Traits/ModuleConfigTrait.php
+++ b/src/Traits/ModuleConfigTrait.php
@@ -58,8 +58,9 @@ public function postAdminAction(ServerRequestInterface $request): ResponseInterf
$configuration = new Configuration($request, $this);
$this->setPreference('default_generations', (string) $configuration->getGenerations());
- $this->setPreference('default_tree_layout', $configuration->getLayout());
- $this->setPreference('default_show_empty_boxes', (string) $configuration->getShowEmptyBoxes());
+ $this->setPreference('default_layout', $configuration->getLayout());
+ $this->setPreference('default_showEmptyBoxes', (string) $configuration->getShowEmptyBoxes());
+ $this->setPreference('default_openNewTabOnClick', (string) $configuration->getOpenNewTabOnClick());
FlashMessages::addMessage(
I18N::translate(